Performance

在外部磁碟上執行大型 R/W 操作時系統滯後

  • March 26, 2019

在 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 磁碟的成像速度,因此減慢這些操作以利於系統平穩執行的解決方案對我來說很好。

我該如何補救?

寫入磁碟映像時,請使用ddwith oflag=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_ratioor dirty_bytes。但整個故事要復雜得多。不同設備的髒記憶體之間應該存在某種程度的仲裁。有較早的門檻值啟動,並試圖限制任何一台設備使用的最大臟記憶體的比例。不過,很難理解這一切到底有多好。

我認為您提到在映像“多個 USB 磁碟”時遇到問題。例如,當您嘗試寫入其中一個磁碟時,每個設備的門檻值可能效果很好,但一旦您同時寫入多個磁碟,就會崩潰。但這只是一個想法;我不知道到底發生了什麼。

有關的:

一些使用者在寫入慢速 USB 記憶棒時觀察到他們的整個系統滯後,並發現降低整體臟限制有助於避免滯後。我不知道對此有什麼好的解釋。

為什麼在 2013 年報告了“U 盤失速”問題?為什麼現有的“No-I/O 臟節流”程式碼沒有解決這個問題?

“寫回節流”是解決“USB 記憶棒失速問題”的方法嗎?

引用自:https://unix.stackexchange.com/questions/474119