正常執行 30 分鐘後,同步/fsync 呼叫速度減慢
使用帶有混合 SSD的 Ubuntu 14.04 執行 30 分鐘後,我看到許多程序使用
iotop
. 這是在磁碟寫入期間,例如,如果我在 gedit 中打開和關閉一個空文件,由於 dconf 寫入設置,可能需要 2 秒才能關閉,這會以類似的方式影響其他應用程序;嚴重減慢整個系統的速度。使用 strace 我設法將其追溯到 fsync 呼叫,並從那裡設法使用 sync 命令重現它。
回顧一下,簡單地
sync
從終端重複執行可能需要 1-2 秒的時間,但只有在 30 分鐘的正常執行時間之後。為了證明這一點,我製作了一個腳本,以秒為單位輸出正常執行時間與執行同步所需的時間,並每秒執行一次:
while true; do cat /proc/uptime | awk '{printf "%f ",$1}'; /usr/bin/time -f '%e' sync; sleep 1; done;
我執行了上面的腳本,等待了大約一個小時(系統處於空閒狀態),然後在 gnuplot 中繪製了結果(y = 執行同步的時間,x = 正常執行時間,以秒為單位):
圖表出現峰值的時間點大約是 1780(1780/60 = 大約 30 分鐘)。
除了腳本之外,此時不應將任何內容寫入磁碟,因此在第一次同步後頁面記憶體中應該幾乎沒有任何內容,每個後續同步都將準確寫入正在寫入腳本的內容,大約為 100 字節或所以。
重啟後此問題仍然存在;例如 - 如果我等待 30 分鐘減速然後重新啟動,減速仍然存在。如果我關機然後重新啟動,問題就會消失,直到 30 分鐘後。
另一個好奇心是,當我檢查上圖並放大正在發生減速的區域時,我得到了這個:
波峰和波谷重複——從波谷到波谷幾乎每 10 秒發生一次,而且波峰在下降時會扭結。
在減速之前,我還執行了 hdparm 測試(
hdparm -t /dev/sda
和):hdparm -T /dev/sda
/dev/sda: Timing cached reads: 23778 MB in 2.00 seconds = 11900.64 MB/sec /dev/sda: Timing buffered disk reads: 318 MB in 3.01 seconds = 105.63 MB/sec
在減速期間:
/dev/sda: Timing cached reads: 2 MB in 2.24 seconds = 915.50 kB/sec /dev/sda: Timing buffered disk reads: 300 MB in 3.01 seconds = 99.54 MB/sec
顯示實際的磁碟讀取沒有受到影響,但記憶體的讀取受到影響,這是否意味著這與系統匯流排有關,而不是 HD?
這是我嘗試過的解決方案:
- 更改 HD 的降速設置,可能 HD 正在進入省電模式:
hdparm /dev/sda -S252 #(set it to 5 hours before spindown)
- 將文件系統的日誌類型更改為寫回而不是排序,以便我們獲得性能改進 - 這並不能解決問題,因為它不能解釋 30 分鐘無減速的正常執行時間。
- 禁用 CRON,因為它似乎在 30 分鐘後發生。
- CPU使用率很好並且完全空閒,所以沒有程序可以被指責但是我已經嘗試關閉包括會話管理器(lightdm)在內的所有服務,這沒有任何作用,因為我認為問題是較低級別的。
- 分析任何在 30 分鐘後進入的新程序表明沒有變化——我已經區分了 PS 之前和之後的輸出,沒有任何區別。
這僅在大約 2 週前開始發生,當時沒有安裝任何東西,也沒有進行任何更新。我認為這個問題的級別要低得多,所以真的很感謝這裡的一些幫助,因為我一無所知,即使指出我正確的方向也會有所幫助 - 例如,有沒有辦法檢查頁面記憶體中被刷新的內容?
在有問題的磁碟上啟用了寫記憶體,我也嘗試過禁用寫屏障。HD 上的 SMART 數據表明 HD 本身沒有問題,但是我懷疑 HD 做了一些神秘的事情,因為它在重新啟動後仍然存在。
編輯:
我弄完了 :
watch -n 1 cat /proc/meminfo
…查看記憶體如何變化,特別是查看臟行和我認為是 HD 磁碟緩衝區的寫回行。它們大部分都保持為零,最高可能是 300kb。呼叫 sync 會按預期將這些刷新回 0,但在減速期間呼叫 sync 當磁碟緩衝區中的髒頁為零且 kb 為零時仍會鎖定 IO。如果沒有刷新頁面記憶體和寫入記憶體的內容,同步還能做什麼?
這些症狀與大部分飽和的 IO 系統非常一致,但是在很大程度上排除了來自作業系統/使用者空間端的 IO 負載,另一種可能性是驅動器自身執行自檢,其中可能包括從所有扇區讀取。這應該可以從 smartctl 查詢/調整(至少有一個地方是 smartctl -c 用於查詢)。
至於為什麼來來去去,現在突然開始:
- 驅動器在其生命週期中已經過了某個階段(寫入的扇區數、旋轉時間等),並且驅動器上的韌體觸發了這些掃描之一
- 我相信這也可以通過 smartctl 觸發,因此可能是一些自動化過程觸發了它
- 觸發其中一個掃描並將其標記為正在進行或已啟動,當驅動器已花費一定時間通電時,它會從頭開始重新觸發或從中斷處恢復