Memory

對許多小文件進行基準測試時,fio 3.23 核心轉儲

  • October 30, 2020

我被要求fio提供此測試數據集的基準測試結果:1048576x1MiB。因此,整體大小為1TiB。該集合包含2^20 個 1MiB文件。伺服器執行CentOS Linux release 7.8.2003 (Core)。它有足夠的記憶體:

[root@tbn-6 src]# free -g
             total        used        free      shared  buff/cache   available
Mem:            376           8         365           0           2         365
Swap:             3           2           1

它實際上不是物理伺服器。相反,它是一個具有以下 CPU 的 Docker 容器:

Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                48
On-line CPU(s) list:   0-47
Thread(s) per core:    2
Core(s) per socket:    12
Socket(s):             2
NUMA node(s):          2
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 85
Model name:            Intel(R) Xeon(R) Gold 6146 CPU @ 3.20GHz
[...]

為什麼是碼頭工人?我們正在開展一個項目,評估使用容器而不是物理伺服器的適當性。回到fio問題。

fio我記得我以前在處理包含許多小文件的數據集時遇到了麻煩。所以,我做了以下檢查:

[root@tbn-6 src]# ulimit -Hn
8388608
[root@tbn-6 src]# ulimit -Sn
8388608
[root@tbn-6 src]# cat /proc/sys/kernel/shmmax
18446744073692774399

在我看來一切都很好。在撰寫本文時,我還使用 GCC 9編譯了最新的 fio 3.23 。

[root@tbn-6 src]# fio --version
fio-3.23

這是作業文件:

[root@tbn-6 src]# cat testfio.ini 
[writetest]
thread=1
blocksize=2m
rw=randwrite
direct=1
buffered=0
ioengine=psync
gtod_reduce=1
numjobs=12
iodepth=1
runtime=180
group_reporting=1
percentage_random=90
opendir=./1048576x1MiB

注:以上內容,可取出以下內容:

[...]
gtod_reduce=1
[...]
runtime=180
group_reporting=1
[...]

其餘的必須保留。這是因為在我們看來執行 fio 時,作業文件的設置方式應盡可能模擬應用程序與儲存的互動,即使知道fio!=也是如此the application

我第一次跑步是這樣的

[root@tbn-6 src]# fio testfio.ini
smalloc: OOM. Consider using --alloc-size to increase the shared memory available.
smalloc: size = 368, alloc_size = 388, blocks = 13
smalloc: pool 0, free/total blocks 1/524320
smalloc: pool 1, free/total blocks 8/524320
smalloc: pool 2, free/total blocks 10/524320
smalloc: pool 3, free/total blocks 10/524320
smalloc: pool 4, free/total blocks 10/524320
smalloc: pool 5, free/total blocks 10/524320
smalloc: pool 6, free/total blocks 10/524320
smalloc: pool 7, free/total blocks 10/524320
fio: filesetup.c:1613: alloc_new_file: Assertion `0' failed.
Aborted (core dumped)

好的,是時候使用--alloc-size

[root@tbn-6 src]# fio --alloc-size=776 testfio.ini
smalloc: OOM. Consider using --alloc-size to increase the shared memory available.
smalloc: size = 368, alloc_size = 388, blocks = 13
smalloc: pool 0, free/total blocks 1/524320
smalloc: pool 1, free/total blocks 8/524320
smalloc: pool 2, free/total blocks 10/524320
smalloc: pool 3, free/total blocks 10/524320
smalloc: pool 4, free/total blocks 10/524320
smalloc: pool 5, free/total blocks 10/524320
smalloc: pool 6, free/total blocks 10/524320
smalloc: pool 7, free/total blocks 10/524320
smalloc: pool 8, free/total blocks 8/524288
smalloc: pool 9, free/total blocks 8/524288
smalloc: pool 10, free/total blocks 8/524288
smalloc: pool 11, free/total blocks 8/524288
smalloc: pool 12, free/total blocks 8/524288
smalloc: pool 13, free/total blocks 8/524288
smalloc: pool 14, free/total blocks 8/524288
smalloc: pool 15, free/total blocks 8/524288
fio: filesetup.c:1613: alloc_new_file: Assertion `0' failed.
Aborted (core dumped)

