讀書筆記 Improving Database Performance With AIX Concurrent I/O

anycall2010發表於2008-06-25

AIX 5.2.0.10 (maintenance level 01 announced May 27, 2003.)JFS2裡引入了一個新功能Concurrent I/O (CIO),這個新功能可以改善許多環境,特別是商業用途資料庫系統。在許多情況下,資料庫在使用了CIO以後可以達到和使用Raw LV媲美的效能。

       長久以來,檔案系統就是UNIX系統儲存管理的核心。操作和管理儲存在檔案中的資料的命令和介面被UNIX世界中的各個階層的使用者熟知和使用。對與應用的輕便性而言,通過者中淺而易懂的機制來管理持久型資料更是十分關鍵。

       和其他所有抽取資料的方法一樣,檔案系統在效能和使用方便之間做了一個折衷。在物理儲存(比如disk)和應用之前傳輸資料最塊的方法就是直接訪問更加原始的介面(或者說媒介)比如Raw LV。使用檔案儲存資料的方式會導致花費一些額外的開銷在序列訪問,緩衝和資料拷貝上,而這些都會影響效能。使用Raw LV就不會出現這些開銷,但它又需要具有教高的技能水平才能實施並且要對使用它的人做培訓,因為資料的管理越來越應用化。而且,操作Raw LV是需要系統許可權的,但檔案系統就不需要。總而言之,由於Raw LV卓越的效能表現,資料庫型別的應用都情願使用Raw LV而不是檔案系統。

       隨著JFS2Concurrent I/O的引入,資料庫應用在檔案系統上的效能也能和在Raw LV上的效能一較高下。

        

2 採用檔案系統的資料庫應用

         對於資料庫應用而言,Raw LV比檔案系統有優勢是因為檔案系統的下列3個特徵:

       The file buffer cache(檔案緩衝)

       The per-file write lock, or inode lock(檔案級別的inode鎖)

       The sync daemon (後臺同步)

這些特徵是為了使檔案系統能保證資料一致性和提供容錯,在很多情況下還能改善應用的效能(這裡應該是指File buffer cache後面會提到)。但是這些特徵經常導致資料庫應用的效能產生瓶頸,下面就來逐一介紹。

 

2.1  File buffer cache

       從最基本的層面上來講,檔案不過是儲存在物理媒介上的一些bit的集合。當一個程式希望訪問檔案中的資料時,作業系統把資料引入到主要記憶體中(這裡應該是指實體記憶體),然後程式就可以檢查資料,修改資料進而發出請求要求把資料寫回磁碟。對每個請求而言,作業系統可以直接對磁碟進行讀寫資料操作,但是響應的時間和吞吐量卻受到磁碟本身的限制。為了儘可能少的訪問磁碟,作業系統採用了將資料緩衝在記憶體中的方法,這一記憶體中緩衝結構(或叫緩衝區?)叫做File buffer cache.當收到一個讀檔案的請求時,檔案系統先在File buffer cache中尋找.如果沒找到,檔案系統才從磁碟去讀,並把讀到的資料放在File buffer cache中.

       同樣,寫檔案也會被快取起來為了使接下來的讀操作可以不用訪問磁碟,從而降低了磁碟寫操作的頻率.如果緩衝區的命中率很高的話,File buffer cache是非常有效的.它同樣使提前讀和延後寫成為可能,同樣可以降低磁碟的I/O頻率.

       File buffer cache的另一個優點是可以使寫檔案變成非同步,因為應用可以在發出寫操作之後繼續執行其他操作而不必等待寫磁碟操作完成.

       儘管File buffer cache改善了I/O效能,但同時消耗了大量的記憶體.AIXJFS2可以通過引數控制File buffer cache在記憶體中的使用比例-maxclient%,這個引數可以通過vmo來調整,範圍是1-100,預設是80,就是說記憶體的80%可以用做File buffer cache

調整命令:vmo – o maxclient%=50

      

       相對於檔案系統,Raw LV並沒有採用系統級別的快取來處理應用的資料,所有就不存在duplication nor double-copying的問題

       (實際上Oracle記憶體管理的很多概念和作業系統是大同小異的,Oracle是把作業系統中一些成功的概念借鑑了過來)

 

