你以为你的SSD硬盘正在待机,实际上它快忙坏了

Background IO,从字面理解即后台IO任务,它和前台IO是相对应的关系。前台IO,就是通常我们所理解的CPU访问SSD盘内数据、写数据到 SSD 闪存颗粒等工作。

Background IO是什么?

但因为,SSD使用了相对HDD来说更加脆弱和敏感的NAND闪存颗粒,所以导致了SSD主控芯片不仅要处理数据的读写,还需要做一些额外的后台工作来保障SSD的正常工作。

一般来说,一款标准的企业级SSD,它所需要做的Background IO主要有以下几种:

  1. PLP电容自检
  2. BootLoader存放区域扫描
  3. 系统区域扫描(固件、坏块表存放区)
  4. 用户数据区域后台扫描
  5. 温度传感器采样
  6. Log日志定时写入NAND
  7. Read disturb数据搬移
  8. 后台GC垃圾回收
  9. 磨损均衡

平时没怎么总结还没发现,原来SSD固件在后台需要处理的任务这么多了,而且还有一些这里没有列出来的。

为什么需要Background IO?

PLP电容自检

正常情况下,拆开一块企业级SSD,基本都可以看到下图中这一块黑色的上面写着1000uF的电容,当然也可以是很多个并联的小电容组成。

Enterprise SSD Background IO

这块电容在SSD中充当着不可或缺的角色,因为企业级对异常掉电后的数据恢复是刚需,因此需要这块电容存储电荷,在掉电时再继续让SSD工作一段时间,将仍留在DRAM中的重要数据及时写到NAND颗粒中,保证了异常掉电下的数据安全。

但是,只要是铝电解电容都会有一些缺点,那就是高温敏感、寿命短、漏电流大。因为铝电解电容内部基本是液态的电解质,当温度过高时,内部电解质会被加热导致挥发甚至是爆浆(有兴趣的读者,可以网上搜索“铝电解电容爆炸的各种姿势,还是挺有意思的”)。而且,如果长期在高温下使用,可能会造成电解质挥发至干涸,最终电容变成一具“干尸”。

当然,做SSD设计时就已经考虑到了铝电解电容的这些特征,因此做了冗余设计,保证电容能够持续工作5年以上。但,基于铝电解电容的这些特性,还是需要定时去检查一下有没有问题,防止电容失效而引起数据丢失灾难。一般每隔24小时检查一次,当然你也可以设置更长或更短时间间隔。

这就像,我们日常开的车,刹车片虽然不用每次保养都去更换,但每次保养都要去检查一下磨损程度。同样的道理。

BootLoader存放区域扫描

Bootloader的用途,做产品研发的同学应该是清楚的。它是一段非常精简的代码,用来引导整个固件或者系统代码的启动。

因此,它真的非常重要!

所以,BootLoader代码一般都不会存放在NAND颗粒中,而是在一颗很小的SPI Flash中,这个SPI Flash的可靠性要远高于NAND闪存颗粒。

但,即使这样,对于BootLoader存放区域的介质健康检查不可省略,谁叫它这么重要呢?至于扫描的时间间隔,每家公司设计不同,可自行决定。

就像,你在家里的密码箱存放了100斤黄金,就算它足够安全不会被偷,你也还是想每天晚上睡觉前打开柜子看看确保安全呢。

系统区域扫描(固件、坏块表存放区)

系统区域,一般是指固件在NAND闪存内部开辟出来的多个高安全区域,这些区域的特点是,相比于其他区域,他们更加安全,更不容易出现bit error。

在这些最安全的系统区域,我们会用来存放固件代码和备份、坏块表等数据,因为固件代码和坏块表足够重要,所以会有很多的备份存放在多个不同的系统区域。

但是,最安全的系统区域,也只是相对安全,并非绝对安全。因此,对这些区域的扫描不可省略,一旦发现某些闪存块有问题,就要立马将数据搬到新的区域。至于扫描的时间间隔,一般是2-3周,或200-300个上下电循环,企业级一般是采用固定时间间隔很少采用上下电循环,消费类盘都可以。

用户数据区域后台扫描

用户数据区域,和刚刚说的系统区域,是一个相对的概念。

相对于系统区域,用户数据区域的数据安全性相对低一些,但也是相当重要的,毕竟用户就是上帝,上帝的数据绝不能丢。

但为什么需要定时去扫描用户的数据区域呢?因为所有的NAND闪存都有一个缺点,包括英特尔家的floating gate架构、或者其他家的charge trap架构,均存在电荷泄漏的问题。

