對許多小文件進行基準測試時,fio 3.23 核心轉儲
我被要求
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= kb在KiB中分配大小為****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-BUGS,https:// /github.com/axboe/fio/blob/fio-3.23/README#L58)。
祝你好運!