大数据小视角5:探究SSD写放大的成因与解决思路

笔者目前开发运维的存储系统的服务器都跑在SSD之上,目前单机服务器最大的SSD容量有4T之多。(公司好有钱,以前在实验室都只有机械硬盘用的~~)但SSD本身的特性与机械硬盘差距较大,虽然说在性能上有诸多优势,但是如果使用的方式方法不对,反而会事倍功半。所以笔者花时间调研了一下固态硬盘的结构与特性,并且总结了一些避免SSD写放大性能下降的法则,希望对大家有所帮助~~

1.SSD的写放大

首先我们来看看什么是写放大,写放大(Write amplification)是2008年,由英特尔和SiliconSystems在论文之中首次提出:它表现为在SSD上实际写入的数据远远大于用户写入数据。

为什么会产生这样的现象呢,我们要回归到固态硬盘原本的特性。首先固态硬盘与传统的机械硬盘不同的点在于它不能够覆盖写。所以对于已经存在数据SSD来说,一次数据的写入分为2个动作:

  • 1、擦除SSD上已有的数据。
  • 2、写入新的数据。

写入放大的问题就出了这个部分,因为SSD每次写入的最小单位为Page,每个Page是4KB大小,而每次擦除的大小单位为BlockBlock通常由64或128个Page组成。也就是说,正是由于SSD写入与擦除的单位大小不匹配,导致了写入放大。如果仅仅是写入单一Page的数据,而单个Block之中没有了空余的Page,则需要擦除一个Block的数据,之后再写入一个Block的数据。所以说,本身只需要4KB的写入,"放大"了64倍甚至是128倍!由于SSD的寿命取决于擦除次数,所以写入放大会大大影响到SSD的使用寿命

典型的一个"写放大"的场景

OK,了解了写入放大的现象之后,我们接下来怎么样会导致写入放大的现象呢?

  • 写入量

这点应该很好理解,由上面的阐述可以看到,如果每次对SSD的写入都是很小的量,就会产生典型的写入放大。

  • 剩余容量

通常我们使用的SSD都存在预留空间(OP)来用于给SSD的主控芯片来进行一些优化操作。其中预留空间最为核心的两项工作就是垃圾回收损耗均衡,在这里笔者简要介绍一下垃圾回收和损耗均衡。

垃圾回收

SSD中主流的垃圾回收算法与Java之中的标记清除的垃圾回收算法类似:

SSD的垃圾回收

如上图所示,SSD首先在Block X之中写入A-D的Page页,之后继续写入到H,并且更新了A'-D',所以原先的A-D的page页成为了需要回收的垃圾。所以主控芯片会将可用数据移动到旁边的有空闲的Block Y,同时完整的擦除Block X。当剩余容量越小,垃圾回收越频发,则SSD的写入放大就越为严重。就是为什么许多手机在刚刚买来之后丝滑如顺,但是之后就越用越卡,这是因为容量越来越小了,SSD需要背锅!!(这也是笔者的64G的小米5剩余容量只有4个G了,日常使用卡如狗的部分原因~~)需要频繁进行垃圾回收的场景会导致写入放大的问题更为严重。

损耗均衡

我们知道,SSD的使用寿命等同于Block的擦写次数,目前主流使用的MLC颗粒的编程/擦写次数一般在3000 ~ 5000次左右。如果反复地编程和擦写某个Block,该Block则会先于其他Blcok损坏,导致坏块大量出现。正是因为这样的原因,SSD的主控芯片会尽可能的让每个Block的擦写次数均匀。所以损耗均衡的操作需要移动并没有新数据写入的Block,这样同样也会导致写放大的上升。

2.写放大问题的一些解决思路

