在外部磁碟上執行大型 R/W 操作時系統滯後
在 Ubuntu 18.04 系統上執行大型磁碟映像操作時,我遇到了一些系統範圍的延遲/滯後問題。這是系統規格:
處理器:英特爾酷睿 i7(絕不接近任何核心的容量)
記憶體:12GB(永不接近容量)
系統盤:SSD(永不接近容量)
外部磁碟:USB 3.0 5400 和 7200RPM 旋轉磁碟
這些大磁碟鏡像操作基本上是:
nice ionice dd if=/dev/usbdisk1 of=/dev/usbdisk2
由於我的系統文件都沒有在任何 USB 磁碟上,理論上,這不應該引入太多延遲。但是我發現,當我對多個 USB 磁碟進行映像時,系統就會爬行。為什麼?我的理解是每個磁碟都有自己的IO隊列,那麼這裡是怎麼回事呢?我該如何補救?
此外,FWIW,我根本不關心 USB 磁碟的成像速度,因此減慢這些操作以利於系統平穩執行的解決方案對我來說很好。
我該如何補救?
寫入磁碟映像時,請使用
dd
withoflag=direct
。O_DIRECT 寫入將避免通過頁面記憶體寫入數據。注意oflag=direct
將需要更大的塊大小,以獲得良好的性能。這是一個例子:dd if=/dev/usbdisk1 of=/dev/usbdisk2 oflag=direct bs=32M status=progress
注意:有時您可能希望通過管道傳輸來自另一個程序的磁碟映像,例如
gunzip
. 在這種情況下,良好的性能還取決於通過另一個命令進行iflag=fullblock
管道傳輸。dd
此處的答案中有一個完整的範例:為什麼 gunzip 到 dd 管道最後會變慢?(另一種解決方案是使用
oflag=sync
而不是oflag=direct
. 這可以通過不建構大量未寫入的記憶體頁面來實現)。我的理解是每個磁碟都有自己的IO隊列,那麼這裡是怎麼回事呢?
他們是這樣。但是,寫入的數據首先儲存在系統頁面記憶體中(在 RAM 中),然後再排隊 IO…
編輯:
由於這個答案被接受,我假設你重新測試了
oflag=direct
,它解決了你的問題,即“系統剛剛開始爬行”。偉大的。最安全的選擇也是添加
iflag=direct
。如果沒有這個選項,dd
仍然是通過系統頁面記憶體*讀取數據。*我假設您在沒有告訴我的情況下沒有添加此選項。這是對您的具體問題的一個提示。應該清楚的是,通過頁面記憶體讀取過多的數據可能會影響系統性能。您通過頁面記憶體推送的數據總量是系統 RAM 的幾倍 :-)。根據讀取的模式,核心可以決定開始丟棄(或交換)其他記憶體數據以騰出空間。
核心沒有萬無一失的遠見。如果您需要使用從記憶體中刪除的數據,則必須從您的磁碟/SSD 重新載入。證據似乎告訴我們這不是你的問題。
臟頁記憶體限制
但是,您的問題更有可能與通過頁面記憶體*寫入數據有關。*未寫入的記憶體,也就是“臟”頁記憶體,是有限的。例如,您可以想像整個臟頁記憶體被限制為 RAM 的 20%。(這是一個方便想像的謊言。真相在這裡寫得亂七八糟)。
如果您的
dd
命令設法填滿最大的髒頁記憶體,它們將被迫“阻塞”(等待),直到一些數據被寫出。但同時,任何其他想寫的程序也會被阻塞(除非它使用O_DIRECT)。這可能會使您的許多桌面程序停止執行,例如當它們嘗試寫入日誌文件時。即使他們正在寫入不同的設備。
整體臟限制被命名為
dirty_ratio
ordirty_bytes
。但整個故事要復雜得多。不同設備的髒記憶體之間應該存在某種程度的仲裁。有較早的門檻值啟動,並試圖限制任何一台設備使用的最大臟記憶體的比例。不過,很難理解這一切到底有多好。我認為您提到在映像“多個 USB 磁碟”時遇到問題。例如,當您嘗試寫入其中一個磁碟時,每個設備的門檻值可能效果很好,但一旦您同時寫入多個磁碟,就會崩潰。但這只是一個想法;我不知道到底發生了什麼。
有關的:
一些使用者在寫入慢速 USB 記憶棒時觀察到他們的整個系統滯後,並發現降低整體臟限制有助於避免滯後。我不知道對此有什麼好的解釋。