计算机组成 -- SSD
对比
| 访问类型 | 机械硬盘(HDD) | 固态硬盘(SSD) |
|---|---|---|
| 随机读 | 慢 | 非常快 |
| 随机写 | 慢 | 快 |
| 顺序写 | 快 | 非常快 |
| 耐用性(重复擦写) | 非常好 | 差 |
读写原理
- CPU Cache用的SRAM是用一个电容来存放一个比特的数据
- 对于SSD硬盘,由一个电容加上一个电压计组合在一起,就可以记录一个或多个比特
- 分类
- SLC:Single-Level Cell
- MLC:Multi-Level Cell
- TLC:Triple-Level Cell
- QLC:Quad-Level Cell
- QLC
- 想要表示15个不同的电压,充电和读取的时候,对精度的要求就会更高,这会导致充电和读取的时候更慢
- QLC的SSD的读写速度要比SLC慢上好几倍
PE擦写问题
- 控制电路
- 常用的是SATA或者PCI Express接口,里面有一个很重要的模块:FTL(Flash-Translation Layer),即内存转换层
- FTL是SSD的核心模块,SSD性能的好坏很大程度上取决于FTL的算法好不好
- 实际的IO设备
- 新的大容量SSD都是3D封装的,即由很多裸片(Die)叠在一起(跟HDD有点类似)
- 一个裸片上可以放多个平面(Plane),一个平面上的存储容量大概在GB级别
- 一个平面上面,会划分成多个块(Block),通常大小在几百KB到几MB不等(AeroSpike为128KB)
- 一个块里面,还会区分很多个页(Page),通常大小为4KB
- 对于SSD,数据的写入叫作Program
- 写入不能像HDD那样,通过覆写(Overwrite)来进行,而是先进行擦除(Erase),然后再写入
- SSD读取和写入的基本单位:页(Page,4KB)
- SSD擦除的基本单位:块(Block)
- SSD的使用寿命,就是每一块的擦除次数
- SLC:10W次;MLC:1W次;TLC、QLC:几K次
读写的生命周期
- 颜色
- 白色:该页从未写入过数据
- 绿色:写入的是有效的数据
- 红色:在操作系统看来,数据是已经被删除了
- 一开始,所有块的每一页都是白色的,随着往里面写数据,某些页变成了绿色
- 然后,删除一些文件,有些页就变成了红色,但这些红色的页并不能再次写入数据
- 因为SSD不能单独擦除一个页,必须一次性擦除整个块
- 如果某个块的数据一次性全部标红,就可以把整个块擦除
- 随着红色页越来越多,已经没有了白色页去写入数据了,就要进行垃圾回收了
- 找一个红色页最多的块,把里面绿色页挪到另一个块里面,然后把整个块擦除,变成白色,就可以重新写入数据了
- 垃圾回收不能太主动和太频繁,因为SSD的擦除次数是有限的
- SSD的容量是无法完全用满的,因此厂商会预留一部分空间,专门用来做垃圾回收的
- 这部分空间叫作预留空间(Over Provisioning),一般SSD的预留空间都在**7%-15%**左右
- SSD特别适合读多写少的应用
- 适合做系统盘,但不适合做下载盘和数据盘
- 使用了SSD的系统盘,就不能用磁盘碎片整理
- 一旦主动去运行磁盘碎片整理,就会发生一次块的擦除,对应块的寿命就减少一些
磨损均衡
- 在操作系统上,并没有SSD上各个块已经擦写的情况和寿命,因此它对待SSD和HDD并没有什么区别
- 均匀磨损(Wear-Leveling):让SSD各个块的擦除次数,均匀分摊到各个块上,实现方式:FTL(即内存转换层)
- 在FTL里,存放了逻辑块地址(Logical Block Address,LBA)到物理块地址(Physical Block Address,PBA)的映射
- 操作系统访问的硬盘地址,其实都是逻辑地址,只有通过FTL转换后,才会变成实际的物理地址,找到对应的块进行访问
- 操作系统本身不需要去考虑块的磨损程度,只要和操作HDD一样来读写数据即可
- 操作系统所有对于SSD的读写请求,都要经过FTL
- FTL里面有逻辑块对应的物理块,因此FTL能够记录下来,每个物理块被擦写的次数
- 如果一个物理块被擦写的次数多了,FTL就可以将这个物理块,『挪到』一个擦写次数少的物理块上
- 但逻辑块不需要变,操作系统也不需要知道这个变化
TRIM
- 操作系统不去关心底层的硬件是什么,使用SSD时会有一个问题,即操作系统的逻辑层和SSD的逻辑层的块状态是不匹配的
- 在操作系统里面删除一个文件,其实并没有真的在物理层去删除这个文件
- 只是在文件系统层面,把对应的inode里面的元信息清理掉,代表这个inode还可以继续使用,可以写入新的数据
- 此时,实际物理层对应的存储空间,在操作系统里面被标记成可以写入
- 因此,日常的文件删除,都只是操作系统层面的逻辑删除
- 可以通过各种恢复软件,把数据找回来
- 如果想要把数据删除干净,需要用到『文件粉碎』的功能
- 上述逻辑在HDD是没有问题的,因为文件被标记成可以写入,后续的写入可以直接覆写这个位置
- 在使用SSD时,操作系统对于文件的删除,SSD其实并不知道!!
- 导致:为了磨损均衡,很多时候都在搬运很多已经删除了的数据 – 写入放大
- 产生很多不必要的数据读写和擦除,既消耗了SSD性能,也缩短了SSD的使用寿命
- 为此,操作系统(Linux、Windows、MacOS)和SSD的主控芯片,都支持TRIM命令
- TRIM命令:在文件被删除的时候,让操作系统通知SSD,对应的逻辑块已经被标记成已删除
写入放大
- TRIM命令的发明,反映了使用SSD的一个问题:SSD容易越用越慢
- 当SSD的存储空间被占用得越来越多,每一次写入新数据,都可能没有足够的空白
- 不得不去进行垃圾回收,合并一些块里面的页,然后在擦除一些块,才能匀出一些空间来
- 在应用层或者操作系统层面来看,可能只是写入一个4KB或者4MB的数据
- 但实际通过FTL后,可以需要搬运8MB、16MB甚至更多的数据
- 写入放大 = 实际内存写入的数据量 / 系统通过FTL写入的数据量
- 写入放大的倍数越多,意味着实际SSD性能就会越差,会远远比不上实际SSD硬盘标称的指标
- 解决方案:在后台定时进行垃圾回收,在硬盘比较空闲的时候,就进行垃圾回收,而不是等待实际数据写入的时候
AeroSpike
- AeroSpike是专门针对SSD特性设计的Key-Value数据库
- AeroSpike操作SSD,并没有通过操作系统的文件系统,而是直接操作SSD里面的块和页
- 对于KV数据库来说,操作系统里面的文件系统,相当于多了一层间接层,只会降低性能
- 读写数据的优化
- 在写入数据的时候,AeroSpike尽可能去写一个较大的数据块,而不是频繁地去写很多小的数据块
- 这样,SSD不太容易频繁出现磁盘碎片
- 另外,一次性写入一个大的数据块,更容易利用好顺序写入的性能优势
- AeroSpike写入的数据块,是128KB,远比一个页的4KB要大得多
- 在读取数据的时候,AeroSpike可以读取512 Bytes这样的小数据
- 因为SSD的随机读性能很好,也不像写入数据那样有擦除寿命的问题
- 很多时候读取的数据需要在网络上传输,如果一次性读出比较大的数据,就可能会导致网络带宽不够用
- 在写入数据的时候,AeroSpike尽可能去写一个较大的数据块,而不是频繁地去写很多小的数据块
- AeroSpike是一个对响应时间要求很高的实时KV数据库,如果出现严重的写放大效应,会导致写入数据的响应时间大幅度变长
- 持续进行磁盘碎片整理
- 采用高水位算法:一旦一个物理块里面的数据碎片超过50%,就把这个物理块搬运压缩,然后进行数据擦除
- AeroSpike给出最佳实践
- 为了保障数据库的性能,只用到SSD标定容量的50%
- 人为地给SSD预留50%的预留空间,以确保SSD的写放大效应尽可能小,不会影响数据库的访问性能
- 持续进行磁盘碎片整理
参考资料
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.