回到原點 :(

我肯定錯過了什麼。任何幫助都非常有義務。

TL;DR設置--alloc-size有一個大數字有幫助)

我敢打賭,您可以簡化這項工作並仍然重現問題(這對於查看此內容的人都會有所幫助,因為可以查看的地方更少)。我猜關鍵是那個opendir選項以及你說目錄包含“2 ^ 20 1MiB文件”的事實……

如果您閱讀文件,--alloc-size您會注意到它提到:

如果在啟用randommap的情況下執行大型作業,fio 可能會耗盡記憶體。

預設情況下,fio 在文件中均勻分佈隨機 I/O(每個塊每次寫入一次),但為此它需要跟踪它已寫入的區域,這意味著它必須為每個文件保留一個資料結構。好的,您可以看到這是怎麼回事…

為某些資料結構預留的記憶體池(因為它們必須在作業之間共享)。最初有 8 個池 ( https://github.com/axboe/fio/blob/fio-3.23/smalloc.c#L22 ),預設情況下每個池的大小為 16 兆字節 ( https://github.com/axboe /fio/blob/fio-3.23/smalloc.c#L21)。

每個執行隨機 I/O 的文件都需要一個資料結構。根據您的輸出,我們猜測每個文件都會強制分配一個 368 字節 + 標頭(https://github.com/axboe/fio/blob/fio-3.23/smalloc.c#L434)的資料結構,結合起來388 字節。因為池在 32 字節(https://github.com/axboe/fio/blob/fio-3.23/smalloc.c#L70)的分配中工作,這意味著我們實際上從 13 塊(416 字節)中取出每個文件一個池。

出於好奇,我有以下問題:

  • 你是在容器中執行它嗎?
  • 你的最大尺寸/tmp是多少?

我認為以上內容與您的問題無關,但最好排除。

更新預設情況下,docker 限制 IPC 共享記憶體的數量(另見其–shm-size選項)。目前尚不清楚這是否是這種特殊情況的一個因素,但請參閱下面的“原始作業僅停止在 8 個池”評論。

那麼為什麼設置沒有--alloc-size=776幫助呢?看看你寫的,你每個池的塊沒有增加似乎很奇怪,對吧?我注意到您的池第二次增長到最多 16 個(https://github.com/axboe/fio/blob/fio-3.23/smalloc.c#L24)。的文件是--alloc-size這樣說的:

–alloc-size= kbKiB中分配大小為****kb 的其他內部 smalloc 池。

$$ … $$池大小預設為16MiB。$$ emphasis added $$

你用過--alloc-size=776… 776 KiB 不是小於 16 MiB 嗎?這將使每個池小於預設值,並且可以解釋為什麼它在第二次執行放棄之前嘗試將池的數量增加到最大 16。

(2 ** 20 * 416) / 8 / 1024 = 53248 (but see the update below)

上述算術建議您希望每個池的大小約為 52 兆字節,如果您將擁有 8 個池,總計大約 416 兆字節的 RAM。使用時會發生什麼--alloc-size=53248

更新:上面計算的數字太低了。在評論中,提問者報告說需要使用更高的設置--alloc-size=1048576

(我有點擔心原來的工作只停在 8 個池 (128 MiB) 上。這是否表明嘗試增長到第 9 個 16 MiB 池是有問題的?)

最後,當您要求隨機 I/O 的特定分佈時,fio 文件似乎暗示正在分配這些資料結構。這表明如果 I/O 是順序的,或者如果 I/O 使用隨機偏移量但不必遵守分佈,那麼也許不必分配這些資料結構……如果你使用會發生什麼norandommap?

(旁白:blocksize=2M但你的文件有 1MiB 大 - 對嗎?)

這個問題對於隨便的 serverfault 答案來說感覺太大了,太專業了,可能會從 fio 項目本身得到更好的答案(參見https://github.com/axboe/fio/blob/fio-3.23/REPORTING-BUGShttps:// /github.com/axboe/fio/blob/fio-3.23/README#L58)。

祝你好運!

引用自:https://serverfault.com/questions/1039640