意思是,当已经保存有数据的NAND闪存断电时,其cell内部的电子会逐渐逃逸出去,导致电荷泄漏,最终数据丢失。当然,不要过度恐慌,这是一个非常缓慢的过程。正常情况下,企业级SSD断电情况下,数据可以在40摄氏度温度下安全存放3个月,即使是生命末期。而消费类的SSD,则数据可以在30摄氏度的温度下安全存放1年的时间(所以,如果有好久没有用过且存有重要数据的SSD,要赶紧拿出来溜溜了,通上电跑一跑)。

它有个专业术语,叫数据保持-data retention。

因此,一旦我们的SSD掉电一段时间后,尤其是经历过高温的情况,之前保存的数据可能会陷入险境之中。这时候,一旦重新上电,SSD固件就要开始马不停蹄地去检查,哪些数据存在风险,要赶紧搬移到新的区域。

温度传感器采样

温度传感器采样,这个比较简单,因为很多情况下,系统需要获取到SSD内部的温度,来决定散热风速的转速。

因此,温度传感器的采用必不可少,一般都是每秒钟采样一次。

Log日志定时写入NAND

都知道Windows/Linux操作系统有各种各样的log日志,来记录系统的状态和debug用途。SSD也是一样,它内部也运行了一套庞大的类似系统一样的复杂逻辑和运算,因此也会存在各种各样的Log日志来记录系统状态、错误信息等内容。

尤其是在SSD研发早期阶段,大量的debug工作非常依赖于系统log。同时,在如今的大型数据中心,越来越多的用户开始关注SSD Log,因为对于数据中心的运维来说,健全的Log可以大大提高debug效率。

但,因为很多时候,最新Log其实是存放在DRAM中的,因为这样可以更快去刷新。而DRAM是易失性存储,即掉电数据丢失,因此,系统Log日志,同样也是需要定期维护刷写到非易失性的NAND闪存中的。至于刷写的时间间隔,因需求而异,可以设置5分钟,也可以设置半小时。

Read Disturb数据搬移

Read Disturb,读干扰,也是NAND闪存的其中一个缺点。具体的原理呢,会比较复杂,一时半会很难说清楚,后续有时间单独开一篇来讲。

这里,只简单说一下读干扰所带来的结果。因为现代NAND制程的进度,密度增加,导致cell之间的距离越来越小。而读干扰的现象也越来越明显,即当我们读取某个页数据非常多次数时(可能是200万~1000万次),会对它周边的页造成干扰,而影响到周边页的数据,严重时会造成周边页数据无法读取。

因此,当我们选择一款NAND开发SSD时,NAND厂商的FAE会告诉我们,read disturb建议的次数时xx次。

当固件发现某个页被连续读取了xx次时,触发了read disturb阈值,此时就要将周边页的数据进行搬移,防止数据丢失。

后台GC垃圾回收

后台GC垃圾回收,这个已经不用说太多了吧。

因此NAND闪存本身的特性,最小写入单位是页,而擦除最小单位是块。因此随着数据不断写入,每个块上都会随机散布着各种数据,这时候如果有新的数据再写进来,则可能没有足够的空间,这时候就需要擦除旧的数据块,并搬移有效数据到新的块。

当经历过了长时间的随机写数据时,这部分GC的工作量是非常大的,而且非常影响这个SSD的性能。

磨损均衡

二八定律无处不在,又或者说,正态分布才是自然的常态。

经过不正经的调查,当没有任何认为干预时,我们随机性地往SSD中写入数据。

当我们写满全盘时,没有太大发现,但是当写了很多次全盘之后,就会发现。

NAND闪存中仅有20%的区域被写入了超过80%的数据,而另外80%的区域却并没有被写入太多数据。

这样会造成一个问题,因为NAND闪存都是有寿命的,而这种写入方法会造成20%的NAND闪存块很快被写完,寿命殆尽。而剩下80%的NAND闪存块却还可以用很久。

但这20%的闪存块的退役,会导致整个SSD系统无法正常工作,相当于一个本来完整的木桶,突然出现了一块短板,导致桶里的水大量流失。

因此,Wear Leveling磨损均衡才被需要,而且相当重要,因为它决定了你的木桶到底能装多少水!

最后

写到这里,我虽意犹未尽,但也累得腰酸背痛想要休息片刻。

不知各位读者看完,作何感想,能写SSD固件代码固然不难,但如果要做好固件真心不易。