數(shù)據(jù)庫的IO特點
????IO有四種類型:連續(xù)讀,隨機讀,隨機寫和連續(xù)寫,連續(xù)讀寫的IO size通常比較大(128KB-1MB),主要衡量吞吐量,而隨機讀寫的IO size比較小(小于8KB),主要衡量IOPS和響應(yīng)時間。數(shù)據(jù)庫中的全表掃描是連續(xù)讀IO,索引訪問則是典型的隨機讀IO,日志文件是連續(xù)寫IO,而數(shù)據(jù)文件則是隨機寫IO。
????數(shù)據(jù)庫系統(tǒng)基于傳統(tǒng)磁盤訪問特性來設(shè)計,最大特點是日志文件采用sequential logging,數(shù)據(jù)庫中的日志文件,要求必須在事務(wù)提交時寫入到磁盤,對響應(yīng)時間的要求很高,所以設(shè)計為順序?qū)懭氲姆绞?,可以有效降低磁盤尋道花費的時間,減少延遲時間。日志文件的順序?qū)懭耄m然是物理位置是連續(xù)的,但是并不同于傳統(tǒng)的連續(xù)寫類型,日志文件的IO size很?。ㄍǔP∮?K),每個IO之間是獨立的(磁頭必須抬起來重新尋道,并等待磁盤轉(zhuǎn)動到相應(yīng)的位置),而且間隔很短,數(shù)據(jù)庫通過log buffer(緩存)和group commit的方式(批量提交)來達到提高IO size的大小,并減少IO的次數(shù),從而得到更小的響應(yīng)延遲,所以日志文件的順序?qū)懭肟梢员徽J為是“連續(xù)位置的隨機寫入”,更關(guān)注IOPS,而不是吞吐量。
????數(shù)據(jù)文件采用in place uddate的方式,意思是數(shù)據(jù)文件的修改都是寫入到原來的位置,數(shù)據(jù)文件不同于日志文件,并不會在事務(wù)commit時寫入數(shù)據(jù)文件,只有當數(shù)據(jù)庫發(fā)現(xiàn)dirty buffer過多或者需要做checkpoint動作時,才會刷新這些dirty buffer到相應(yīng)的位置,這是一個異步的過程,通常情況下,數(shù)據(jù)文件的隨機寫入對IO的要求并不是特別高,只要滿足checkpoint和dirty buffer的要求就可以了。
SSD的IO特點
1.隨機讀能力非常好,連續(xù)讀性能一般,但比普通SAS磁盤好。
2.不存在磁盤尋道的延遲時間,隨機寫和連續(xù)寫的響應(yīng)延遲差異不大。
3.erase-before-write特性,造成寫入放大,影響寫入的性能。
4.寫磨損特性,采用wear leveling算法延長壽命,但同時會影響讀的性能。
5.讀和寫的IO響應(yīng)延遲不對等(讀要大大好于寫),而普通磁盤讀和寫的IO響應(yīng)延遲差異很小。
6.連續(xù)寫比隨機寫性能好,比如1M順序?qū)懕?28個8K的隨即寫要好很多,因為隨即寫會帶來大量的擦除。
? ??基于SSD的上述特性,如果將數(shù)據(jù)庫全部放在SSD上,可能會有以下的問題:
1.日志文件sequential logging會反復(fù)擦寫同一位置,雖然有損耗均衡算法,但是長時間寫入依然會導(dǎo)致性能下降。
2.數(shù)據(jù)文件in place update會產(chǎn)生大量的隨機寫入,erase-before-write會產(chǎn)生寫入放大。
3.數(shù)據(jù)庫讀寫混合型應(yīng)用,存在大量的隨機寫入,同時會影響讀的性能,產(chǎn)生大量的IO延遲。
優(yōu)化方案
????基于SSD的優(yōu)化就是解決erase-before-write產(chǎn)生的寫入放大的問題,不同類型的IO分離,減少寫操作帶來的性能影響。
In-page logging
????In-page logging是基于SSD對數(shù)據(jù)庫sequential logging的一種優(yōu)化方法,數(shù)據(jù)庫中的sequential logging對傳統(tǒng)磁盤是非常有利的,可以大大提高響應(yīng)時間,但是對于SSD就是噩夢,因為需要對同一位置反復(fù)擦寫,而wear leveling算法雖然可以平衡負載,但是依然會影響性能,并產(chǎn)生大量的IO延遲。所以In-page logging將日志和數(shù)據(jù)合并,將日志順序?qū)懭敫臑殡S機寫入,基于SSD對隨機寫和連續(xù)寫IO響應(yīng)延遲差異不大的特性,避免對同一位置反復(fù)擦寫,提高整體性能。
? ??In-page logging基本原理:在data buffer中,有一個in-memory log sector的結(jié)構(gòu),類似于log buffer,每個log sector是與data block對應(yīng)的。在data buffer中,data和log并不合并,只是在data block和log sector之間建立了對應(yīng)關(guān)系,可以將某個data block的log分離出來。但是,在SSD底層的flash memory中,數(shù)據(jù)和日志是存放在同一個block(擦除單元),每個block都包含data page和log page。
????當日志信息需要寫入的時候(log buffer空間不足或者事務(wù)提交),日志信息會寫入到flash memory對應(yīng)的block中,也就是說日志信息是分布在很多不同的block中的,而每個block內(nèi)的日志信息是append write,所以不需要擦除的動作。當某個block中的log sector寫滿的時候,這時會發(fā)生一個動作,將整個block中的信息讀出,然后應(yīng)用block中的log sector,就可以得到最新的數(shù)據(jù),然后整個block寫入,這時,block中的log sector是空白的。
????在in-page logging方法中,data buffer中的dirty block是不需要寫入到flash memory中的,就算dirty buffer需要被交換出去,也不需要將它們寫入flash memory中。當需要讀取最新的數(shù)據(jù),只要將block中的數(shù)據(jù)和日志信息合并,就可以得到最新的數(shù)據(jù)。
????In-page logging方法,將日志和數(shù)據(jù)放在同一個擦除單元內(nèi),減少了對flash相同位置的反復(fù)擦寫,而且不需要將dirty block寫入到flash中,大量減少了in-place update的隨機寫入和擦除的動作。雖然在讀取時,需要做一個merge的操作,但是因為數(shù)據(jù)和日志存放在一起,而且SSD的隨機讀取能力很高,in-page logging可以提高整體的性能。
SSD作為寫cache-append write
????SSD可以作為磁盤的寫cache,因為SSD連續(xù)寫比隨機寫性能好,比如:1M順序?qū)懕?28個8K的隨機寫要好很多,我們可以將大量隨機寫合并成為少量順序?qū)懀黾覫O的大小,減少IO(擦除)的次數(shù),提高寫入性能。這個方法與很多NoSQL產(chǎn)品的append write類似,即不改寫數(shù)據(jù),只追加數(shù)據(jù),需要時做合并處理。
????基本原理:當dirty block需要寫入到數(shù)據(jù)文件時,并不直接更新原來的數(shù)據(jù)文件,而是首先進行IO合并,將很多個8K的dirty block合并為一個512KB的寫入單元,并采用append write的方式寫入到一個cache file中(保存在SSD上),避免了擦除的動作,提高了寫入性能。cache file中的數(shù)據(jù)采用循環(huán)的方式順序?qū)懭?,當cache file空間不足夠時,后臺進程會將cache file中的數(shù)據(jù)寫入到真正的數(shù)據(jù)文件中(保存在磁盤上),這時進行第二次IO合并,將cache file內(nèi)的數(shù)據(jù)進行合并,整合成為少量的順序?qū)懭?,對于磁盤來說,最終的IO是1M的順序?qū)懭?,順序?qū)懭胫粫绊懲掏铝?,而磁盤的吞吐量不會成為瓶頸,將IOPS的瓶頸轉(zhuǎn)化為吞吐量的瓶頸,從而提升了整體系統(tǒng)能力。
????讀取數(shù)據(jù)時,必須首先讀取cache file,而cache file中的數(shù)據(jù)是無序存放的,為了快速檢索cache file中的數(shù)據(jù),一般會在內(nèi)存中為cache file建立一個索引,讀取數(shù)據(jù)時會先查詢這個索引,如果命中查詢cache file,如果沒有命中,再讀取data file(普通磁盤),所以,這種方法實際不僅僅是寫cache,同時也起到了讀cache的作用。
????但是這種方法并不適合日志文件的寫cache,雖然日志文件也是append write,但是因為日志文件的IO size比較小,而且必須同步寫入,無法做合并處理,所以性能提升有限。
SSD作為讀cache-flashcache
????因為大部分數(shù)據(jù)庫都是讀多寫少的類型,所以SSD作為數(shù)據(jù)庫flashcache是優(yōu)化方案中最簡單的一種,它可以充分利用SSD讀性能的優(yōu)勢,又避免了SSD寫入的性能問題。實現(xiàn)的方法有很多種,可以在讀取數(shù)據(jù)時,將數(shù)據(jù)同時寫入SSD,也可以在數(shù)據(jù)被刷出buffer時,寫入到SSD。讀取數(shù)據(jù)時,首先在buffer中查詢,然后在flashcache中查詢,最后讀取datafile。
????SSD作為flashcache與memcache作為數(shù)據(jù)庫外部cache的最大區(qū)別在于,SSD掉電后數(shù)據(jù)是不丟失的,這也引起了另外一個思考,當數(shù)據(jù)庫發(fā)生故障重啟后,flashcache中的數(shù)據(jù)是有效還是無效?如果是有效的,那么就必須時刻保證flashcache中數(shù)據(jù)的一致性,如果是無效的,那么flashcache同樣面臨一個預(yù)熱的問題(這與memcache掉電后的問題一樣)。目前,據(jù)我所知,基本上都認為是無效的,因為要保持flashcache中數(shù)據(jù)的一致性,非常困難。
????flashcache作為內(nèi)存和磁盤之間的二級cache,除了性能的提升以外,從成本的角度看,SSD的價格介于memory和disk之間,作為兩者之間的一層cache,可以在性能和價格之間找到平衡。