SSD 还分随机和顺序 IO 吗?
原文 http://blog.sina.com.cn/s/blog_69406f8d0102vcxz.html
上周,有位朋友提出一个问题:“在 HDD 中,顺序 8KB 写和离散(随机) 8KB 写的 IOPS 差别大,这是因为磁盘机械的原因。那么在 SSD 里面,顺序 8KB 和离散 8KB 写 IOPS 也还会有差别吗?”
这是一个好问题。因为硬盘每一次随机访问,都需要消耗磁头寻道和盘片旋转等待这两部分时间;而 SSD 使用的是半导体闪存介质,随机访问要快得多。
我在《 Oracle Exadata X5弹性扩展与SSD性能计算 》一文中,经过推算得出“ Oracle Exadata X5弹性扩展与SSD性能计算 Exadata 公布的 SQL 闪存写 IOPS 可以是顺序操作,所以会超过 IntelP3600 标称的 8KB 随机写 IOPS ”的判断。当时也确实有点拍脑袋,印象中看过这方面的测试数字,但却一时拿不出证据了。
最简单的办法,就是用实际测试再验证一遍,这时我已经做好推翻自己的准备:)
上图引用了 IDF 关于 SSD 的演示文稿,“不管顺序还是随机写入,都没有寻址时间,因为它们都是被顺序地写到 NAND 里面去的。”
这里的说明不只代表 Intel SSD ,所有以闪存为介质的固态盘都是如此,通过 FTL “将新数据写入新的物理地址,将原来的 LBA 地址标明无效并不可用”,让我想起了 NetApp WAFL 和 ZFS 文件系统。
以上是理论 基础 ,下面看看测试环境和测试结果。
测试环境
首先,我可没有 Exadata 那样高大上的东西,话说以我的 Oracle 水平也玩不动,现在拿给我玩也浪费了。
就拿自己用的 SL500 笔记本吧,正好系统盘已经换成 SSD ——被誉为渣渣的三星 840 EVO ( TLC ),凑合着做个验证。
如上图,由于 C 盘上安装了操作系统,不能影响正经事儿,所以我在当初预留的 11GB 空间上创建了一个测试分区,并且用 Iometer 将其“填满”后开始测试。
这里说明 2 点:
1. 我测试的不是整盘,但 SSD 有 FTL 来实现磨损平衡,因此实际写入的 LBA 范围很可能比较大并在物理上不连续,可以像 WAFL/ZFS 文件系统那样永远写到新的位置。
2. 另外我是在 NTFS 文件系统上做的测试,与直接测试裸盘有些差别,每种文件系统 / 卷管理器通常都会有些缓存、元数据之类的,不过对本次测试影响不大。
操作系统是 Windows7 64 位, Iometer 软件版本 1.1.0-win64.x86_64 ,每次测试运行 2 分 30 秒(我的 SSD 已经过一段时间的“老化”)。我们看到 C 盘里的数据也不少,如果是机械硬盘这样测试 Z 盘的话,只要没有(对 C 盘操作) I/O 争用就无所谓;而 SSD 则不同,整个盘的内充满数据的比例、以及碎片化程度都会影响到性能,特别是写入性能。
由于 SSD 的特点,不仅写入闪存页面速度没有读快,另外已经写入数据的页面(大小 4KB/8KB )需要经过块( 64KB 以上)擦除才能再次写入,也就是通常所说的垃圾回收( GC )过程。相比之下机械硬盘不存在这些问题。
测试结果及分析
SSD 随机 / 顺序写入性能对比(关闭写缓存)
为了避免写缓存的干扰,我首先在关闭写缓存的情况下运行了测试。根据以上图表,排除测试误差情况因素,差距确实比较小。 SSD 在队列深度为 1 时的 500 左右 IOPS ,也达到了我笔记本 5400 转机械硬盘的 10 倍。
结论初步有了,但是接下来我又面临一个问题——之前对 Exadata X5 存储节点 SQL flash read/write IOPS 的简单分析如何解释?
“ ExtremeFlash 全闪存节点为 377,000 ,这里是 SQL IOPS 已经考虑到 ASM 冗余带来的写惩罚,那么落到每个 SSD (每节点 8 个)上应该就是 94,250 ——好像这个数字明显超过了 IntelP3600 标称的 8KB 写 IOPS 33,000 ?
那么 HighCapacity 大容量混合存储节点的 192,000 ,落到 4 块闪存卡上 96,000 写 IOPS 也是类似的情况? ”
我们仍然以 Oracle 给出的最大性能指标是落在 SSD 上的真实 IOPS 为前提 ,如果顺序写不能比随机写更快的话,那这个数字是怎么测出来的?
有 Oracle 的朋友给出了回答: “ F160 ( NVMe SSD )的指标和 P3600 不完全一样,说用的是 eMLC , 8KB 随机写入指标到 42000 ”,“我们的卡不是标准产品,比标准的卡性能更好,寿命更长。”
Oracle 给出的 F160 性能确实比上表中的 IntelP3600 高,但距离我计算之后期望的数值还相差比较多。至于 eMLC 和寿命之说,感觉 Intel 又有点玩了数字游戏——我曾经写过 P3600 没有像 P3700 那样标明 High Endurance Technology (HET) 闪存,但新发布同样支持 5 年每天 3 次整盘写入, 1.6TB 型号最大写入数据量 10.7PB 的 S3610 (同容量的 P3600 为 8.76PB ),就标明了高耐久度 MLC 。
我们再看看还有啥提高性能的方法。
参考上图,不知 Smart Scan 能否 将 8KB 数据块整合成更大的 I/O ?如此则写入带宽将会增加。不过这违背了我们刚刚设定的前提。
增加队列深度对随机读改善比较明显,也就是发挥闪存的并发能力,其实看前面关闭写缓存情况下 的 随机 / 顺序写测试也是如此。
上面的文字重新解释了“ 随机度 ”对性能的影响,理由是 顺序操作减少通道冲突,以及碎片回收的难度 。右边柱状图中的差距是在什么条件下测得的呢?
还有过量冗余—— Intel 等厂商早就说过“减少 LBA 的访问范围可以提升性能、耐久性和服务质量”。右边的折线图最右端为 100% 随机写,当 超量配置 ( OP )为 0% 时写 I/O 很容易触发垃圾回收;有了 20% 和 40% 空间冗余 比例可以带来显著的写 IOPS 提升。
让我们再来看看 Intel 当年的 SSD 320 是公布了怎样的“作弊方法”——在 8GB LBA 范围内测试,并打开写缓存。其实消费级 SSD 公布的 IOPS ,有几家不是这样测的呢,甚至于 Fusion-io 好像也这么干过。
那么 Exadata X5 是不是也可以预留闪存容量呢——没有说测试数据集一定要多大吧?可惜我的笔记本 SSD 太搓,在 11GB 分区内测试也没快到哪里去,不过可以打开写缓存试试看。
SSD 随机 / 顺序写入性能对比(打开写缓存)
如上图, 4 条不同颜色的实线表示 IOPS ,以左边的坐标轴为单位; 4 条对应颜色的虚线表示延时(单位毫秒),以右边的坐标轴位单位。从左到右的 4 个点,代表每项测试我都运行了 4 遍。我的 Excel 水平不高,大家凑合看看:)
首先,我在队列深度设为 1 的情况下对比了 8KB 随机写和顺序写,由于写缓存的因素,前 2 次测试的 IOPS 波动比较大,而到了第 3 次以后则趋于稳定并出现明显一些的差距。将队列深度改为 32 之后,随机写 IOPS 并没有明显的改善。
至于队列深度 32 的 8KB 顺序写,只是拿来做个参考数字,毕竟我都是在有限的时间内运行测试。 8KB 是 Oracle OLTP 应用的典型 IO 尺寸;对于批量插入和 redo log 这样的小数据块顺序写操作,我不确定多线程 / 进程能够发挥到什么程度。由于我在数据库方面并不专业,所以这里就不妄下判断了。
尝试给出一个结论: Intel 在资料中提到过随机度对 SSD 写入性能的影响(原因前面解释过了)。除了过量冗余能够提高写入性能之外,根据测试, 打开写缓存在一些情况下也可以改善 SSD 8KB 顺序写 IOPS (长时间测试效果有待验证)。
极限测试和 POC 、读 IOPS 如何
许多消费级 SSD 大胆使用 DRAM 写缓存来提高 IOPS 性能,我在《 SSD 缓存掉电保护: 3 种方案的利与弊 》一文中提到有的企业级 SSD 也这么做,但要用电容来做保护; 这样对性能的效果与控制器 /RAID 卡的写缓存,延时将数据持久化到硬盘 /SSD 的情况类似。
尽管可能会带来数据风险,但对于极限性能测试来说,快一些有什么不好呢?正如同行朋友所说,有多少 POC 会老老实实地使用 write-through 、 SYNC 这样的参数呢?
最后我还顺手做了个读测试,可以看到在并发足够(队列深度 32 )的情况下 8KB 随机读 IOPS 能够达到甚至超过 8KB 顺序读,这时我的笔记本 CPU 占用率已达 80-90% (还有杀毒软件什么的,就算是个小小的生产环境吧),这个 SSD 可能还有潜力。
另一方面,如果队列深度只有 1 ,那么顺序读还是比随机读要快不少,我理解这是预读的效果。
本人的技术水平有限,欢迎大家批评指正!文中如有不够严谨的观点,权且当作给大家拓展思路吧:)