You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
12 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 46 | SSD硬盘如何完成性能优化的KPI
随着3D垂直封装技术和QLC技术的出现今年的“618”SSD硬盘的价格进一步大跳水趁着这个机会我把自己电脑上的仓库盘从HDD换成了SSD硬盘。我的个人电脑彻底摆脱了机械硬盘。
随着智能手机的出现互联网用户在2008年之后开始爆发性增长大家在网上花的时间也越来越多。这也就意味着隐藏在精美App和网页之后的服务端数据请求量呈数量级的上升。
无论是用10000转的企业级机械硬盘还是用Short Stroking这样的方式进一步提升IOPSHDD硬盘已经满足不了我们的需求了。上面这些优化措施无非就是把IOPS从100提升到300、500也就到头了。
于是SSD硬盘在2010年前后进入了主流的商业应用。我们在[第44讲](https://time.geekbang.org/column/article/113809)看过一块普通的SSD硬盘可以轻松支撑10000乃至20000的IOPS。那个时候不少互联网公司想要完成性能优化的KPI最后的解决方案都变成了换SSD的硬盘。如果这还不够那就换上使用PCI Express接口的SSD。
不过只是简单地换一下SSD硬盘真的最大限度地用好了SSD硬盘吗另外即便现在SSD硬盘很便宜了大部分公司的批量数据处理系统仍然在用传统的机械硬盘这又是为什么呢
那么接下来这两讲就请你和我一起来看一看SSD硬盘的工作原理以及怎么最大化利用SSD的工作原理使得访问的速度最快硬盘的使用寿命最长。
## SSD的读写原理
SSD没有像机械硬盘那样的寻道过程所以它的随机读写都更快。我在下面列了一个表格对比了一下SSD和机械硬盘的优缺点。
![](https://static001.geekbang.org/resource/image/a5/7c/a53e407311293609cb0753c7889a367c.jpeg)
你会发现不管是机械硬盘不擅长的随机读写还是它本身已经表现不错的顺序写入SSD在这些方面都要比HDD强。不过有一点机械硬盘要远强于SSD那就是耐用性。如果我们需要频繁地重复写入删除数据那么机械硬盘要比SSD性价比高很多。
要想知道为什么SSD的耐用性不太好我们先要理解SSD硬盘的存储和读写原理。我们之前说过CPU Cache用的SRAM是用一个电容来存放一个比特的数据。对于SSD硬盘我们也可以先简单地认为它是由一个电容加上一个电压计组合在一起记录了一个或者多个比特。
### SLC、MLC、TLC和QLC
能够记录一个比特很容易理解。给电容里面充上电有电压的时候就是1给电容放电里面没有电就是0。采用这样方式存储数据的SSD硬盘我们一般称之为**使用了SLC的颗粒**全称是Single-Level Cell也就是一个存储单元中只有一位数据。
![](https://static001.geekbang.org/resource/image/06/a7/0698c240459faa11254932905675dba7.jpeg)
但是这样的方式会遇到和CPU Cache类似的问题那就是同样的面积下能够存放下的元器件是有限的。如果只用SLC我们就会遇到存储容量上不去并且价格下不来的问题。于是呢硬件工程师们就陆续发明了**MLC**Multi-Level Cell、**TLC**Triple-Level Cell以及**QLC**Quad-Level Cell也就是能在一个电容里面存下2个、3个乃至4个比特。
![](https://static001.geekbang.org/resource/image/94/79/949106cb0ca5985a47388caef6925a79.jpeg)
只有一个电容我们怎么能够表示更多的比特呢别忘了这里我们还有一个电压计。4个比特一共可以从0000-1111表示16个不同的数。那么如果我们能往电容里面充电的时候充上15个不同的电压并且我们电压计能够区分出这15个不同的电压。加上电容被放空代表的0就能够代表从0000-1111这样4个比特了。
不过要想表示15个不同的电压充电和读取的时候对于精度的要求就会更高。这会导致充电和读取的时候都更慢所以QLC的SSD的读写速度要比SLC的慢上好几倍。如果你想要知道是什么样的物理原理导致这个QLC更慢可以去读一读这篇[文章](https://www.anandtech.com/show/5067/understanding-tlc-nand/2)。
### P/E擦写问题
如果我们去看一看SSD硬盘的硬件构造可以看到它大概是自顶向下是这么构成的。
![](https://static001.geekbang.org/resource/image/6a/5e/6ac3cfd51d39d3e3022effc7e4255e5e.jpeg)
首先自然和其他的I/O设备一样它有对应的**接口和控制电路**。现在的SSD硬盘用的是SATA或者PCI Express接口。在控制电路里有一个很重要的模块叫作**FTL**Flash-Translation Layer也就是**闪存转换层**。这个可以说是SSD硬盘的一个核心模块SSD硬盘性能的好坏很大程度上也取决于FTL的算法好不好。现在容我卖个关子我们晚一会儿仔细讲FTL的功能。
接下来是**实际I/O设备**它其实和机械硬盘很像。现在新的大容量SSD硬盘都是3D封装的了也就是说是由很多个裸片Die叠在一起的就好像我们的机械硬盘把很多个盘面Platter叠放再一起一样这样可以在同样的空间下放下更多的容量。
![](https://static001.geekbang.org/resource/image/0e/d3/0eee44535a925825b657bcac6afb72d3.jpeg)
接下来,一张裸片上可以放多个**平面**Plane一般一个平面上的存储容量大概在GB级别。一个平面上面会划分成很多个块Block一般一个块Block的存储大小 通常几百KB到几MB大小。一个块里面还会区分很多个页Page就和我们内存里面的页一样一个页的大小通常是4KB。
在这一层一层的结构里面,处在最下面的两层块和页非常重要。
对于SSD硬盘来说数据的**写入**叫作Program。写入不能像机械硬盘一样通过**覆写**Overwrite来进行的而是要先去**擦除**Erase然后再写入。
SSD的读取和写入的基本单位不是一个比特bit或者一个字节byte而是一个**页**Page。SSD的擦除单位就更夸张了我们不仅不能按照比特或者字节来擦除连按照**页**来擦除都不行,我们必须按照**块**来擦除。
而且你必须记住的一点是SSD的使用寿命其实是每一个块Block的擦除的次数。你可以把SSD硬盘的一个平面看成是一张白纸。我们在上面写入数据就好像用铅笔在白纸上写字。如果想要把已经写过字的地方写入新的数据我们先要用橡皮把已经写好的字擦掉。但是如果频繁擦同一个地方那这个地方就会破掉之后就没有办法再写字了。
我们上面说的SLC的芯片可以擦除的次数大概在10万次MLC就在1万次左右而TLC和QLC就只在几千次了。这也是为什么你去购买SSD硬盘会看到同样的容量的价格差别很大因为它们的芯片颗粒和寿命完全不一样。
### SSD读写的生命周期
下面我们来实际看一看一块SSD硬盘在日常是怎么被用起来的。
我用三种颜色分别来表示SSD硬盘里面的页的不同状态白色代表这个页从来没有写入过数据绿色代表里面写入的是有效的数据红色代表里面的数据在我们的操作系统看来已经是删除的了。
![](https://static001.geekbang.org/resource/image/96/81/966e51db8354922b533e1db236337e81.jpeg)
一开始,所有块的每一个页都是白色的。随着我们开始往里面写数据,里面的有些页就变成了绿色。
然后因为我们删除了硬盘上的一些文件所以有些页变成了红色。但是这些红色的页并不能再次写入数据。因为SSD硬盘不能单独擦除一个页必须一次性擦除整个块所以新的数据我们只能往后面的白色的页里面写。这些散落在各个绿色空间里面的红色空洞就好像硬盘碎片。
如果有哪一个块的数据一次性全部被标红了那我们就可以把整个块进行擦除。它就又会变成白色可以重新一页一页往里面写数据。这种情况其实也会经常发生。毕竟一个块不大也就在几百KB到几MB。你删除一个几MB的文件数据又是连续存储的自然会导致整个块可以被擦除。
随着硬盘里面的数据越来越多红色空洞占的地方也会越来越多。于是你会发现我们就要没有白色的空页去写入数据了。这个时候我们要做一次类似于Windows里面“磁盘碎片整理”或者Java里面的“内存垃圾回收”工作。找一个红色空洞最多的块把里面的绿色数据挪到另一个块里面去然后把整个块擦除变成白色可以重新写入数据。
不过这个“磁盘碎片整理”或者“内存垃圾回收”的工作我们不能太主动、太频繁地去做。因为SSD的擦除次数是有限的。如果动不动就搞个磁盘碎片整理那么我们的SSD硬盘很快就会报废了。
说到这里你可能要问了这是不是说我们的SSD硬盘的容量是用不满的因为我们总会遇到一些红色空洞
![](https://static001.geekbang.org/resource/image/e7/74/e7fcd994384145eefde614aaf3b45874.jpeg)
没错一块SSD的硬盘容量是没办法完全用满的。不过为了不得罪消费者生产SSD硬盘的厂商其实是预留了一部分空间专门用来做这个“磁盘碎片整理”工作的。一块标成240G的SSD硬盘往往实际有256G的硬盘空间。SSD硬盘通过我们的控制芯片电路把多出来的硬盘空间用来进行各种数据的闪转腾挪让你能够写满那240G的空间。这个多出来的16G空间叫作**预留空间**Over Provisioning一般SSD的硬盘的预留空间都在7%-15%左右。
## 总结延伸
到这里相信你对SSD硬盘的写入和擦除的原理已经清楚了也明白了SSD硬盘的使用寿命受限于可以擦除的次数。
仔细想一想你会发现SSD硬盘特别适合读多写少的应用。在日常应用里面我们的系统盘适合用SSD。但是如果我们用SSD做专门的下载盘一直下载各种影音数据然后刻盘备份就不太好了特别是现在QLC颗粒的SSD它只有几千次可擦写的寿命啊。
在数据中心里面SSD的应用场景也是适合读多写少的场景。我们拿SSD硬盘用来做数据库存放电商网站的商品信息很合适。但是用来作为Hadoop这样的Map-Reduce应用的数据盘就不行了。因为Map-Reduce任务会大量在任务中间向硬盘写入中间数据再删除掉这样用不了多久SSD硬盘的寿命就会到了。
好了,最后让我们总结一下。
这一讲我们从SSD的物理原理也就是“电容+电压计”的组合向你介绍了SSD硬盘存储数据的原理以及从SLC、MLC、TLC直到今天的QLC颗粒是怎么回事儿。
然后我们一起看了SSD硬盘的物理构造也就是裸片、平面、块、页的层次结构。我们对于数据的写入只能是一页一页的不能对页进行覆写。对于数据的擦除只能整块进行。所以我们需要用一个类似“磁盘碎片整理”或者“内存垃圾回收”这样的机制来清理块当中的数据空洞。而SSD硬盘也会保留一定的预留空间避免出现硬盘无法写满的情况。
到了这里我们SSD硬盘在硬件层面的写入机制就介绍完了。不过更有挑战的一个问题是在这样的机制下我们怎么尽可能延长SSD的使用寿命呢如果要开发一个跑在SSD硬盘上的数据库我们可以利用SSD的哪些特性呢想要知道这些请你一定要记得回来听下一讲。
## 推荐阅读
想要对于SSD的硬件实现原理有所了解我推荐你去读一读这一篇[Understand TLC NAND](https://www.anandtech.com/show/5067/understanding-tlc-nand)。
## 课后思考
现在大家使用的数据系统里往往会有日志系统。你觉得日志系统适合存放在SSD硬盘上吗
欢迎在留言区写下你的思考。如果有收获,你也可以把这篇文章分享给你的朋友。