調整 ZFS 清理,141KB/s 執行 15 天
一個非常基本的系統,在 7.2k rpm sas 磁碟上執行鏡像+條帶,沒有特別載入。對所有數據集沒有重複數據刪除和壓縮。Scrub 已經以死蝸牛的速度執行了 15 天。是否需要進行一些優化,或者可能是由於一些錯誤的硬體?
- 帶 MD1200 機箱的戴爾 R510。
- 2x 至強 E5620
- 48GB
- NexentaStor 3.1.3,社區版
一些資訊:
scan: scrub in progress since Mon Apr 1 19:00:05 2013 171G scanned out of 747G at 141K/s, 1187h40m to go 0 repaired, 22.84% done config: NAME STATE READ WRITE CKSUM tank ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 c7t5000C500414FB2CFd0 ONLINE 0 0 0 c7t5000C500414FCA57d0 ONLINE 0 0 0 mirror-1 ONLINE 0 0 0 c7t5000C500415C3B1Bd0 ONLINE 0 0 0 c7t5000C500415C5E4Fd0 ONLINE 0 0 0 mirror-2 ONLINE 0 0 0 c7t5000C500415DC797d0 ONLINE 0 0 0 c7t5000C500415DC933d0 ONLINE 0 0 0 logs c7t5000A7203006D81Ed0 ONLINE 0 0 0 cache c7t5000A72030068545d0 ONLINE 0 0 0 # iostat -en ---- errors --- s/w h/w trn tot device 0 8887 0 8887 c2t0d0 0 0 0 0 c0t395301D6B0C8069Ad0 0 0 0 0 c7t5000C500415DC933d0 0 0 0 0 c7t5000A72030068545d0 0 0 0 0 c7t5000C500415DC797d0 0 0 0 0 c7t5000C500414FCA57d0 0 0 0 0 c7t5000C500415C3B1Bd0 0 0 0 0 c7t5000C500415C5E4Fd0 0 0 0 0 c7t5000C500414FB2CFd0 0 0 0 0 c7t5000A7203006D81Ed0
spa_last_io 每次執行時都會更改
# echo "::walk spa | ::print spa_t spa_name spa_last_io spa_scrub_inflight" | mdb -k spa_name = [ "syspool" ] spa_last_io = 0x25661402 spa_scrub_inflight = 0 spa_name = [ "tank" ] spa_last_io = 0x25661f84 spa_scrub_inflight = 0x21
每 5 秒寫入大約 20-25 MB/s。在這些寫入之間,基本上沒有讀取或寫入。
capacity operations bandwidth latency pool alloc free read write read write read write ------------------------- ----- ----- ----- ----- ----- ----- ----- ----- syspool 427G 501G 0 0 0 0 0.00 0.00 c0t395301D6B0C8069Ad0s0 427G 501G 0 0 0 0 0.00 0.00 ------------------------- ----- ----- ----- ----- ----- ----- ----- ----- tank 903G 1.84T 810 5.21K 1.50M 20.8M 9.42 4.71 mirror 301G 627G 22 1.00K 53.0K 3.96M 8.96 3.93 c7t5000C500414FB2CFd0 - - 20 244 50.1K 3.97M 6.70 1.14 c7t5000C500414FCA57d0 - - 19 242 48.2K 3.97M 7.60 1.12 mirror 301G 627G 25 1016 46.8K 4.10M 16.11 5.28 c7t5000C500415C3B1Bd0 - - 21 257 41.6K 4.11M 4.63 1.24 c7t5000C500415C5E4Fd0 - - 21 255 43.0K 4.11M 16.54 1.15 mirror 301G 627G 62 754 119K 3.03M 19.72 3.78 c7t5000C500415DC797d0 - - 57 219 114K 3.03M 9.99 1.15 c7t5000C500415DC933d0 - - 56 220 119K 3.03M 13.20 1.22 c7t5000A7203006D81Ed0 260K 46.5G 0 0 0 0 0.00 0.00 cache - - - - - - c7t5000A72030068545d0 93.1G 8M 0 0 0 0 0.00 0.00 ------------------------- ----- ----- ----- ----- ----- ----- ----- -----
iostats 是否告訴我我花更多的時間等待磁碟,然後我應該這樣做?特別是 %b 列
# iostat -xe device r/s w/s kr/s kw/s wait actv svc_t %w %b s/w h/w trn tot sd3 5.1 43.9 20.6 643.8 0.0 0.1 2.9 0 5 0 0 0 0 sd4 9.4 1.8 141.1 169.6 0.0 0.0 0.5 0 0 0 0 0 0 sd5 3.1 43.8 15.8 643.8 0.0 0.1 1.4 0 3 0 0 0 0 sd6 5.2 38.1 14.3 494.4 0.0 0.1 3.0 0 7 0 0 0 0 sd7 4.2 40.2 11.1 623.2 0.0 0.1 2.7 0 7 0 0 0 0 sd8 3.6 44.3 9.7 623.2 0.0 0.1 1.5 0 4 0 0 0 0 sd9 2.9 37.4 7.0 494.4 0.0 0.1 1.3 0 2 0 0 0 0 sd10 0.7 0.4 3.4 0.0 0.0 0.0 0.0 0 0 0 0 0 0
延遲有點偏高?
# zpool iostat 10 10 capacity operations bandwidth latency pool alloc free read write read write read write tank 909G 1.83T 86 2.82K 208K 12.7M 22.68 13.63 ---------- ----- ----- ----- ----- ----- ----- ----- ----- tank 909G 1.83T 29 857 42.4K 3.50M 17.86 4.47 ---------- ----- ----- ----- ----- ----- ----- ----- ----- tank 909G 1.83T 30 947 46.1K 3.54M 15.55 5.67
應用了一些調整,但差別不大。zfs_top_maxinflight 設置為 127,zfs_scrub_delay 設置為 0,zfs_scan_idle 設置為 0。
# echo zfs_top_maxinflight | mdb -k zfs_top_maxinflight: zfs_top_maxinflight: 127 # echo zfs_scrub_delay/D |mdb -k zfs_scrub_delay: zfs_scrub_delay:0 # echo zfs_scan_idle/D |mdb -k zfs_scan_idle: zfs_scan_idle: 0 scan: scrub in progress since Wed Apr 17 20:47:23 2013 1.85G scanned out of 918G at 1.14M/s, 229h36m to go 0 repaired, 0.20% done
預 mdb 調整,注意相當高的 b% 列
$ iostat -nx -M 5
r/s w/s Mr/s Mw/s wait actv wsvc_t asvc_t %w %b device 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c2t0d0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c0t395301D6B0C8069Ad0 35.2 44.2 0.3 0.7 0.0 0.4 0.0 5.3 0 32 c7t5000C500415DC933d0 19.8 3.2 0.2 0.0 0.0 0.0 0.0 0.1 0 0 c7t5000A72030068545d0 31.2 46.2 0.2 0.7 0.0 0.3 0.0 4.4 0 27 c7t5000C500415DC797d0 30.6 46.8 0.2 0.8 0.0 0.4 0.0 4.6 0 28 c7t5000C500414FCA57d0 37.6 53.0 0.3 0.8 0.0 0.4 0.0 4.7 0 33 c7t5000C500415C3B1Bd0 37.6 53.6 0.3 0.8 0.0 0.5 0.0 5.6 0 39 c7t5000C500415C5E4Fd0 33.2 46.8 0.3 0.8 0.0 0.5 0.0 6.1 0 33 c7t5000C500414FB2CFd0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c7t5000A7203006D81Ed0
發布 mdb 調整,注意 b% 列,80-85% 時間處於忙碌等待狀態
$ iostat -nx -M 5 r/s w/s Mr/s Mw/s wait actv wsvc_t asvc_t %w %b device 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0 0 c2t0d0 0.2 27.2 0.0 0.3 0.0 1.0 0.0 35.4 0 18 c0t395301D6B0C8069Ad0 129.6 20.2 0.9 0.4 0.0 2.9 0.0 19.5 0 85 c7t5000C500415DC933d0 48.4 4.0 0.4 0.0 0.0 0.0 0.0 0.1 0 1 c7t5000A72030068545d0 130.4 19.8 0.9 0.4 0.0 3.0 0.0 20.2 0 84 c7t5000C500415DC797d0 125.8 25.8 0.9 0.5 0.0 2.9 0.0 19.2 0 80 c7t5000C500414FCA57d0 131.2 24.2 0.9 0.5 0.0 3.1 0.0 20.3 0 83 c7t5000C500415C3B1Bd0 130.6 25.8 0.9 0.5 0.0 3.5 0.0 22.5 0 88 c7t5000C500415C5E4Fd0 126.8 28.0 0.9 0.5 0.0 2.8 0.0 18.0 0 79 c7t5000C500414FB2CFd0 0.2 0.0 0.0 0.0 0.0 0.0 0.0 0.1 0 0 c7t5000A7203006D81Ed0
ZFS 清理操作根據一些相當腦殘的原則進行操作。最值得注意的是,它只在沒有其他事情發生時才花時間擦洗。如果你在一個相當穩定的基礎上只用一點數據訪問來戳一個池,那麼清理將有效地使自己餓死並且幾乎什麼都不做。
可以探索的可調參數,以及我對它的作用的快速註釋(不過,我最近一次研究過這個):
- zfs_scan_idle - 如果使用者 I/O 在這麼多時鐘週期內發生,則將清理 I/O 延遲 zfs_scrub_delay 時鐘週期
- zfs_scrub_delay - 如果由 zfs_scan_idle 觸發,則延遲清理操作的時鐘滴答數
- zfs_top_maxinflight - 每個頂級 vdev 的最大清理 I/O 數
- zfs_scrub_limit - 每個葉子 vdev 的最大清理 I/O 數
- zfs_scan_min_time_ms - 每個 txg 花費在清理操作上的最小毫秒數
- zfs_no_scrub_io - 沒有註釋
- zfs_no_scrub_prefetch - 沒有註釋,名稱似乎暗示不會在清理操作上引起預取
所有這些都可以使用“迴聲”即時更改
$$ tunable $$/W0t$$ number $$“改變和"迴響$$ tunable $$/D” 查看目前設置(我建議在更改之前執行此操作)。 因此,在理論上和一般實踐中,如果您要將 zfs_scan_idle 更改為 10(或 1 - 或 0,如果它支持,則需要檢查程式碼)並將 zfs_scrub_delay 更改為 1(或 0,如果它支持),並且如果您的 txg_synctime_ms 設置為 5000 或更高,則可能會稍微更改 zfs_scan_min_time_ms ,即使發生某種級別的使用者 I/O,實際執行清理操作也應該變得更加積極。
在您的特定情況下,報告的 %b 和 asvc_t 意味著正在進行一些非常非常隨機的讀取工作負載(旋轉磁碟應該比真正順序的磁碟做得更好),並且您已經完成了上面解釋的“簡單”工作. 所以,首先我會打開 zfs_no_scrub_prefetch,禁用清理操作的預取,看看是否有幫助。如果不滿意,取決於您使用的 Nexenta 版本 - 您可能正在執行 30/5、5/1 或 10/5(這是我們用於設置 zfs_txg_timeout & (zfs_txg_synctime_ms*1000) 的簡寫)。將 zfs_txg_timeout 更改為 10 並將 zfs_txg_synctime_ms 更改為 5000,然後嘗試將 zfs_scan_min_time_ms 提高到 3000 或 4000。這告訴 ZFS 與使用 5/1 作為預設值的舊 NexentaStor 安裝上的預設設置相比,它可以在清理上花費更長的時間 - 但是小心,
希望這可以幫助。祝你好運!