照章節目錄,本週的主題是SSD。在外面,介紹SSD的文章很是之多,在個人文章裏面就不重複其餘地方介紹過的知識了。趕在睡覺時間以前發出來,但願你們可以輕輕鬆鬆瞭解點知識,而後閤眼睡覺~算法
在本篇文章中,我想着重的分析如下幾個問題:後端
1.在不一樣廠商的實現中,SSD的讀寫iops爲何會有如此之大的差距?緩存
2.SSD的優點在於沒有尋道時間了,爲何4K隨機寫還會是個性能大瓶頸?ide
3.FLASH控制器,看來成敗就看他了!把他扔在那裏最合適呢?性能
在不一樣廠商的實現中,SSD的讀寫iops爲何會有如此之大的差距?測試
第一個問題是我第一次接觸SSD的時候就一直不大理解的問題,由於廠內也作了ssd相關的嘗試,所以也接觸了幾類廠商的ssd成品。在整個測試中,性能指標的差距很是之大,讓我印象很是深入,所以也一直有一個疑問,爲何在不一樣的ssd存儲產品中的性能差距會這麼大呢?這個問題我也問過不少人,也看過很多資料。在下面,我來嘗試回答一下這個問題:優化
首先須要先介紹一些固態磁盤的基礎知識,目前主流的ssd,使用的存儲顆粒是NANDFLASH,他主要由以下幾個關鍵的組件組成:線程
1.協議轉換層(可選),主要是把ata/sata/scsi/ide這樣的磁盤讀寫協議轉換爲針對NANDFLASH的讀寫訪問請求。這個開銷可控,不是咱們今天要介紹的內容。設計
2.FLASH芯片控制層,是整個ssd最重要的部分,也是本章的主角兒~,直接決定了ssd的一切。有一些實現中,須要SDRAM來作緩存支持,並有本身獨立的CPU。對象
3.NANDFLASH芯片,存數據的地方
首先來看看NANDFLASH芯片
NANDFLASH芯片主要由Single-levelcell(SLC)/(Multi-levelcell)MLC兩種。
從名字看來,彷佛MLC比SLC要高級,其實不是--,簡單來講,SLC就是一個單元只存一個電位,所以SLC一個單元能夠表示一個bit,而MLC則會存儲兩個甚至三個電位,所以MLC一個單元能夠表示2或者3個bit。表示的bit越多,存儲相同數據所消耗的存儲單元就越少,所以價格就越便宜,不過由於單元自己寫入有次數限制,而一個單元表示3個bit,也就意味着其中只要變化一位的數字,單元就必須進行一次擦寫,所以MLC的壽命會低不少。
MLC和SLC在控制層中的優化方式可能有很大的不一樣,不過爲了簡化,咱們以SLC做爲後續談論的主要對象,來看看SLC的一些具體的技術特性。
對於用戶來講,閃存要求用戶一次讀取4Kb的數據,用時4微秒。而向其寫入4Kb的數據,用時爲250微秒。通常的,咱們將4Kb的數據稱爲一頁(page)
對閃存來講,刪除是個特殊的操做,須要作一下詳細的解說,由於幾乎閃存中大部分的複雜性都來源於NAND刪除操做的特殊特性:
對於NAND來講,刪除是個很是耗時的操做,所以,爲了取得最高的時效,NAND要求一次刪除的最小單元是256KB,也就是64個Page要一塊兒刪除掉,爲了描述方便,咱們把64個page合併到一塊兒,稱做一個塊(block)。這樣能夠取得最好的刪除效能。耗時約2000微秒。NAND自己沒有「更新」這個概念,對於它來講,一次更新等於一次刪除加一次插入。後面咱們在分析flash控制器的時候會使用到這些特徵,請多看幾回:)
瞭解了NANDFLASH芯片的特性以後,就請隨我一塊兒進入FLASH控制器的領域,來嘗試回答一下:在不一樣廠商的實現中,SSD的讀寫iops爲何會有如此之大的差距?這個問題吧~
讓咱們來看看FLASH控制器主要在承擔的職責有哪些:
1.協調多塊NAND芯片,使用並行技術,提高整塊磁盤的讀寫吞吐量和IOPS
在上面,咱們已經知道一塊NAND可以實現的寫入和讀取性能實際上是有限的,而若是可以將多塊NAND合理的組織到一塊兒,使用PARTITION技術進行數據寫入的切分(好比按照key取模,或者使用映射表)和並行執行,就能夠充分的利用多塊NAND,達到提高讀寫吞吐量和IOPS的做用了。
2.處理寫入放大問題
NAND芯片要求一次必須刪除64個頁。而這些頁內頗有可能出現一些尚未被標記要刪除的數據,這時候若是咱們要往這些空間中寫入數據,就須要將這64個頁一塊兒讀出到緩存中,而後調用NAND的接口刪除這個塊(block)。很明顯的,這裏會有一些額外的謄寫操做,這就形成了沒必要要的的浪費,爲了衡量這個浪費的嚴重程度,因而就有了一個指標叫:寫入放大倍數,寫入放大倍數=閃存中實際寫入的數據量/用戶請求寫入的數據量
而這裏,最理想的狀態下,應該是全部頁內的數據都是已經被標記爲刪除的數據,那麼這樣就不須要進行謄寫了,這時候寫入放大的倍數是1。也就是沒有寫入放大。
3.磨損平衡WearLeveling(WL)
NAND芯片自己都有寫入壽命限制,爲了保證讓全部芯片均衡磨損,須要將全部寫入和擦除均衡的分配到全部的block中。這就須要記錄下每一個塊的擦寫次數,並儘量平衡全部塊的擦寫次數。
由於FLASH存儲產生的時間比較短,從上世紀80年代至今也才三十幾年,直到最近幾年纔有爆發式的增加,因此在控制器上面的積累遠遠沒有成熟。差一些的控制器,受到成本和技術的限制,在並行寫入程度以及處理寫入放大問題上不大成熟,以致於在一些很便宜的芯片上,寫入放大比率甚至高達4以上,徹底沒法發揮出SSD的性能優點。
同時,從成本上考慮,在一些實現中可能會採起更少的RAM,更便宜的處理器來下降成本,RAM變少,會讓SSD在進行寫入以及垃圾回收中受到更大的系統資源限制,從而可能沒法作出最優的寫入策略。
以上這些也就解釋了目前各類ssd在性能上差距如此明顯的緣由所在了,由於整個產業尚未徹底成熟,各家的還在嘗試尋找最好的軟件算法和硬件搭配來讓NAND可以更符合咱們的實際使用場景須要,所以就致使了性能上的巨大差距。
「在一些SSD產品中的隨機寫入性能比磁盤還要低」第一次看到這樣的介紹的時候,相信有不少人也會馬上眉頭緊鎖,這不是很奇怪麼?在傳統磁盤結構中,致使隨機寫性能降低的元兇是隨機尋道,而在ssd中明明已經沒有了磁頭和隨機尋道這些致使隨機寫性能降低的元兇,爲何隨機寫仍是個這麼嚴重的問題呢?
下面咱們就來深刻的進行一下分析:
若是用一個成語來形容ssd的隨機寫性能下降的話,那就是狼前虎後,通過了這麼多年的努力才解決了磁頭的隨機尋道代價很高的問題,但還沒來得及高興幾天,發現新的存儲也存在着影響隨機寫的硬件限制。
這限制就是寫入放大,而引發寫入放大的元兇就是ssd的數據擦除成本很是高昂(請瀏覽前面NAND芯片介紹部分)
對於數據的操做,綜合來看應該有如下這麼幾類:
4k插入:直接找個新的空頁進行寫入便可
4k刪除:標記某個頁已經被刪除,由於真正的刪除操做代價很高,因此最理想的狀態下,應該是儘量將塊刪除操做延後,這樣一個塊內就會有更多的數據頁有可能被標記爲刪除。當一個塊中有足夠多的頁被標記爲刪除後。就能夠進行真正的塊刪除操做了。
4k更新:NANDFLASH不支持原位更新,所以全部的更新都被處理爲一次4k刪除和一次4k插入。
塊刪除:(重要!)由於在實際的場景中,一塊內的64個頁中可能還有一些數據並未被標記爲刪除,爲了保證這些未被標記爲刪除的數據不會丟失,須要要先把整個塊都讀取出來,而後將塊內還沒被刪除的數據謄寫到新的空塊後,調用NAND的塊刪除命令來清除整塊操做。天然的,若是謄寫的數據越多,意味着用戶的一次寫入操做對應了屢次系統寫入操做和塊刪除操做。
一旦塊的回收速度趕不上用戶進行插入/刪除請求的速度,那麼整個ssd磁盤的延遲就由單塊寫的延遲250微秒,變爲刪除加寫入的延遲2250微秒。
這個延遲的上升就致使iops的陡降,並且降低後若是不給ssd恢復和整理的時間,那麼整個ssd盤的性能就受限於刪除延遲,從而出現了隨機寫入的瓶頸。
而若是應用是簡單的順序寫和順序刪除,則全部數據只須要以塊爲單元進行刪除和寫入就好了,不存在寫入放大問題,所以iops瓶頸在寫入延遲,因而就不會出現特別誇張的性能陡降的狀況了。
彷佛看起來問題還不大複雜,好比若是我設計一種策略,讓一個後臺進程儘量快的按期將被刪除的數據比率很高的塊進行回收就能夠解決問題了不是麼?若是隻是如此簡單那就太好了。。惋惜實際的生活遠遠不會天隨人願。。
SSD是有壽命限制的,所以若是回收進行的過於頻繁,雖然對寫入性能有極大幫助,但可能會致使ssd的壽命更快的耗盡。
所以,必須找到一個比較好的算法,可以平衡用戶對ssd的實際性能需求,塊的回收,以及磁盤的擦寫壽命。
這也就是各家Flash控制器性能如此不一樣的主要緣由之一了~
由於這裏涉及到各家的核心技術,我是確定不可能有太深刻的瞭解的,不過經過合理的知識遷移和猜想,應該!可能!可以大概的描述處理這個問題的一些核心思路。
首先,隨機寫問題比較好的解決方案就是把全部的隨機寫變成順序寫,針對這個場景,在90年代以後已經有比較成熟的一套理論體系來解決這類問題了,它就是Log-structuredMergeTree,咱們在後面的章節會詳細的介紹這套體系的理論基礎,在這裏只是作個入門。
這套體系的核心思路就是,你的全部更新和刪除操做,都會被轉換爲一個log並被追加到文件尾部,這樣就能夠將全部的原位更新都轉換爲順序寫入,代價則是更多的讀取次數,不過由於NAND的讀取不是瓶頸,因此代價是能夠接受的。
同時,後端有一組線程,從文件頭開始順序的讀取全部的塊,將塊中未被標記爲刪除的數據找出來,湊夠64個頁後寫到新的塊中,而後調用塊刪除命令,清除那些已經完成謄寫的數據塊。
其他的問題就是考慮ssd的磨損平衡問題,儘量將謄寫的那些數據放到擦除次數比較少的那些塊內。
最後是經過各類實際的測試,找到一個最佳的均衡點,可以兼顧到性能,響應時間和NAND壽命。估計這個配置模型的價值應該能超越等值的黃金XDDDDDD.
控制器要作的事情所須要的計算資源其實遠遠超出咱們的想象,舉個最簡單的例子,一個頁4k大小,那麼對於120G的SSD來講,單單只是存儲每一個頁是否有數據這件事,就須要30’000’000個標記位,完成其餘功能也須要不少計算資源和存儲資源。
一個好的控制器既然如此影響性能,放在什麼地方,由誰來負責進行計算和存儲就天然而然的成爲了一個很重要的問題。
在大部分的實現裏面,控制器是一個專門的芯片,封裝了本身的算法和存儲芯片。
不過在最近,有一些公司走出了不一樣的道路,嘗試使用用戶的CPU來進行計算和數據存儲。
這兩種方式各有優劣。
若是你使用了專門的控制器,那麼好處是不會佔用寶貴的中央處理器資源。而壞處則主要是升級有必定難度,而且計算資源會受到板載硬件的限制。
而若是你與用戶共享中央處理器,那麼好處是升級容易,用戶甚至能夠直接經過修改廠商提供的硬件驅動的方式增長更符合本身實際業務場景的寫入策略,但壞處是會佔用中央處理器資源。
目前來看,兩種方式各有優點,後續也會相互借鑑進而更加完善,目前尚未哪一方可以徹底佔據市場,在可見的將來應該也不會。
很容易能夠看到,NAND芯片會隨着產能的提高而進一步下降價格,而且Flash控制器的也會隨着時間和用戶數的增加而更加完善。目前在intel比較新的控制芯片中,寫入放大倍數甚至已經可以在某些場景下達到1.1左右了,幾乎不是太大的問題了,隨着這些問題的解決,隨機寫性能將有進一步的提高空間,而成本將進一步下降。
能夠預見,在將來,對於追求iops的數據讀寫類應用來講,將用戶常常訪問的熱點數據所有從傳統磁盤搬到ssd上面應該是個趨勢。自此,磁盤將是新的磁帶,閃存是新的磁盤,內存爲王。