了解了SSD的写放大的成因之后,我们可以『对症下药』的尝试给出一些方案来减小写放大问题来对我们线上服务的影响。

  • 批量写 这几乎是解决磁盘io问题的通用解决方案,同样适合于传统的机械硬盘与SSD。尽量在代码逻辑之中减少随机写的次数,来避免由少量写操作引发的写放大问题,同时可以考虑通过块对齐的方式来进一步减少写入产生的写放大问题。当然这里所谓块对齐的思路在是与程序运行环境紧耦合的,程序的可移植性会大打折扣
  • 预留空间,容量告警 这也是我们运维线上机器常用的思路,对于SSD的使用量要有一个阀值,超过我们的预设容量时,线上的程序需要给运维和开发人员告警。
  • 写压缩 写压缩是依赖SSD的主控芯片的,部分SSD主控芯片支持写压缩。也就说接受到操作系统发送要写入20m数据,主控芯片可以通过一些流压缩或块压缩的算法压缩数据,在读取数据时,再重新进行解压。这种方式强依赖硬件,并且新的瓶颈可能会是主控芯片的压缩,解压的速度。
  • TRIM命令 TRIM是操作系统层级的命令。操作系统利用TRIM命令来标记SSD上某个Page的数据可以回收。一旦某个Page被SSD标记为可以回收,在SSD空闲的时候SSD的主控芯片会将这些被标记的Page数据收集到同一个Block,然后共同擦除。这样每次需要写数据时,就在已经有足够空闲的Page可以写入新的数据。

上述几个思路都是在实践中可以采取的措施,其实TRIM命令需要通过Linux设置开启,这里笔者在这里介绍一下如何在Linux下开启TRIM命令:

  1. 确认Linux的内核是否大于 2.6.28,笔者这里是4.9.0的内核。

查看系统内核 2.调用hdparm -I /dev/sda1 命令确认SSD设备是否支持TRIM。

SSD设备支持TRIM 3.修改/etc/fstab文件,在挂载选项之中添加discard,重启之后就开启了TRIM

在fstab之中添加discard参数

3.小结

到此为止,笔者聊了聊SSD写放大的成因,并且针对SSD写放大的成因,提出了一些解决的思路和方法,希望大家能有所收获,在生产环境之中能够更好的『调教好』SSD~~~

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏玉树芝兰

如何用VOSviewer分析CNKI关键词共现?

用VOSviewer尝试CNKI中文文献关键词共现(keyword co-occurence)分析时,你可能会踩到一个大坑。本文帮助你绕开这个坑,或是从坑里爬出...

15820
来自专栏刘君君

Rest Notes-表述性状态移交(Representational State Transfer ,REST)

20450
来自专栏机器之心

教程 | 如何使用Kubernetes GPU集群自动训练和加速深度学习?

选自GitHub 机器之心编译 参与:蒋思源、Smith、吴攀 像 Docker 这样的容器格式和 Kubernetes 之类的容器管理平台正越来越受到人们的欢...

67630
来自专栏吉浦迅科技

Titan V做计算真的这么不靠谱么?

今年3月份有一篇文章在高性能计算这个领域算是引起了一个不小的波动英伟达的 Titan V GPU 计算故障:2+2=4,呃=4.1,不,=4.3.....

92120
来自专栏美团技术团队

人工智能在线特征系统中的数据存取技术

一、在线特征系统 主流互联网产品中,不论是经典的计算广告、搜索、推荐,还是垂直领域的路径规划、司机派单、物料智能设计,建立在人工智能技术之上的策略系统已经深入到...

1K50
来自专栏Python小屋

Python使用三种方法批量修改记事本文件编码格式

应用背景:近期计划写一个贝叶斯算法邮件分类的教学案例,苦于没有足够的训练集,就让同学们帮忙每人从自己的邮箱中找几封垃圾邮件把内容复制下来放到记事本文件中发给我,...

11720
来自专栏HappenLee的技术杂谈

大数据小视角5:探究SSD写放大的成因与解决思路

首先我们来看看什么是写放大,写放大(Write amplification)是2008年,由英特尔和SiliconSystems在论文之中首次提出:它表现为在S...

23250
来自专栏机器之心

业界 | AMD的GPU现在可以加速TensorFlow深度学习了

目前,AMD 的深度学习加速解决方案已经官方支持 TensorFlow 和 Caffe 两种框架。

30120
来自专栏AI研习社

基于 TensorFlow 、OpenCV 和 Docker 的实时视频目标检测

在本文中,我将介绍如何在 Docker 容器中使用 Tensorflow Object-detection API 来执行实时(网络摄像头)和视频的目标检测。我...

37320
来自专栏施炯的IoT开发专栏

Windows on Device 项目实践 2 - 感光灯制作

在上一篇《Windows on Device 项目实践 1 - PWM调光灯制作》中,我们学习了如何利用Intel Galileo开发板和Windows on ...

21570

扫码关注云+社区

领取腾讯云代金券