順序讀性能調優
VMM 的順序預讀功能能夠改進需要順序訪問大文件的程序的性能。
下面的插圖展示了典型的預讀的情況。
順序預讀的例子. 插圖顯示了用一行塊模擬一分段磁道的文件頁號。這些塊段按 0,1 到 3,4 到 7,8 到 15 以及 16 到 23 編號。順序預讀的步驟可以在緊接著插圖后的文本中找到。
在這個例子中,minpgahead 的值為 2,maxpgahead 的值為 8 (缺省值)。程序順序處理文件。圖中只顯示了對預讀機制有重要作用的數據引用(按從 A 到 F 的順序標出)。這些步驟是:
A
第一次文件訪問讀取文件的第一頁(第 0 頁)。在這個時候,VMM 并不知道這次訪問是隨機還是順序訪問。
B
當程序訪問下一頁(第 1 頁)的首字節而不存在對文件其它頁的插入訪問時,VMM 推斷出該程序正在進行順序訪問。于是將頁提前量設為 minpgahead (2) 并且調度讀取額外的頁(第二、三頁)。這樣步驟 B 總共讀取了 3 頁。
C
當程序訪問預讀的第一頁(第 2 頁)的首字節時,VMM 將頁提前量加倍到 4 并且調度讀取第 4 到 7 頁。
D
當程序訪問前次預讀的第一頁(第 4 頁)的首字節時,VMM 將頁提前量加倍到 8 并且調度讀取第 8 到 15 頁。
E
當程序訪問前次預讀的第一頁(第 8 頁)的首字節時,VMM 決定將頁提前量設為 maxpgahead 并且調度讀取第 16 到 23 頁。
F
VMM 在程序訪問前一組預讀頁的首字節的情況下繼續預讀 maxpgahead 頁直到文件結尾。
一旦程序偏離了順序訪問模式并且不按次序訪問了文件中的一頁,順序預讀就會終止。當 VMM 檢測到程序恢復順序訪問后,頁提前量便會恢復到 minpgahead 頁。
可在 ioo 命令中使用 -r 和 -R 選項來更改 minpgahead 和 maxpgahead 的值。如果您打算改變這些值,請記?。?BR>該值必須是集合:0、1、2、4、8、16 等中的一個。使用其它值可能會對性能或功能造成不利影響。
o 由于 VMM 的加倍算法,該值應該是 2 的冪。
o 大于 16 的 maxpgahead 值(預讀量大于 64 KB)會超出某些磁盤設備驅動程序的能力。在這種情況下,預讀的大小會保持在 64 KB。
o 更大的 maxpgahead 值可用于條帶狀邏輯卷的順序性能顯得至關重要的系統中。
minpgahead 和 maxpgahead 的值都為 0 能有效消除此機制。這會給性能帶來負面影響。但是,在 I/O 隨機的一些情況下,這可能也有用處,這時 I/O 的大小會使預讀算法生效。
對于非條帶狀文件系統,當 maxpgahead 值為 8 或 16 時,其順序 I/O 性能會達到可能的最大值。
預讀值從 minpgahead 增加到 maxpgahead 的過程很快,對于大多數文件大小來說增大 minpgahead 值都不會帶來任何性能的提高。
可以針對 JFS 和增強型 JFS 分別調優順序預讀功能。JFS 的預讀頁可以通過改變 minpgahead 和 maxpgahead 的值調優,而增強型 JFS 使用 j2_minPageReadAhead 和 j2_maxPageReadAhead。
順序和隨機后寫性能調優
后寫涉及在達到某個閾值后將內存中修改過的頁面異步寫到磁盤上,而不是等待 syncd 守護程序將頁面清空到磁盤上。這被用于限制內存中的臟頁數,減少系統開銷和最小化磁盤碎片。后寫有兩種類型:順序后寫和隨機后寫。
順序后寫
缺省情況下,一個 JFS 文件劃分成 16 KB 大小的分區或 4 頁。每一個這樣的分區被稱為一簇。如果該簇中的 4 頁都是臟頁,那么一旦修改完下一個分區,系統就會調度該簇中的 4 頁并將其寫入磁盤。如果不具備這一功能,則直到 syncd 守護程序運行前,該頁都會留存于內存,導致可能的 I/O 瓶頸和文件碎片。
VMM 用于充當閾值的簇數是可調優的。缺省值是一簇。使用 ioo -o numclust 命令來增加 numclust 參數可以延遲后寫。
對于增強型 JFS,ioo -o j2_nPagesPerWriteBehindCluster 命令用來指定每次調度的頁數,而不是簇數。增強型 JFS 簇的缺省頁數為 32,意味著增強型 JFS 的缺省大小為 128 KB。
隨機后寫
可能存在一些應用程序執行大量的隨機 I/O,即 I/O 模式不滿足后寫算法的要求,因而導致所有頁面駐留在內存中,直到 syncd 守護程序運行為止。如果應用程序在內存中修改了許多頁,就有可能在 syncd 守護程序調用 sync() 時向磁盤寫入大量頁。
后寫功能提供了這樣一種機制,即當給定文件在內存中的臟頁數超過規定閾值后,則會調度所寫的后續頁面以寫到磁盤上。
通過使用 ioo 命令并帶有 JFS maxrandwrt 參數可調整此閾值。缺省值為 0,表示隨機后寫是禁用的。將該值增加到 128 表示一旦文件駐留于內存的頁達到 128 頁,隨后的任何臟頁都將被調度寫入磁盤。而這些頁將在調用 sync() 后刷新。
對于增強型 JFS,ioo 命令選項 j2_nRandomCluster(-z 標志)和 j2_maxRandomWrite(-J 標志)用來調優隨機后寫。增強型 JFS 的 j2_maxRandomWrite 選項和 JFS 的 maxrandwrt 選項功能相同。即它限定了每個文件可以留在內存中的臟頁數。j2_nRandomCluster 選項指定了可以被視為隨機的兩次連續寫入之間的簇數。
異步磁盤 I/O 性能調優
如果應用程序進行同步 I/O 操作,它必須等待 I/O 完成后才能繼續執行。相反,異步 I/O 操作在后臺運行,不會阻塞用戶應用程序。這就改進了性能,因為 I/O 操作和處理中的應用程序可以同時運行。許多應用程序,諸如數據庫和文件服務器,利用了重疊處理和重疊 I/O 的能力。
應用程序可以使用 aio_read() 命令、aio_write() 或 lio_listio() 子例程(或它們的副本)來執行異步磁盤 I/O。一旦請求被排隊,控制權就從子例程返回應用程序。當磁盤操作被執行時,應用程序可以繼續處理。
為了管理異步 I/O,每一個異步 I/O 請求在應用程序地址空間有一個相應的控制塊。該控制塊包含了請求的控制和狀態信息。在 I/O 操作完成后可以被再次使用。
在發出了一個異步 I/O 請求,用戶應用程序可以決定何時并以何種方式結束 I/O 操作。這些信息在以下三種方式的任何一種中提供:
應用程序可以輪詢 I/O 操作的狀態。
當 I/O 操作完成后系統可以異步通知應用程序。
應用程序可以阻塞,直到 I/O 操作完成。
每個 I/O 是由單個 kproc 處理,并且一般來說 kproc 不能處理任何更多的隊列中的請求,直到 I/O 已經完成。當異步 I/O 啟用時,缺省的配置好的服務器最小數目為 1。這是 minservers 屬性。還存在一個可以創建的最大異步 I/O 服務器數,它由 maxservers 屬性控制,缺省值為 10(每個 CPU)。服務器的數量限制了可以在系統中同時處理的異步磁盤 I/O 操作的數目。服務器數可用 SMIT 命令(smitty -> 設備 -> 異步 I/O -> 更改/顯示異步 I/O 的特征 -> {MINIMUM | MAXIMUM} 服務器數目或 smitty aio)或者使用 chdev 命令來設置。
很少運行應用程序的系統可以使用異步 I/O,缺省值通??梢悦銖妷蛴?。
如果異步 I/O 請求數目是高的,那么推薦您增加 maxservers 大約至同時 I/O 可能的數目。在大多數情況下,您最好保留 minservers 參數為缺省值,因為如果需要的話,AIO 內核擴展將生成附加的服務器數。
注:
執行在裸邏輯卷上的 AIO 操作并不使用 kproc 服務器進程。有關 maxservers 和 minservers 的設置在這種情況下沒有效果。
通過查看 AIO 服務器的 CPU 利用率,如果利用率在它們中間均勻的分配,那就意味著它們都在使用中;在這種情況下,您可能要增加它們的數量。以名稱查看 AIO 服務器,運行 pstat -a 命令。運行 ps -k 命令來查看名稱為 kproc 的 AIO 服務器。
在異步磁盤 I/O 的性能很重要并且卷請求很高,而你又沒有一個適當的同步 I/O 數量的環境下,建議把 maxservers 至少設置為 10(異步存儲磁盤的數)。
對系統來說可以通過三個異步存取磁盤獲得,如下所示:
# chdev -l aio0 -a maxservers='30'
此外,您可以設置未完成異步 I/O 請求的最大值以及服務器的優先級。如果您的系統擁有大量的異步 I/O 應用程序,那就可以適當地增加請求數以及降低優先級數目。
文件同步性能調優
JFS 的非順序文件 I/O 會一直存儲在內存中直到滿足一定條件:
空閑列表縮小到 minfree,以致需要進行頁替換。
syncd 守護程序按固定調度間隔刷新頁。
執行了 sync 命令。
隨機后寫在達到隨機后寫閾值后清空臟頁面。
如果在以上的任一條件滿足前已存儲了過多頁,則在 syncd 守護程序進行刷新時,會獲得一個 i-node 鎖并保持到所有的臟頁都被寫入磁盤。在這段時間里,任何試圖訪問此文件的線程會由于無法獲得 i-node 鎖而被阻塞。請記?。簊yncd 守護程序會順利的刷新一個文件中的所有臟頁,但限于一次一個文件。在一個擁有大量內存并同時有大量頁需要修改的系統中,syncd 守護程序刷新頁時 I/O 可能達到高峰值。
AIX 有一個稱為 sync_release_ilock 的可調選項。ioo 命令加上 -o sync_release_ilock=1 選項允許在清空該文件的臟頁面后釋放 i-node 鎖。這一選項使得在調用 sync() 的過程中訪問該文件有更好的響應。
阻塞效果也可通過在 syncd 守護程序中提高同步頻率使之最小化。更換用于啟用 syncd 守護程序的 /sbin/rc.boot。然后重新引導系統使之生效。對現行系統,殺死 syncd 守護程序進程并按新的值重新啟動守護程序。
第三種調優這種行為的方法是使用 ioo 命令開啟隨機后寫功能
文件系統緩沖區調優
以下 ioo 參數可用于調優磁盤 I/O:
numfsbufs 參數
當有大量針對文件系統的同步或大型 I/O 或是存在針對文件系統的大型順序 I/O 時,這些 I/O 可能會在等待 bufstruct 時成為文件系統級的瓶頸。每個文件系統的 bufstructs 數目(稱為 numfsbufs)可使用 ioo 命令增加。該值僅在文件系統加載后才會生效;因此如果更改了這個值,則必須卸載然后再次加載文件系統。numfsbufs 的缺省值目前為每個文件系統 93 個 bufstruct。
j2_nBufferPerPagerDevice 參數
在增強型 JFS 中,bufstruct 數量由參數 j2_nBufferPerPagerDevice 指定。當前增強型 JFS 文件系統的缺省 bufstruct 數是 512。每個增強型 JFS 文件系統的 bufstructs 數(j2_nBufferPerPagerDevice)可以使用 ioo 命令來增加。該值在文件系統被加載后才起作用。
lvm_bufcnt 參數
如果應用程序正在處理很大量的裸 I/O 而不通過文件系統,同文件系統相同類型的瓶頸也可能出現在 LVM 層上。極大量的 I/O 加上極快的 I/O 設備可能會導致 LVM 層上的瓶頸。但是如果真的出現瓶頸,則可以通過 ioo 命令增加 lvm_bufcnt 參數,以提供大量的“uphysio”緩沖區。該值會立刻生效。當前的缺省值是 9 個 “uphysio” 緩沖區。由于當前 LVM 將 I/O 分為每個 128 K,而 lvm_bufcnt 的缺省值為 9,故一次可寫入 9*128 K。如果正在進行的 I/O 大于 9*128 K,增加 lvm_bufcnt 的值才會有利。
hd_pbuf_cnt 參數
hd_pbuf_cnt 參數控制可用于 LVM 設備驅動程序的 pbufs 數。pbuf 是用于存放暫掛于 LVM 層的 I/O 請求的固定內存緩沖區。
在 AIX 中,順序 I/O 的結合使得無論 I/O 包括多少頁,每個順序 I/O 請求只使用單個 pbuf。這種類型的瓶頸一般很難遇到。而對于隨機 I/O,除非運行 syncd 守護程序,I/O 一般會被零星地刷新。
確定是否發生 pbuf 瓶頸的最好方法是檢查稱為 hd_pendqblked 的 LVM 變量。以下的腳本會給出該變量的值:
#!/bin/ksh
# requires root authority to run
# determines number of times LVM had to wait on pbufs since system boot
addr=`echo "knlist hd_pendqblked" | /usr/sbin/crash 2>/dev/null |tail -1| cut -f2 -d:`
value=`echo "od $addr 1 D" | /usr/sbin/crash 2>/dev/null | tail -1| cut -f2 -d:`
echo "Number of waits on LVM pbufs are: $value"
exit 0
ioo -a 命令也會顯示 hd_pendqblked 值。
注:
請不要把 hd_pbuf_cnt 值設得太大,因為除了重新引導系統無法減小該值。
pd_npages 參數
pd_npages 參數指定當刪除文件時 RAM 的某一塊中應該刪除的頁數。改變此值只對那些需要刪除文件的實時應用程序才有用。由于在分派某個進程/線程之前將刪除少量的頁面,因此通過減小 pd_npages 參數的值,實時應用程序可獲得更快的響應時間。缺省值是最大可能文件大小除以頁面大?。壳盀?4096);如果最大可能文件大小為 2 GB,則 pd_npages 參數的值缺省為 524288。
v_pinshm 參數
當 v_pinshm 參數設置為 1 時,如果執行 shmget() 的應用程序指定 SHM_PIN 作為標志的一部分,就會使共享內存段中的頁面由 VMM 固定。缺省值為 0。
應用程序可以選擇提供某種可調優性:指定應用程序是否應該使用 SHM_PIN 標志(例如: Oracle 8.1.5 及以上版本中提供的 lock_sga 參數)。請避免固定過多的內存,因為在這種情況下無法進行頁替換。由于節約了這些共享內存段的異步 I/O 開銷(不需要異步 I/O 內核擴展來固定緩沖區),因此這種固定是很有用的。
fsbufwaitcnt 和 psbufwaitcnt 計數器
只要 bufstruct 變得不可用以及 VMM 將一個線程放入 VMM 等待列表中,fsbufwaitcnt 和 psbufwaitcnt 計數器就會遞增。使用 crash 命令或 ioo -a 命令的 fsbufwaitcnt 和 psbufwaitcnt 選項來檢查這些計數器的值。下面是輸出的示例:
# ioo -a
hd_pendqblked = 305
psbufwaitcnt = 0
fsbufwaitcnt = 337
xpagerbufwaitcnt 計數器
只要增強型 JFS 文件系統上的 bufstruct 不可用,xpagerbufwaitcnt 就會遞增??墒褂?ioo -a 命令檢查 xpagerbufwaitcnt 計數器的值。下面是輸出的示例:
# ioo -a
xpagerbufwaitcnt = 815
直接 I/O 調優
當您在對文件進行正常的 I/O 處理時,I/O 在應用程序緩沖區和 VMM 之間來回進行。在緩沖區中的內容通過 VMM 把實存作為文件緩沖區的高速緩存的使用而高速緩存于 RAM 中。如果文件高速緩存命中率很高,那么這個高速緩存的類型在提高 I/O 的總體性能上將十分有效。但是高速緩存命中率很低的應用程序或者執行大量 I/O 的應用程序也許不會從正常的高速緩存 I/O 使用中得到很多好處。
直接 I/O 的主要益處在于通過消除從 VMM 文件高速緩存到用戶緩存的副本來減少 CPU 對文件讀操作和寫操作的使用率。如果高速緩存命中率低,那么大多數讀取請求不得不轉向磁盤。寫操作在大多數情況下使用正常高速緩存 I/O 要更快。但是如果文件是以 O_SYNC 或 O_DSYNC打開的,那么寫操作將不得不轉向磁盤。在這種情況下,直接 I/O 可能使應用程序獲益,因為數據的副本被消除了。
另一個益處是直接 I/O 可以允許應用程序避免稀釋高速緩存對其他文件的效能。當一個文件被讀取或寫入時,該文件競爭內存空間,有可能引起其他文件數據被推出內存。如果一個應用程序開發者知道某些文件有較低的高速緩存利用率特征,那么只有那些文件可以用 O_DIRECT 打開。
為了讓直接 I/O 有效地工作,I/O 請求適用于正被使用的文件系統的類型。finfo() 和 ffinfo() 子例程可以用來查詢偏移量、長度以及固定塊大小文件系統、碎片文件系統和大文件文件系統有關對地址校正的需求(直接 I/O 沒有支持壓縮文件系統)。查詢到的信息包含于 diocapbuf 結構中,該結構在 /usr/include/sys/finfo.h 文件中描述。
為了避免一致問題,如果有多個調用用來打開文件并且一個或多個調用沒有制定 O_DIRECT 而另一個打開操作指定了 O_DIRECT,那么文件將保留于正常高速緩存 I/O 模式。同樣的,如果文件是通過 shmat() 或 mmap() 系統調用來映射到內存中,它們保留在正常高速緩存模式。如果最后一個沖突,非直接存取被消除,那么文件系統將把文件移入直接 I/O 模式(或者使用 close()、munmap() 或者使用 shmdt() 子例程)。從正常模式到直接 I/O 模式可能代價不小,因為所有在內存中修改過的頁面將不得不在那點上刷新磁盤。
直接 I/O 讀操作的性能
即使使用直接 I/O 可能減少 CPU 的使用,但很有可能產生更長的消逝時間,特別對小型 I/O 請求而言,因為請求不會在內存中高速緩存。
直接 I/O 讀取操作會從磁盤引起同步讀操作,然而通過正常的高速緩存策略,讀取操作可能會從高速緩存那里得到滿意的結果。如果數據在內存中遵循正常高速緩存策略,那么這樣可能導致性能低下。直接 I/O 也忽略 VMM 預讀算法,因為 I/O 并不通過 VMM。預讀算法對順序存取文件非常有用,因為 VMM 可以啟動磁盤請求并且能在應用程序請求頁面之前使頁面早就駐留在內存中。應用程序可以通過一下方法中的一種補償預讀的損失:
執行讀取請求(最小 128 K)
使用多個線程執行異步直接 I/O 預讀取。
使用異步 I/O 設施諸如 aio_read() 或者 lio_listio()
直接 I/O 寫操作的性能
直接 I/O 寫操作繞過 VMM 直接寫入磁盤,以致于可能產生嚴重的性能損失;在正常高速緩存的 I/O 中,寫操作可以寫入內存,稍后通過 sync 或 write behind 操作清空到磁盤上。由于直接 I/O 寫操作并不復制到內存,當一個 sync 操作執行后,它不會必須刷新這些頁面,這樣一來就減少了 syncd 守護程序必須執行的工作量。
直接 I/O 調優摘要
直接 I/O 本質上比常規 I/O 需要更少的 CPU 周期。 I/O 增強性應用程序不會在常規 I/O 所提供的高速緩存中得到益處,但是可以使用直接 I/O 來增強性能。
作為直接 I/O 的適當候選者的程序通常受 CPU 限制并且執行大量的磁盤 I/O。擁有大量順序 I/O 的技術應用程序是適當的候選者。執行許多小型 I/O 的應用程序一般來說受到較少的性能益處,因為直接 I/O 不能預讀或后寫。受益于條帶區的應用程序同樣是不錯的候選者。
原文轉自:http://www.anti-gravitydesign.com