轉:https://www.cnblogs.com/shengs/p/5085980.htmlhtml
關於頁面緩存的信息,能夠用
cat /proc/meminfo
看到。其中的Cached 指用於pagecache的內存大小(diskcache-SwapCache)。隨着寫入緩存頁,Dirty 的值會增長。
一旦開始把緩存頁寫入硬盤,Writeback的值會增長直到寫入結束。
Linux 用pdflush進程把數據從緩存頁寫入硬盤,查看有多少個pdflush進程
cat /proc/sys/vm/nr_pdflush_threads
pdflush的行爲受/proc/sys/vm中的參數的控制
/proc/sys/vm/dirty_writeback_centisecs (default 500):
1/100秒, 多長時間喚醒pdflush將緩存頁數據寫入硬盤。默認5秒喚醒2個(更多個)線程。
若是wrteback的時間長於dirty_writeback_centisecs的時間,可能會出問題。
pdflush的第一件事是讀取
/proc/sys/vm/dirty_expire_centiseconds (default 3000)
1/100秒。緩存頁裏數據的過時時間(舊數據),在下一個週期內被寫入硬盤。默認30秒是一個很長的時間。
第二件事是判斷內存是否到了要寫入硬盤的限額,由參數決定:
/proc/sys/vm/dirty_background_ratio (default 10)
百分值,保留過時頁緩存(髒頁緩存)的最大值。是以MmeFree+Cached-Mapped的值爲基準的
pdflush寫入硬盤看兩個參數:
1 數據在頁緩存中是否超出30秒,若是是,標記爲髒頁緩存;
2 髒頁緩存是否達到工做內存的10%;
如下參數也會影響到pdflush
/proc/sys/vm/dirty_ratio (default 40)
總內存的最大百分比,系統所能擁有的最大髒頁緩存的總量。超過這個值,開啓pdflush寫入硬盤。若是cache增加快於pdflush,那麼整個系統在40%的時候遇到I/O瓶頸,全部的I/O都要等待cache被pdflush進硬盤後才能從新開始。
對於有高度寫入操做的系統
dirty_background_ratio: 主要調整參數。若是須要把緩存持續的而不是一會兒大量的寫入硬盤,下降這個值。
dirty_ratio: 第二調整參數。
Swapping參數
/proc/sys/vm/swappiness
默認,linux傾向於從物理內存映射到硬盤緩存,保持硬盤緩存儘量大。未用的頁緩存會被放進swap區。
數值爲0,將會避免使用swapping
100,將會盡可能使用swapping
少用swapping會增長程序的響應速度;多用swapping將會提升系統的可用性。
若是有大量的寫操做,爲避免I/O的長時間等待,能夠設置:
$ echo 5 > /proc/sys/vm/dirty_background_ratio
$ echo 10 > /proc/sys/vm/dirty_ratio
文件系統數據緩衝須要頻繁的內存分配。加大保留內存的值能提高系統速度和穩定。小於8G的內存,保留內存爲64M,大於8G的設置爲256M
$ echo 65536 > /proc/sys/vm/min_free_kbytes
I/O 調度器
cat /sys/block/[disk]/queue/scheduler
4中調度算法
noop anticipatory deadline [cfq]
deadline : deadline 算法保證對既定的IO請求以最小的延遲時間。
anticipatory: 有個IO發生後,若是又有進程請求IO,則產生一個默認6ms猜想時間,猜想下一個進程請求IO是幹什麼。這對於隨機讀取會形成較大的延時。
對數據庫應用很糟糕,而對於Web Server等則會表現不錯。
cfq: 對每一個進程維護一個IO隊列,各個進程發來的IO請求會被cfq以輪循方式處理,對每個IO請求都是公平。適合離散讀的應用。
noop: 對全部IO請求都用FIFO隊列形式處理。默認IO不會存在性能問題。
改變調度器
$ echo deadline > /sys/block/sdX/queue/scheduler
對於數據庫服務器,deadline算法是推薦的。
提升調度器請求隊列的
$ echo 4096 > /sys/block/sdX/queue/nr_requests
有大量的讀請求,默認的請求隊列應付不過來,能夠提升這個值。缺點是要犧牲必定的內存。
爲了增長連續讀取的吞吐量,能夠增長預讀數據量。預讀的實際值是自適應的,因此使用一個較高的值,不會下降小型隨機存取的性能。
$ echo 4096 > /sys/block/sdX/queue/read_ahead_kb
若是LINUX判斷一個進程在順序讀取文件,那麼它會提早讀取進程所需文件的數據,放在緩存中。
服務器遇到磁盤寫活動高峯,致使請求處理延遲很是大(超過3秒)。經過調整內核參數,將寫活動的高峯分佈成頻繁的屢次寫,每次寫入的數據比較少。這樣能夠把尖峯的寫操做削平成屢次寫操做。以這種方式執行的效率比較低,由於內核不太有機會組合寫操做。但對於繁忙的服務器,寫操做將更一致地進行,並將極大地改進交互式性能。node
/proc/sys/vm/dirty_ratiopython
控制文件系統的寫緩衝區的大小,單位是百分比,表示佔系統內存的百分比,表示當寫緩衝使用到系統內存多少的時候,開始向磁盤寫出數據。增大之會使用更多系統內存用於磁盤寫緩衝,也能夠極大提升系統的寫性能。可是,當你須要持續、恆定的寫入場合時,應該下降其數值。linux
/proc/sys/vm/dirty_background_ratio
控制文件系統的pdflush進程,在什麼時候刷新磁盤。單位是百分比,表示系統內存的百分比,pdflush用於將內存中的內容和文件系統進行同步,好比說,當一個文件在內存中進行修改,pdflush負責將它寫回硬盤.每當內存中的垃圾頁(dirty page)超過10%的時候,pdflush就會將這些頁面備份回硬盤.增大之會使用更多系統內存用於磁盤寫緩衝,也能夠極大提升系統的寫性能。可是,當你須要持續、恆定的寫入場合時,應該下降其數值:ios
/proc/sys/vm/dirty_writeback_centisecs
控制內核的髒數據刷新進程pdflush的運行間隔。單位是 1/100 秒。缺省數值是500,也就是 5 秒。若是你的系統是持續地寫入動做,那麼實際上仍是下降這個數值比較好,這樣能夠把尖峯的寫操做削平成屢次寫操做。
若是你的系統是短時間地尖峯式的寫操做,而且寫入數據不大(幾十M/次)且內存有比較多富裕,那麼應該增大此數值。
該參數的設置應該小於dirty_expire_centisecs,但也不能過小,過小I/O太頻繁,反而
使系統性能降低。具體可能須要在生產環境上測試。聽說1:6 (dirty_expire_centisecs : dirty_writeback_centisecs )的比例比較好。算法
/proc/sys/vm/dirty_expire_centisecs
數據庫
聲明Linux內核寫緩衝區裏面的數據多「舊」了以後,pdflush進程就開始考慮寫到磁盤中去。單位是 1/100秒。缺省是 30000,也就是 30 秒的數據就算舊了,將會刷新磁盤。對於特別重載的寫操做來講,這個值適當縮小也是好的,但也不能縮小太多,由於縮小太多也會致使IO提升太快。
固然,若是你的系統內存比較大,而且寫入模式是間歇式的,而且每次寫入的數據不大(好比幾十M),那麼這個值仍是大些的好。api
/proc/sys/vm/vfs_cache_pressure
緩存
表示內核回收用於directory和inode cache內存的傾向;缺省值100表示內核將根據pagecache和swapcache,把directory和inode cache保持在一個合理的百分比;下降該值低於100,將致使內核傾向於保留directory和inode cache;增長該值超過100,將致使內核傾向於回收directory和inode cache服務器
/proc/sys/vm/min_free_kbytes
表示強制Linux VM最低保留多少空閒內存(Kbytes)。
缺省設置:724(512M物理內存)
/proc/sys/vm/nr_pdflush_threads
表示當前正在運行的pdflush進程數量,在I/O負載高的狀況下,內核會自動增長更多的pdflush進程。
/proc/sys/vm/overcommit_memory
指定了內核針對內存分配的策略,其值能夠是0、一、2。
0, 表示內核將檢查是否有足夠的可用內存供應用進程使用;若是有足夠的可用內存,內存申請容許;不然,內存申請失敗,並把錯誤返回給應用進程。
1, 表示內核容許分配全部的物理內存,而無論當前的內存狀態如何。
2, 表示內核容許分配超過全部物理內存和交換空間總和的內存(參照overcommit_ratio)。
缺省設置:0
/proc/sys/vm/overcommit_ratio
若是overcommit_memory=2,能夠過載內存的百分比,經過如下公式來計算系統總體可用內存。系統可分配內存=交換空間+物理內存*overcommit_ratio/100
缺省設置:50(%)
/proc/sys/vm/page-cluster
表示在寫一次到swap區的時候寫入的頁面數量,0表示1頁,1表示2頁,2表示4頁。
缺省設置:3(2的3次方,8頁)
/proc/sys/vm/swapiness
表示系統進行交換行爲的程度,數值(0-100)越高,越可能發生磁盤交換。
更改:
/etc/sysctl.conf
vm.dirty_ratio = 40
sysctl -p
查看:
find /proc/sys/vm -name dirty* -print | while read name; do echo $name ;cat ${name}; done
(1)使用hdparm命令檢測讀取速度:
hdparm命令提供了一個命令行的接口用於讀取和設置IDE和SCSI硬盤參數。
安裝:
yum install hdparm
語法:
hdparm(選項)(參數)
經常使用選項:
-f: 將內存緩衝區的數據寫入硬盤,並清除緩衝區;
-g: 顯示硬盤的磁軌,磁頭,磁區等參數;
-i: 顯示硬盤的硬件規格信息,這些信息是在開機時由硬盤自己所提供;
-I: 直接讀取硬盤所提供的硬件規格信息;
-t: 評估硬盤的讀取效率;
-T: 評估硬盤快取的讀取效率;
參數:
設備文件:指定id驅動對應的設備文件名
實例:
使用方法很簡單,hdparm -Tt /dev/sda
[root@super python]# hdparm -Tt /dev/sda
/dev/sda:
Timing cached reads: 8470 MB in 2.00 seconds = 4235.83 MB/sec # 硬盤的快取讀取速度,2.00秒讀取了8470 MB,平均每秒讀取:4235.83 MB/sec
Timing buffered disk reads: 722 MB in 3.22 seconds = 224.28 MB/sec # 硬盤的讀取速度:3.22秒讀取了722 MB,平均每秒讀取:224.28 MB/sec
(2) 使用dd命令測試寫入速度:
dd命令是一個不太專業的測速工具,若是要求的不是很嚴格,仍是能夠進行屢次測試來獲得一個近似值的。
安裝:
yum install coreutils
實例:
[root@super python]# dd if=/dev/zero of=test bs=1M count=2048 # 寫入一個文件名test, bytes 爲1M,共2048 blocks 的文件,總共大小爲:1M * 2048 = 2G
記錄了2048+0 的讀入
記錄了2048+0 的寫出
2147483648字節(2.1 GB)已複製,88.8786 秒,24.2 MB/秒
88.8786 秒寫入了2.1 GB數據,平均:24.2 MB/秒
#iostat -x 1
avg-cpu:%user%nice%sys%idle
16.240.004.3179.44
Device:rrqm/swrqm/sr/sw/srsec/swsec/srkB/swkB/savgrq-szavgqu-szawaitsvctm%util
/dev/cciss/c0d0
0.0044.901.0227.558.16579.594.08289.8020.5722.3578.215.0014.29
/dev/cciss/c0d0p1
0.0044.901.0227.558.16579.594.08289.8020.5722.3578.215.0014.29
/dev/cciss/c0d0p2
0.000.000.000.000.000.000.000.000.000.000.000.000.00
上面的iostat輸出代表秒有28.57次設備I/O操做:總IO(io)/s=r/s(讀)+w/s(寫)=1.02+27.55=28.57(次/秒)其中寫操做佔了主體(w:r=27:1)。
平均每次設備I/O操做只須要5ms就能夠完成,但每一個I/O請求卻須要等上78ms,爲何?由於發出的I/O請求太多(每秒鐘約29個),假設這些請求是同時發出的,那麼平均等待時間能夠這樣計算:
平均等待時間=單個I/O服務時間*(1+2+…+請求總數-1)/請求總數
應用到上面的例子:平均等待時間=5ms*(1+2+…+28)/29=70ms,和iostat給出的78ms的平均等待時間很接近。這反過來代表I/O是同時發起的。
每秒發出的I/O請求不少(約29個),平均隊列卻不長(只有2個左右),這代表這29個請求的到來並不均勻,大部分時間I/O是空閒的。
一秒中有14.29%的時間I/O隊列中是有請求的,也就是說,85.71%的時間裏I/O系統無事可作,全部29個I/O請求都在142毫秒以內處理掉了。
delta(ruse+wuse)/delta(io)=await=78.21=>delta(ruse+wuse)/s=78.21*delta(io)/s=78.21*28.57=2232.8,代表每秒內的I/O請求總共須要等待2232.8ms。因此平均隊列長度應爲2232.8ms/1000ms=2.23,而iostat給出的平均隊列長度(avgqu-sz)卻爲22.35,爲何?!由於iostat中有bug,avgqu-sz值應爲2.23,而不是22.35。