讀/寫塊大小性能不一致的結果,我的測試準確嗎?
我正在嘗試根據文件系統塊大小進行一些測試,以辨識由於 IO 錯誤導致的網格作業中的一些潛在瓶頸。我注意到在作業期間有很多 8096 B 的小文件增量,而 FS 的塊大小為:
stat -fc %s /my/filesytem 1048576
這遠非最佳。為了模擬這種行為,我創建了兩個從 1GB 到 20GB 的小隨機文件,
dd
並/dev/urandom
作為源,我嘗試了這個 python 程式碼:#!/bin/python bsize=8096 print('File random.20g1') print(strftime("%Y-%m-%d_%H:%M:%S")) f1= open('random.20g1','rb') f2= open('random.20g1.dest','wb') while True: b = f1.read(bsize) if b: f2.write(b) else: break print(strftime("%Y-%m-%d_%H:%M:%S"))
我也試過了
bsize=1048576
。我首先觀察到塊大小為 8096 和 1048576 之間的讀/寫時間差為 4 秒(大塊大小少 4 秒)。
第一個結果很有希望,但經過進一步測試,例如將文件大小增加到 20GB 或對 10 個 GB 文件執行相同操作,我觀察到在性能方面始終存在 4/3 秒的相同差異,並且增益永遠不會擴展文件。
我在我的測試過程中做錯了什麼還是你覺得沒問題?
例如,我預計在增加文件大小方面會有所改進。
這段程式碼
while True: b = f1.read(bsize) if b: f2.write(b) else: break
正在執行順序讀取和寫入 - 給定 any
bsize
,它讀取第一個bsize
字節,將它們寫入目標文件,然後讀取第二bsize
個字節,將它們附加到目標文件,…您的作業系統將通過頁面記憶體緩衝這些內容,甚至可以像評論中提到的@StephenKitt 那樣預讀和預緩衝您的輸入數據。因此,對實際磁碟的底層 IO 呼叫最終會合併成更大的塊,可能是您提到的 1 MB。
您在性能上看到的微小差異幾乎肯定是因為當您使用較小的程序時,
bsize
您的程序必須對核心進行更多的系統呼叫才能實際移動數據。因此,幾乎可以肯定這就是為什麼您在更改
bsize
測試程式碼時看不到太大差異的原因,但是如果沒有關於您的系統的更多詳細資訊,就無法確定。更多的…
你正在做的實際上是相同的
dd if=random.20g1 of=random.20g1.dest bs=8192
如果您要實際使用
dd
,您可以做更多的事情來測試磁碟 IO(只需查看手冊頁- 例如,您可以使用直接 IO 繞過頁面記憶體),但最終,IO 測試您can do withdd
非常有限,因為它將是連續的。dd
將向您展示接近最佳IO 性能,但它無法模擬大量揭示 IO 性能缺點的真實工作負載。您需要確定有關網格作業實際使用的 IO 模式的更多資訊 - 它是像在您的測試中那樣進行順序讀取/寫入,還是在文件中尋找有效隨機的位置進行隨機讀取和/或寫入做IO之前的位置?隨機 IO 操作對文件系統和底層磁碟硬體的要求更高——尤其是旋轉磁碟。可以移動數百 MB/秒的流式順序 IO 的系統可能會被隨機的小尺寸 IO 操作削弱到**每秒幾千字節。**特別是如果您使用的是 SLOW 5,000-RPM SATA 磁碟。
當不了解文件系統和 RAID 陣列的人設置儲存時,情況會變得非常糟糕。您提到的 1 MB 文件系統塊大小肯定看起來您可能正在處理錯誤的“越大總是更快”範式下的儲存系統設置。
將“越大越快”的範式與 RAID5/6 陣列和隨機小塊 IO(例如您的網格作業似乎正在做的事情)等東西混合在一起,可能會導致 IO 性能非常糟糕。
您可以
strace
在 Linux上使用來獲取您的工作所做的實際系統呼叫。查找諸如lseek
、write
、read
和pwrite
的呼叫pread
。這將告訴您您的工作所做的實際 IO 模式。獲得 IO 模式後,您可以使用接近複製該模式的工具測試和基準測試該模式下的實際儲存性能。您可能需要一個可以向/從隨機位置寫入或讀取的工具。同樣,假設 Linux,您可以從
fio
. 您可能需要使用隨機讀/寫選項。