調整 ZFS 以實現突發順序寫入

調整 ZFS 以實現突發順序寫入

這是以下內容的後續內容:高速網路寫入,大容量存儲。設定發生了顯著變化。

我有一個包含 6 個驅動器的池raid-z2,所有 Exos X18 CMR 驅動器。透過使用fio和手動測試,我知道該陣列平均可以維持大約 800 MB/s 的順序寫入,這很好,並且符合該陣列的預期性能。該機器是 Ryzen5 Pro 2400 GE(4C/8T,3.8 GHz boost),具有 32G ECC RAM、NVMe 啟動/系統驅動器和 2x10Gbps 乙太網路連接埠(Intel x550-T2)。我正在運行最新的 Arch 系統具有 zfs 2.1.2-1。

我的用例是一個視訊存檔,其中大部分是大型(~30G)一次寫入、一次讀取的壓縮影片。我已經禁用atime、 set recordsize=1M、 set compressios=offdedup=off因為數據實際上是不可壓縮的,並且測試顯示性能比compression=lz4互聯網off上所說的更差,並且設計上沒有重複數據。此池透過 Samba 在網路上共用。我已經將我的網路和 Samba 調整到從 Windows 電腦上的 NVMe NTFS 到 NVMe ext4 的傳輸速度達到 1GB/s,即相當接近 9K 巨型幀的 10 Gbps 鏈路飽和。

這就是我遇到問題的地方。我希望能夠以 1GB/s 的速度將一整個 30G 視訊存檔傳輸到raid-z2只能支援 800 MB/s 順序寫入的陣列。我的計劃是使用基於 RAM 的髒頁來吸收溢出,並在客戶端「完成」傳輸後將其刷新到磁碟。我認為我所需要的只是(1024-800)*30~=7GRAM 中的髒頁,這些髒頁可以在傳輸完成後約 10 秒內刷新到磁碟。我了解這對資料完整性的影響,風險是可以接受的,因為我可以在一個月內再次傳輸文件,以防斷電導致文件遺失或不完整。

但是我無法讓 ZFS 按照我期望的方式運行...我/etc/modprobe.d/zfs.conf已經像這樣編輯了我的檔案:

options zfs zfs_dirty_data_max_max=25769803776
options zfs zfs_dirty_data_max_max_percent=50
options zfs zfs_dirty_data_max=25769803776
options zfs zfs_dirty_data_max_percent=50
options zfs zfs_delay_min_dirty_percent=80

我已執行適當的mkinitcpio -P命令來刷新我的 initramfs 並確認重新啟動後應用了這些設定:

# arc_summary | grep dirty_data
        zfs_dirty_data_max                                   25769803776
        zfs_dirty_data_max_max                               25769803776
        zfs_dirty_data_max_max_percent                                50
        zfs_dirty_data_max_percent                                    50
        zfs_dirty_data_sync_percent                                   20

即,我將最大髒頁設定為 24G,這比我需要的 7G 多得多,並保持開始延遲寫入,直到使用了其中的 80%。據我了解,池應該能夠在開始延遲客戶端(Samba)的寫入之前將 19G 吸收到 RAM 中。

然而,我從 Windows 用戶端觀察到的寫入情況是,在約 1 GB/s 的寫入速度大約 16 秒後,寫入效能急劇下降(iostat仍然顯示磁碟正在努力刷新資料),我只能假設這是推回ZFS 的寫入限制機制。然而,這毫無意義,因為至少即使在 16 秒內沒有任何東西被沖走,它也應該在 3 秒後凝固。另外最後又脫落,見圖:[ 在此輸入影像描述][https://i.stack.imgur.com/Yd9WH.png]

我嘗試調整zfs_dirty_data_sync_percent以更早開始寫入,因為髒頁緩衝區比預設值大得多,我還嘗試調整活動 io 縮放以zfs_vdev_async_write_active_{min,max}_dirty_percent更早啟動,以使寫入速度更快大髒緩衝區。這兩者都只是稍微移動了懸崖的位置,但與我的預期相差甚遠。

問題:

  1. 我是否誤解了寫入限制延遲的工作原理?
  2. 我想做的事情可能嗎?
  3. 如果是這樣,我做錯了什麼?

是的,我知道,我實際上只是在追逐幾秒鐘,並且永遠不會收回為實現這一目標而付出的努力。沒關係,此時這是我和 ZFS 之間的私人問題,而且是原則問題;)

答案1

您還需要將zfs_txg_timeout參數從目前預設值 5 秒增加到 7G/0.2G/s = 35 秒,因此設定為 40 秒就足夠了。

在你的/etc/modprobe.d/zfs.conf

options zfs zfs_txg_timeout=40

請注意,ARC 正是這樣的「讀取」緩存,寫入快取為零,因此請確保您的 ARC 未設定為消耗區塊寫入快取每 30GB 寫入流必須吸收的額外 7G+ 資料。 ZFS 的寫入快取與任何其他簡單的區塊寫入快取(如commitext4 檔案系統的參數)一樣,因此請務必在非生產環境中進行測試,以確保在所有傳輸場景中不會出現 RAM 不足的情況。

答案2

如果 zfs Primarycache = all(預設),則每次寫入都會更新 ARC。如果讀取延遲對於您目前正在寫入的資料並不重要,我建議設定 zfs Primarycache=meta。

答案3

您目前沒有足夠的 RAM 或儲存資源來滿足您的需求。

圍繞您所需的 I/O 吞吐量等級及其最壞情況效能進行設計。

如果您在所描述的工作資料集的所有條件下都需要 1GB/s 的吞吐量,那麼請確保磁碟軸數或介面吞吐量能夠支援這一點。

相關內容