轉(zhuǎn)帖|其它|編輯:郝浩|2011-03-14 11:05:28.000|閱讀 589 次
概述:本文主要講述NoSQL在Flash設(shè)備上的可以選擇的其中一種優(yōu)化策略,并粗略提了一下SSD設(shè)備的特性。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
對Flash設(shè)備的性能優(yōu)化,微軟曾經(jīng)做過一份paper,但是里面很多東西比較局限:比如paper中將SSD作為了寫入的buffer,而眾所 周知,寫性能不會是任何一款NoSQL的瓶頸;比如SSD的索引采用了Hash的數(shù)據(jù)結(jié)構(gòu),這樣在進(jìn)行cache evict的時候,粒度的控制也很有問題。本文對其進(jìn)行了改進(jìn),羅列如下:
Features of SSD
SSD對于傳統(tǒng)硬盤的優(yōu)勢在于它沒有機(jī)械裝置,介質(zhì)也由磁介質(zhì)變?yōu)榱穗娊橘|(zhì),因此它具備直接按地址讀取數(shù)據(jù)的能力,沒有了尋道時間,這也是為什么SSD的IOPS可以達(dá)到數(shù)萬的原因。
而SSD的寫操作比較特殊,其最小寫入單元是4K,當(dāng)寫入空白位置的時候可以直接寫入,但是當(dāng)需要改寫某個單元時,則需要一個額外的擦出操作,擦除的操作一般是128個page,每個擦出的單元稱為一個塊。
Wear Leveling
因?yàn)镾SD的存儲單元壽命有限,因此,當(dāng)某個特定的部位被頻繁擦寫,不僅會造成性能問題,而且使得SSD壽命大幅降低,所以SSD做了Wear Leveling,即損耗均衡算法。這樣,當(dāng)需要改寫某個page時,并不寫入原有位置,而是讀取現(xiàn)有塊,合并需要改寫的數(shù)據(jù),然后一起寫入新的空閑塊, 原有的塊被標(biāo)記為invalid,等待被擦除回收。這樣做的好處在于,一是不會反復(fù)擦寫同一個block,二是寫入的速度會比較快(省略了擦除的動作)。
Write amplification
因?yàn)镾SD的erase-before-write的特性,所以就出現(xiàn)了一個寫入放大的概念,比如你想改寫4K的數(shù)據(jù),必須首先將整個擦除塊 (512KB)中的數(shù)據(jù)讀出到緩存中,改寫后,將整個塊一起寫入,這時你實(shí)際寫入了512KB的數(shù)據(jù),寫入放大系數(shù)是128。寫入放大最好的情況是1,就 是不存在放大的情況。
Conclustion
綜合SSD的特性,我們需要做到以下兩點(diǎn)來合理使用SSD并且提高其使用壽命:
1. 盡量避免隨機(jī)寫。由于損害均衡算法的存在,隨機(jī)寫特定page將造成寫入放大。
2. 避免每次寫入過少的數(shù)據(jù)。如果每次寫入的數(shù)據(jù)不足SSD的一個page大,那么當(dāng)前寫入的數(shù)據(jù)將導(dǎo)致該page有浪費(fèi),并且接下來對該文件邏輯上的append將導(dǎo)致,之前寫的不足一個page的數(shù)據(jù)被讀取出來,并合并到新的page中去。
3. 不要使用完全部的空間。SSD的損耗均衡算法雖然一定程度上減少了對特定部位的頻繁擦寫,但是如果空間不夠,這個還是很難避免,因此,最好預(yù)留至少50%的空間。
可以看到,不得不說,絕大部分的NoSQL產(chǎn)品都做到了上述兩個特性。因此,在新型存儲設(shè)備上的嘗試將是NoSQL時代的主題。
SSD as Level2 Cache
雖然當(dāng)前SSD相比內(nèi)存便宜了很多,但目前SSD每存儲單元在價(jià)格上仍然比普通硬盤要貴很多,因此,在這個過渡時期,普遍的想法是把SSD當(dāng)做二級 Cache。像Flashcache這樣利用Linux Device Mapper,將SSD等設(shè)備當(dāng)做Write Back block cache。關(guān)于其詳細(xì)介紹,這里就不多說了,可以去//github.com/facebook/flashcache 看看官方的介紹。這里講述另外一種可能比較簡單易實(shí)現(xiàn)的方式。
根據(jù)上面描述的SSD的性能特點(diǎn),可以采用下面的設(shè)計(jì):
上圖是邏輯上的結(jié)構(gòu),物理的實(shí)現(xiàn)已經(jīng)把很多東西都合并了,比如讀cache和寫buffer,以及SSD的索引B-tree,都可以進(jìn)行合并成為一 顆B-tree(Berkeley Db的方式),另外,我需要強(qiáng)調(diào)的一點(diǎn)是,這里的SSD索引使用了B-Tree,相比于Hash是為了提供更粗粒度的SSD Cache失效機(jī)制,這一點(diǎn)的原因在上面的SSD特性中已經(jīng)講過了,下面講述get以及set操作的流程。
Get
首先,邏輯上先查詢內(nèi)存中的Read Cache,如果不存在,則查詢Write Buffer,然后是SSD Cache的B-Tree Index,然后是Bloom Filter確認(rèn)key的確在硬盤存在,最后查詢到硬盤。
Set
插入的時候,先寫到write buffer里面,當(dāng)buffer到達(dá)一個臨界值的時候?qū)⑵渌⒌絊SD上,當(dāng)SSD到達(dá)一個臨界值的時候,將其踢出并移到硬盤,當(dāng)然整個過程Bloom Filter也要保持一致。
Delete
刪除操作首先檢查內(nèi)存中的各buffer和cache有沒有該值,如果有,直接在內(nèi)存中刪除其父節(jié)點(diǎn)對它的引用,隨后直接返回;如果沒有,那么先查看Bloom Filter是否該key存在,如果存在則去硬盤上刪掉。
這里需要強(qiáng)調(diào)的是,刪除操作只是一個標(biāo)記刪除,物理文件上的刪除會有后臺線程定時掃描,這樣能夠保證每次SSD的擦除操作能更加有效。
Evict strategy
既然SSD做為了二級Cache,那么其必然存在一個evict操作,evict操作的憑據(jù)是每個節(jié)點(diǎn)的 generation,generation會在每次節(jié)點(diǎn)被訪問的時候+1,這里的+1是一個全局的+1,即整顆樹維護(hù)一個long型的 generation,A節(jié)點(diǎn)被訪問一次則其generation為1,那么過一會B節(jié)點(diǎn)被訪問那么generation為2,以此類推。
Evict的時候?qū)⑤^小的generation的節(jié)點(diǎn)刪除,將其踢到硬盤,這里需要注意,這里的節(jié)點(diǎn)我指的是非頁節(jié)點(diǎn),因此,一般情況下,每次 evict至少有默認(rèn)128個葉節(jié)點(diǎn)被踢出,即使這128個節(jié)點(diǎn)物理上的位置不連續(xù),由于我們有后臺的clean線程(參加海量數(shù)據(jù)存儲之Key- value存儲簡介的過期數(shù)據(jù)清理一章)的參與,因此,我們總能保證,每次SSD的擦除操作都是連續(xù)并且是大塊的。
最后,很顯然,這樣的設(shè)計(jì)L1 Cache、L2 Cache以及Disk組成了一套完整的數(shù)據(jù),因此,在掉電的時候,SSD的cache無需失效,當(dāng)然,前提是由于我們的系統(tǒng)有Write-ahead-log保證了內(nèi)存中的數(shù)據(jù)掉電不丟失。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:網(wǎng)絡(luò)轉(zhuǎn)載