將 ZFS 池作為一個整體快速安全地離線?
正如問題所說。
假設我想為我的 FreeNAS 池設置一個腳本化的“緊急按鈕”——我可以點擊它從 GUI 執行或在控制台/SSH 中執行,這會很快關閉可能正在讀取或寫入的所有內容,解除安裝文件系統,並且 - 理想情況下 - 靜默它正在使用的磁碟或分區。
我不關心通過這樣做導致其他軟體或遠端連接的錯誤,或者過早中止任何長文件傳輸,我只希望它以最快的方式使池離線,這與保持其一致性並可能給它一些任何掛起的寫入完成和池處於一致狀態以用於數據目的的秒數。
ZFS 命令建議的選項看起來並不樂觀:
zpool offline
僅適用於單個設備,因此如果在一次刪除一個磁碟時發生寫入,則可能會出現競爭條件;如果正在使用,則需要 -f 選項,並帶有可能失去數據zpool export
的警告。-f
可以使用池或其設備(數千個或數十萬個?)檢查所有打開file descriptors
的內容並手動強制關閉每個,但這可能會遇到競爭條件,因為它不會阻止同時創建新的 fd。我也不應該假設所有 ZFS 活動都由要發送退出信號的遠端文件服務守護程序列表調解,因為某些文件活動可能是本地的(cron/CLI/分離會話)。因此,看看如何最好地安全快速地使整個池離線,這看起來
umount
可能是我最好的選擇 - 它在文件系統級別上工作,並且可以作為一個整體單元快速離線整個文件系統,之後zpool export
看起來會然後能夠在沒有-f
選項的情況下以安全的方式實際完成和靜默任何內部活動,從而使數據本身保持在有保證的一致狀態。如果正在進行原始磁碟活動(重新同步或清理),那麼我猜想當池稍後重新聯機時會恢復或重新啟動。但
umount
似乎並沒有完全做到這一點,因為也可能有 iSCSIzvol
目標在使用中。由於伺服器不知道其結構,因此其中的數據本質上無法保持一致,因此遠端啟動器在重新連接時必須盡可能地進行數據修復。我對此很好,但我不確定是否需要某種強制終止或離線目標的命令或最佳實踐。(注意:強制終止連接與關閉單個 fd 的問題相同。)我知道,如果在寫入發生時池突然退出 RW 狀態,肯定會出現某種數據失去或問題。但只要它不失去一致性(在 ZFS 池和文件系統級別),那就沒問題 - 任何正在更新的正在使用的文件/iSCSI 目標都必須在 ZFS 一致的文件/塊上冒險但是由於在寫入數據的中途離線而導致數據無效狀態。這是不可避免的,也不是問題的問題。
那麼我實際上需要執行哪些步驟,以盡可能快地使正在使用的池離線,並與保證池的安全性和一致性保持一致 - 並且手動
umount
使用正在使用的 ZFS 文件系統(作為解決方案的一部分)是安全的或承擔任何數據損壞的風險?**更新:**在這裡提及以防其他人發現這很有用。接受的答案表明
export -f
zvols(iSCSI 等)可能存在問題。基於這個提示,我發現 FreeNAS 使用的 iSCSI 處理程序可以強制註銷/終止會話,並且還有其他可以預先發出的有用子命令 - 請參閱man ctladm
. 無論您的 zvol 用於什麼用途,都可能有一些命令可以結束它們的會話。)
免責聲明:目前我手頭沒有很多連結和參考資料可供備份,也沒有進行廣泛的測試。這只是我在過去五到七年中閱讀的關於 ZFS 及其工作原理的內容的摘要,以及一些有限的自己的測試(未協調,但主要是隨機重啟)。
此外,以下所有內容均未涉及災難性事件(伺服器完全燒毀)、軟體錯誤(ZFS 和主作業系統以及硬體控制器中的錯誤)和活動惡意(流氓管理員、管理錯誤)。對於所有這些情況,您仍然需要定期進行可恢復的備份!
靜態數據/磁碟一致性
我不關心通過這樣做導致其他軟體或遠端連接的錯誤,或者過早中止任何長文件傳輸,我只希望它以最快的方式使池離線,這與保持其一致性並可能給它一些任何掛起的寫入完成和池處於一致狀態以用於數據目的的秒數。
首先,好消息:由於 ZFS 使用 CoW 和原子事務,即使在突然斷電的情況下,您已經存在的數據也將是安全的。這包括池佈局和元數據。由於在新數據完全寫入之前,舊數據永遠不會移動(實際上,它根本不會移動,只是重新分配),因此如果寫入突然中斷,這些數據不會有任何危險。
此外,校驗和(Merkle 雜湊樹)有助於證明在重新啟動期間沒有發生任何不良情況,您可以通過清理池來檢查。如果您有冗餘的 vdev,ZFS 將自動更正它從已知良好副本中發現的任何錯誤。如果某些塊會以任何方式損壞(例如,被不寫但說有的流氓磁碟控制器損壞),它們的校驗和將與來自其他 vdev 的校驗和不匹配,並且會顯示錯誤。
飛行/寫入模式中的數據和最後 n 秒的失去
同步和非同步寫入
通常,ZFS 收集多個事務以加速對旋轉驅動器的昂貴寫入 - 定位 HDD 的寫入頭比實際寫入需要更多時間,因此您將希望盡可能多地排隊,然後按順序將其寫入(更快!)訂單(請記住,我們有 CoW,這在這裡很自然地工作)。
這樣做的缺點是您收集的時間越長,您的應用程序等待“寫入成功”消息的時間就越長 - 這意味著您的系統將鎖定幾秒鐘,這是不可接受的。更糟糕的是——如果發生電源故障,您將失去所有要寫入磁碟但尚未寫入的數據。如果您的應用程序無法處理此問題,則應用程序層可能會發生損壞。
為了解決這個問題,添加了 ZIL(ZFS 意圖日誌)。所有同步事務都收集在這個日誌中(預設儲存在慢池磁碟上,但可以儲存在速度更快的鏡像 SSD 上,稱為 SLOG 設備),儲存後返回“寫入成功”到可以繼續執行其任務的應用程序(不再鎖定)。此外,所有非同步事務都是在沒有 ZIL 的情況下完成的,因此它們可以更快 - 只要應用程序為其數據呼叫正確的寫入操作(同步與非同步)。
ZFS 屬性
現在來看更有趣的部分——你的作品會發生什麼?在那裡我們必須辨識文件系統的操作模式(它是 ZFS 屬性,可以為每個文件系統單獨設置)。三種可能的模式是(來自手冊頁):
sync=standard This is the default option. Synchronous file system transactions (fsync, O_DSYNC, O_SYNC, etc) are written out (to the intent log) and then secondly all devices written are flushed to ensure the data is stable (not cached by device controllers). sync=always For the ultra-cautious, every file system transaction is written and flushed to stable storage by a system call return. This obviously has a big performance penalty. sync=disabled Synchronous requests are disabled. File system transactions only commit to stable storage on the next DMU transaction group commit which can be many seconds. This option gives the highest performance. However, it is very dangerous as ZFS is ignoring the synchronous transaction demands of applications such as databases or NFS. Setting sync=disabled on the currently active root or /var file system may result in out-of-spec behavior, application data loss and increased vulnerability to replay attacks. This option does *NOT* affect ZFS on-disk consistency. Administrators should only use this when these risks are understood.
您會注意到,即使
disabled
選擇了,您的池佈局/內部一致性也不會受到影響 - 您只會失去最後 5 秒的數據,這可能會使您的文件處於不正確的狀態(例如,因為您有一個虛擬機top 期望同步寫入,但您只提供了一個非同步 zvol 作為備份數據儲存)。另一方面,如果您根本不想失去任何東西,請將所有文件系統設置為
always
並切換到高性能 SSD,至少對於 SLOG 設備(或忍受等待時間)。
standard
是一種折衷方案,也是最靈活的——應用程序本身決定它需要哪種寫入模式。如果您的應用程序不好,您可能會遇到數據失去。如果它們表現良好,您將在給定的安全基線下獲得最佳性能。池導出/導入:
從有關的文件中
zpool export
:該命令會在繼續之前嘗試解除安裝池中任何已安裝的文件系統。如果任何文件系統無法解除安裝,您可以使用 -f 選項強制解除安裝它們。
如果設備在導出時不可用,則無法將設備辨識為乾淨導出。如果其中一個設備稍後連接到沒有任何工作設備的系統,它會顯示為“潛在活動”。
如果池中正在使用 ZFS 卷,則無法導出池,即使使用 -f 選項也是如此。要導出具有 ZFS 卷的池,首先確保該卷的所有使用者不再處於活動狀態。
這大致意味著三件事:
-f
通過強制解除安裝所有文件系統來強制導出池,即使它們處於活動狀態(忽略鎖或寫在那裡的應用程序)- 這不適用於
zvol
s- 您不應該拆分池並在不同的系統上使用它們(小心故障轉移情況)
概括:
- 如果您只關心磁碟上的一致性,那麼您可以使用
export -f
或完全關閉- 如果您關心所有數據,請使用
sync=always
快速 SSD- 關於 iSCSI/NFS 作為 VM 的數據儲存,此概述也可能會有所幫助(摘錄:在來賓/VM 主機上使用 NFS 或禁用 iSCSI 寫回記憶體;在獲取 ZFS 快照之前靜默 VM,無論如何 ZFS 都可以,但來賓 VM 會只有崩潰一致)
回複評論中的後續問題(省略了我沒有任何有用答案的問題):
(1) “好消息/COW”——如果頂層塊即將更新——它是否總能找到可用的頂層塊(即使指向元數據樹的稍舊版本)?這能有多糟糕?
最壞的情況是所有冗餘設備上的超級塊(所有其他塊的頂部)都損壞了。因為它上面沒有塊,你不能從上面重建它,所以每個 uberblock 都存在多個副本(IIRC 大約是 3 或 4 個),所以一個可能會失去並且替換副本仍然存在。
(2) 熟悉TXG,使用ESXi。使用 APC UPS + 良好的 PSU/hw + P3700 NVMe ZIL,所以它是不錯的電源 + 快速 ZIL。但是目前的寫入不太可能全部同步,正如您所說,sync=always 很慢。但是你的回复確實引發了一個想法,我可能會做一些性能測試。我正在使用 dedup(節省 4 倍,值得),所以無論如何 write=slow(必須查找 DDT)。sync=always 的原因只會影響由於 DDT 而導致的緩慢寫入。但是設置 sync=always 會強制執行 ZIL,ZIL 非常快,這使得長 TXG 安全,這可能意味著磁碟訪問更有效。或者它可能會殺死延遲。不知道是哪個!可能得試試!
我對 dedup 沒有真正的經驗,所以我不能在這裡說任何有用的東西,除非你已經在硬體方面做出了很好的選擇(低延遲、高隨機 64k 寫入 IOPS、NVMe 介面)。如果您投資一些非常昂貴的永久 RAM 驅動器(ZeusRAM 等人),它只會更快。
(6)“磁碟一致性”是指 ZFS 是快樂的,池是自洽的?如果某些文件/目錄不擔心。最終出現無效內容或未移動/刪除是池突然消失,或 zvol 上的 NTFWS/VMFS 等文件系統內部損壞(即,作為 ZFS zvol 它很好,但從客戶端的角度來看,它需要 fsck/chkdsk),提供池在 ZFS 看來是安全/一致的
是的。本質上是“我的游泳池沒有搞砸,耶!” 在多使用者設置中 - 即使一個使用者的文件有問題,其他使用者也不會受到影響。
(7)“崩潰一致”是指我的意思嗎(我認為您會這樣做)-ZFS 會很好,就 ZFS 而言,池會很好,但是遠端客戶端的數據可能會從該客戶端的數據中損壞類似於客戶端遇到突然的磁碟 IO 故障並且寫入失去的觀點?== 池會很好,客戶端可能失去/不一致的數據並且可能需要幫助來恢復,就像任何其他磁碟 IO 故障或系統崩潰一樣?
是的,本質上是硬關閉虛擬機而不是乾淨關閉然後拍攝快照 - 如果你之後打開它,
fsck
或者類似的取決於文件系統將執行,它可能會抱怨不干淨的關閉。這與 ESXi 快照不同,後者在準確的時間點恢復,就好像什麼都沒發生一樣,但它們需要與來賓系統互動(安裝來賓添加)並包括 VM 的虛擬記憶體。您可以將兩者結合起來發揮自己的優勢:首先拍攝 ESXi 快照,然後拍攝數據儲存的 ZFS 快照(ESXi 將其快照儲存在 VM 旁邊)。然後刪除您的 ESXi 快照,但保留 ZFS 快照(由於塊級副本佔用的空間要少得多)。還原時,首先還原 ZFS 快照,然後還原到(已保存)的 ESXi 快照,然後從上次中斷的地方繼續。napp-it(帶有 Web 界面的優秀 ZFS 管理系統)內置了這個概念(至少對於 NFS 數據儲存,我沒有檢查 iSCSI,但假設它是相似的)。