2.1.1  Direct I/O 

       對於一些應用而言,他們從File buffer cache中得不到一點好處,因為他們訪問資料的方式決定了不可能重用File buffer cache中的資料,導致緩衝區的命中率十分低下.資料庫就是個例子,他們在應用層的級別上緩衝了資料,所以不再需要檔案系統再提供這個功能.事實上在這種情況下,採用了File buffer cache以後會導致不可預料的開銷,因為資料先從磁碟移到File buffer cache然後再從File buffer cache移到應用自己的buffer.這種double-copying資料會導致額外的CPU消耗和記憶體的消耗,使應用可用的記憶體減小,從而進一步導致系統在管理記憶體方面的消耗.(估計是指page in page out

       對於這種希望繞開這個功能的應用,JFS2提供了一個選項-Direct I/O,如果檔案採用了Direct I/O,資料可以直接從磁碟傳到應用自己的Buffer而不必再經過File buffer cache.(2道販?)

 

2.1.1.1  Direct I/O的使用

       有2種方法可以使用Direct I/O

1 mount檔案系統的時候指定 mount –o dio

2 在用系統呼叫函式open()開啟檔案的時候以O_DIRECT作為OFlag引數

對與第一種方法,如果一個檔案系統用了mount –o dio選項,那麼檔案系統下的所有檔案都會以Direct I/O的方式訪問,或者也可以指定在檔案級別使用Direct I/O選項,比如:

mount –v namefs –o dio /somefs/subsomefs /somefs.

這個命令就可以將/somefs/subsomefs資料夾下的所有檔案以Direct I/O的方式掛到/somefs下,並換了名字叫 namefs

Direct I/O對應用的I/O的頻寬和長度有最小限制(不知道此處譯的對不對),滿足不了這個限制的I/O將會以傳統的Cache I/O的方式讀寫,但是在資料傳輸到應用的buffer以後,這些資料將會從File buffer cache丟掉.檔案系統的提前讀的特性也不會在Direct I/O中發生.

 

下表就是Direct I/OI/O的限制

       為了避免一致性的問題,比如一些程式希望通過Cache I/O的方式訪問一個檔案,而同時其他的一些程式希望通過Direct I/O方式訪問,這時候檔案還是會以Cache I/O的方式被訪問,

同樣的如果檔案是通過系統呼叫函式shmat()mmap()影射到記憶體中,也是以Cache I/O的方式,一旦最後一次非Direct I/O方式訪問結束(比如用系統呼叫函式close(), munmap(), shmdt()),檔案會被轉為Direct I/O模式,這個轉化的代價是相當高的,因為在轉換的那一刻,所有以Cache I/O模式下修改的此檔案的資料會被刷回磁碟.

 

 

2.1.1.2           Direct I/O的效能

       由於Direct I/O減少了CPU的消耗而且沒有copy資料2次的額外開銷,應用可以從中得到不少好處.但是還有些因素會影響Direct I/O的效能.

       每個Direct I/O的讀都會引起一次磁碟的同步讀.不象普通的Cache I/O有些讀是可以直接在Cache中完成的.這就會導致那些在普通的Cache I/O中願意待在記憶體中的資料(或者說經常可以通過File buffer cache得到的資料)採用Cache I/O時就會降低效能.

       而且Direct I/O繞過了JFS2的提前讀(read-ahead).檔案系統的read-ahead對連續訪問檔案的操作有極大的效能提升.作業系統通過觀察程式訪問檔案的方式來預先讀取將來可能會訪問到的檔案中的連續資料到Cache中.如果一個程式連續2次成功得到了一個檔案的page(4096 bytes),作業系統就假定這個程式會繼續讀剩下的部分,就預先把這些內容讀到Cache中來,以在程式需要讀他們的時候可以直接在Cache中找到,而不是等程式發出指令給系統之後再進行I/O.預先讀取的page受到下面2個引數的控制:

1.j2_minPageReadAhead  預設是2

當作業系統第一次探測到程式在連續訪問一個檔案時,作業系統將讀取j2_minPageReadAheadpage(2page)Cache中,如果程式繼續訪問,下一次預讀入Cachepage數就是2*j2_minPageReadAhead(4page),再下次就是4*j2_minPageReadAheadpage(8page),

依次遞增.

2           j2_maxPageReadAhead 預設是8

當系統預讀入Cachepage數達到j2_maxPageReadAhead後就不再增長,持續以這個數讀入page.

這2個引數可以通過ioo調整.

 

下面這個表對Cache I/ODirect I/O分別做了效能測試做出比較

       Block size 4k

j2_minPageReadAhead 預設為2

j2_maxPageReadAhead 預設為8

 

 

解釋:

       1 第一行表示程式每次以1byte的量訪問一個大小為1M的檔案,

對於Cache I/O來說,可以從read-ahead受益,因為系統預讀入Cache比程式每次需

讀取的資料量大,因而基本上所有的資料都在Cache能找到(系統預讀入了).

Direct I/O就沒這麼幸運了,由於沒有滿足Direct I/OI/O的限制(上一節講到的),

檔案讀入程式Buffer時仍然採用傳統的Cache I/O,而且最要命的是,在從Cache讀到程式buffer以後,Cache中的資料會被丟掉,這就導致了下一個byte的訪問要重新從disk讀取一個pageCache,但實際上這個page剛剛從Cache中丟掉.這也就是第一行Direct I/O為何一共讀取了4194320=4096*(1M/1byte)的原因.

       2     第二行表示程式每次以4K的量訪問一個大小問1G的檔案

對於Cache I/O,依然可以從read-ahead受益.

       對於Direct I/O,雖然I/O已經滿足了限制,但是由於read-ahead的出色表現, Direct I/O還是在效能上差於Cache I/O很多.

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/8334342/viewspace-364765/,如需轉載,請註明出處,否則將追究法律責任。

相關文章