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