大家好,我是五月。
前言
目前絕大數存儲設備都是以閃存為存儲介質的,內部許多固件算法方案都是在為閃存服務的。
無論是什么算法,都是遵循著Flash的特性為前提的。
那閃存究竟有哪些潛規則的特性呢?

先擦后寫
閃存塊(Block)是不能覆蓋寫的,它不允許開發者在一個地方上重復寫入,必須先擦除一遍才行。
一般來說,當有一筆數據寫入的數據,都是安排寫到新的地址空間上,當你實在不清楚一個地址究竟有沒有有效數據的時候,穩妥的做法一般都是先擦除一遍再寫入。
整page寫入,整Block擦除
閃存允許最小的寫入單位就是page,最少寫入的數據量都得是1個page。
FTL算法中有一個基本操作,會把主機Host傳下來的數據湊成1page,再寫入Flash中,不足1page的,就放在Dbuf中,等待下一次數據來湊成1page,再寫入Flash中。
閃存允許擦除的基本單位是1個Block,只要發生了擦除操作,那么這一整個Block的數據都會被清除掉,所以我們一般不會輕易做整塊擦除。
解決辦法:當有一筆新數據下來的時候,會把數據放在新的物理地址上,這樣做一來是為了不輕易做擦除操作,避免失誤擦除掉了有效數據,二來也避免在同一個物理地址上做重復的擦寫,過快消耗閃存塊壽命。
寫入數據需要隨機化
我們寫的時候,如果簡單把數據寫進去,會遇到很多錯誤,有時候是寫失敗,有時候是讀出來數據不對。
這是由于閃存存儲電子的工作模式導致的,其對數據寫入的樣式特別敏感,如果不斷地寫入全0或者全1,容易導致內部電荷量不足,造成信號抗干擾性下降。
直觀的現象就是你會發現某些數據bit位發生了翻轉。
解決辦法:寫入數據前需要先將數據做隨機化處理,也就是打亂數據,使得0和1的分布均勻。
但是打亂也不是隨便打亂的,它會以某種方式進行隨機化處理寫入flash,讀取數據的時候,會先進行一次反隨機化處理,得到真實數據。
數據寫滿整個Block才會穩定
閃存還有個奇怪的特性,就是數據你必須得寫滿一整個塊,這個塊的數據才會穩定下來。
但是很多時候,我們沒有那么多數據正正好好去寫滿一整個Block。
解決辦法:為了保證寫入數據穩定,我們寫入一筆數據后,會額外寫入幾頁數據,目的就是讓寫入的那筆數據保持穩定,而額外寫入的幾頁數據,稱之為附加邏輯頁數據。
閃存塊都有一定的壽命
每一次寫和擦,都會對閃存塊造成磨損,磨損久了,閃存塊也就壞掉了。其壽命是用PE(擦寫次數)來衡量的。
在使用中,我們盡量避免集中在同一片區域上重復擦寫,不然這片區域的塊很快就磨損沒了。
解決辦法:FTL中需要做一個磨損平衡的處理,讓所有的Block都來均攤數據的寫入。
將數據分擔到其他的Block上,讓每一個Block都磨損的平均些,既可以保證閃存有最大數據寫入量,還能延長閃存的壽命。

每個閃存塊讀次數是有限的
除了有擦寫次數限制,閃存塊還有讀次數的限制,讀取的次數多了,數據便會出錯,這種現象稱之為讀干擾現象。
解決辦法:FTL算法需要做一個讀干擾處理,當某個Block的讀次數達到一定的閾值時,就把數據從該Block上搬移到新的Block上。
數據保持會丟失
閃存能存儲數據的原理就是電荷的存儲,但是電荷是流動不定的,時間一旦久了,電荷就會流失,反映出來的現象就是數據的丟失。
這個時間不好說,長則十多年,短則幾年,幾個月,甚至更短。
如果是在高溫的環境下,電荷流失的速度會更快。
解決辦法:FTL算法需要做一個掃描處理,去發現是否有數據保持丟失的問題,如果發現了,立馬將數據搬移到新的位置,未雨綢繆。
壞塊產生不可避免
閃存出現壞塊這是無法避免的,有的是出廠的時候就有的壞塊,有的是閃存在使用中產生的壞塊。
壞塊的癥狀就是擦除失敗,或者寫失敗,或者讀失敗(ECC糾錯糾不過來)。
解決辦法:FTL算法需要做一個壞塊管理的處理,對壞塊打上壞塊標記,在使用的時候就不要用這些壞塊了,挑好的Block用。
對于MLC或TLC而言,存在下頁損壞問題
對于MLC,一個worlLine存在Upper page和Lower page;
對于TLC,一個worlLine存在Upper page、Extra page和Lower page;
在寫入時,如果發生意外,比如異常掉電這些,Lower page上成功寫入的數據會被破壞掉。
解決辦法:一個辦法是在電路上加上電容,一旦發生異常掉電,讓電容開始放電,在這段時間將數據保存起來,并且開啟正常掉電流程。
還有一個辦法是在FTL算法中需要做一個掉電恢復的處理,通過重建映射表將丟失的數據恢復回來。
一般無論有沒有電容,FTL中都會帶有一個異常掉電處理模塊。
小結
閃存存在這么多的毛病,但是依舊抵擋不住各大存儲領域的企業入局去研究其毛病,畢竟,一切方案,都是以特性未前提的,先明白了特性,才能有解決方案。
好了,這次先寫到這兒,祝各位生活愉快。


浙公網安備 33010602011771號