linux2.6.37内核接两个硬盘导致读写效率变低的问题
一、問題分析:
通過跟蹤定位write系統調用的實現發現,在每次調用a_ops->write_end之后,都會去調用balance_dirty_pages_ratelimited,該函數負責檢查當前系統總的臟頁數是否超過閥值(ratelimit_pages),如果超過,就會去調用balance_dirty_pages去刷新臟頁。ratelimit_pages表示每個cpu臟頁的閥值,超過此閥值,balance_dirty_pages_ratelimited函數就會去查看是否需要強制回寫臟頁。
balance_dirty_pages函數會去讀取系統物理內存全局的臟頁數目、當前的后備存儲器(如磁盤)上的臟頁數目,并與其閥值做比較,從而判斷是否需要回寫臟頁,主要的代碼如下:
bdi_nr_reclaimable:當前后備存儲器的臟頁數目。
bdi_nr_writeback:當前后備存儲器正在回寫的臟頁數目。
bdi_thresh:當前后備存儲區的臟頁閥值,超過此閥值就需要回寫臟頁。
nr_reclaimable:系統全局的臟頁數目。
nr_writeback:系統全局的正在回寫的臟頁數目。
dirty_thresh:系統全局的臟頁閥值。
上述代碼中dirty_exceeded的計算可能出現下面的這種情況:
nr_reclaimable + nr_writeback > dirty_thresh
bdi_nr_reclaimable + bdi_nr_writeback < bdi_thresh
這種情況下dirty_exceeded=1,此時系統中全局的臟頁數目超過閥值,但是當前后備存儲器的臟頁數目并未超過閥值,此時該函數就會一直在此循環等待,等待后臺flush線程定期的回寫臟頁,直到全局臟頁數降低到閥值以下,該函數才會結束循環,而此時write系統調用才會返回,所以就會導致從應用層來看,寫硬盤速度變慢。而此時的io_schedule_timeout會被計算到iowait中,所以會出現iowait 100%的情況。
這種做法是很不合理的,內核把所有磁盤的臟頁全局對待了,沒有嚴格按照目標磁盤來劃分,如果當時系統比較忙,全局的臟頁數超過了閥值,所有需要寫盤的進程都需要等待,直到臟頁的數量降低至閥值以下,這樣嚴重影響了系統寫盤的性能。在出現上述情況時,當前磁盤的臟頁數目低于閥值,應該立刻返回,根本不用等待臟頁回寫。
二、解決方法
1、通過調整proc下相關參數
/proc/sys/vm/dirty_ratio
這個參數控制一個進程在文件系統中的文件系統寫緩沖區的大小,單位是百分比,表示系統內存的百分比,表示當一個進程中寫緩沖使用到系統內存多少的時候,再有磁盤寫操作時開始向磁盤寫出數據。增大之會使用更多系統內存用于磁盤寫緩沖,也可以極大提高系統的寫性能。
/proc/sys/vm/dirty_background_ratio
這個參數控制內核的flush進程何時刷新磁盤。單位是百分比,表示系統總內存的百分比,意思是當磁盤的臟數據達到系統內存多少的時候,flush開始把臟數據刷新到磁盤。增大會使用更多系統內存用于磁盤寫緩沖,也可以極大提高系統的寫性能。
/proc/sys/vm/dirty_writeback_centisecs
這個參數表明內核的flush線程每隔多久被喚醒并執行把臟數據寫出到硬盤。單位是?1/100?秒。缺省數值是500,也就是?5秒。如果你的系統是持續地寫入動作,那么實際上還是降低這個數值比較好,這樣可以把尖峰的寫操作削平成多次寫操作。
?
/proc/sys/vm/dirty_expire_centisecs
這個參數聲明Linux內核寫緩沖區里面的臟數據多久了之后,flush?進程就開始考慮寫到磁盤中去。單位是?1/100秒。缺省是30000,也就是?30?秒的數據就算舊了,將會刷新磁盤。對于特別重載的寫操作來說,這個值適當縮小也是好的,但也不能縮小太多,因為縮小太多也會導致IO提高太快。
通過調整以上四個值,會提高硬盤的寫速度,丟幀的數目也能降到一定的比例,但是始終無法徹底解決該問題。
2、在balance_dirty_pages中使用更加嚴格的判斷機制
由于使用上述判斷dirty_exceeded的機制,只要系統中存在多個IO目標設
備(后備存儲器),如果1個目標設備性能出現降低,導致臟頁回寫變慢,就會嚴重影響到其他目標設備的性能。而實際上,應該把磁盤上的臟頁分開來進行處理,只有各自的磁盤上累積的臟頁比較多,才需要等待后臺刷新,否則就可以直接跳出循環函數,繼續寫磁盤。而在linux3.2的版本上,應用了更加嚴格的判斷dirty_exceeded的機制,參照高版本內核的修改,修改linux2.6.37的內核:
dirty_exceeded =
?????????? (bdi_nr_reclaimable + bdi_nr_writeback > bdi_thresh)
?????????? && (nr_reclaimable + nr_writeback > dirty_thresh);
只有當前系統全局的臟頁數超過閥值并且當前的磁盤臟頁數目也超過閥值,才認為需要等待臟頁的回寫,否則,直接退出循環,繼續進行后續的寫操作。通過這種修改,只有在當前磁盤的臟頁數目超過閥值,才會在當前磁盤上等待臟頁回寫。當系統中有多個后備存儲器時,多個后備存儲器之間互相不影響,各自管理各自的臟頁數目,使系統對臟頁的處理更加的合理。
from:http://sunjiangang.blog.chinaunix.net/uid-9543173-id-3571758.html
轉載于:https://www.cnblogs.com/wangfengju/p/6172381.html
總結
以上是生活随笔為你收集整理的linux2.6.37内核接两个硬盘导致读写效率变低的问题的全部內容,希望文章能夠幫你解決所遇到的問題。