照章节目录,本周的主题是SSD。在外面,介绍SSD的文章非常之多,在我的文章里面就不重复其他地方介绍过的知识了。赶在睡觉时间之前发出来,希望大家能够轻轻松松了解点知识,然后合眼睡觉~
在本篇文章中,我想着重的分析以下几个问题:
1.在不同厂商的实现中,SSD的读写iops为什么会有如此之大的差距?
2.SSD的优势在于没有寻道时间了,为什么4K随机写还会是个性能大瓶颈?
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的优势在于没有寻道时间了,为什么4K随机写还会是个性能大瓶颈?
“在一些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.
FLASH控制器,看来成败就看他了!把他扔在那里最合适呢?
控制器要做的事情所需要的计算资源其实远远超出我们的想象,举个最简单的例子,一个页4k大小,那么对于120G的SSD来说,单单只是存储每个页是否有数据这件事,就需要30’000’000个标记位,完成其他功能也需要很多计算资源和存储资源。
一个好的控制器既然如此影响性能,放在什么地方,由谁来负责进行计算和存储就自然而然的成为了一个很重要的问题。
在大部分的实现里面,控制器是一个专门的芯片,封装了自己的算法和存储芯片。
不过在最近,有一些公司走出了不同的道路,尝试使用用户的CPU来进行计算和数据存储。
这两种方式各有优劣。
如果你使用了专门的控制器,那么好处是不会占用宝贵的中央处理器资源。而坏处则主要是升级有一定难度,并且计算资源会受到板载硬件的限制。
而如果你与用户共享中央处理器,那么好处是升级容易,用户甚至可以直接通过修改厂商提供的硬件驱动的方式增加更符合自己实际业务场景的写入策略,但坏处是会占用中央处理器资源。
目前来看,两种方式各有优势,后续也会相互借鉴进而更加完善,目前还没有哪一方能够完全占据市场,在可见的未来应该也不会。
很容易可以看到,NAND芯片会随着产能的提升而进一步降低价格,并且Flash控制器的也会随着时间和用户数的增长而更加完善。目前在intel比较新的控制芯片中,写入放大倍数甚至已经能够在某些场景下达到1.1左右了,几乎不是太大的问题了,随着这些问题的解决,随机写性能将有进一步的提升空间,而成本将进一步降低。
可以预见,在未来,对于追求iops的数据读写类应用来说,将用户经常访问的热点数据全部从传统磁盘搬到ssd上面应该是个趋势。自此,磁盘将是新的磁带,闪存是新的磁盘,内存为王。
转载于:https://blog.51cto.com/aliapp/1325353