共计 3442 个字符,预计需要花费 9 分钟才能阅读完成。
大家都晓得硬盘的随机 IO 很慢,然而比程序 IO 慢多少呢,不晓得你是否有过数字上的间接比照。明天我来理论压测比照一下磁盘在程序 IO 和随机 IO 不同场景下的性能数据体现。通过明天的试验数据,你将能深刻理解数据库事务中为什么要用日志的形式来实现,为什么索引中要用节点更大的 B + 树。
对于任何存储系统,性能指标无非就是带宽、提早或 IOPS。我的测试机器的硬盘配置是一个由 7 块 300G 万转机械磁盘组成的 RAID5,压测工具应用的 fio,压测过程中,咱们固定几个参数:
- IO 引擎咱们抉择 libaio
- 为了防止操作系统治理的 PageCache 内存对测试后果的烦扰,应用 direct 参数绕开
- 关上 unified_rw_reporting,让后果中别离显示读和写
- 为了保障测试绝对精确,咱们运行工夫设置为 300s
- 因为服务器敏感性,压测对象没有抉择裸设施,用的文件,会有一点文件系统额定开销
- 测试文件尺寸定义为 100G,我的 RAID 卡缓存是 1G,目标就是让它的命中率别太高
- 调度策略咱们抉择最最罕用的 noop
- 关上 refill_buffers,每次 I / O 提交后都从新生成测试文件数据片段,保障随机性
- 依照 RAID 应用配置倡议,敞开掉磁盘自带缓存
而后再对另外的参数进行动静调整,而后进行屡次比照测试
- 读写模式上,应用程序读和随机读进行别离验证
- 磁盘 IO 单位咱们应用扇区的整数倍,512 1K 2K …
- RAID 卡预读策略,别离设置 NORA(不开启预读)和 RA(开启预读)来独立测试
程序读取测试
咱们先来看一下程序读取状况下,在该磁盘阵列的带宽体现,见图 1:
能够看到,当 IO size 比拟小的时候,即便是程序发动间断 IO 申请,带宽体现也不算给力,只有不到 20MB/s。随着 IO size 减少的时候,带宽也上来了, 最大可能达到 1.2GB 多。
大家留神看下在 NORA 状况下,在 128K 减少到 256K 的时候,带宽忽然减少了很多,这是为啥呢?机密在于我的 RAID 阵列里的条带大小是 128K, 当 IO size 为 256K 的时候,磁盘阵列才开始真正并行工作了。IO size 小的时候,并不能施展多盘劣势。
/opt/MegaRAID/MegaCli/MegaCli64 -LDInfo -Lall -aALL
......
Strip Size : 128 KB
另外就是对于程序 IO 的状况,RA 预取也能起到一些作用,在 IO size 在 64k 的时候就可能达到 1.2GB 的带宽。
咱们再来看提早,见图 2:
咱们图中的单位是微秒 -us,在《简略聊聊磁盘分区》中,我对磁盘耗时进行过实践上的估算,磁盘耗时次要在两个中央:
- 寻道工夫:3-15ms,这个耗时能够通过正当分区优化
- 旋转提早:万转磁盘这个提早大略 0 -6ms
为什么在图 2 试验后果里,延时却都很低,在 IO size 为 512 的时候,均匀居然只有 30us 左右?其实程序 IO 的状况下,RAID 卡缓存命中率很高,其实绝大部分的读申请并没有穿透到让磁盘的机械轴来工作。
咱们再来看 IOPS,见图 3:
在 IO 申请 size 正好为 1 个扇区大小的时候,磁盘阵列的 IOPS 体现最高,达到了 3W 屡次每秒。当 IO size 减少的时候,IOPS 在逐渐降落,但这时候,其实磁盘的吞吐是在减少的。
汇总一下,磁盘阵列在程序 IO 的状况下体现还是很不错的,起因有三个:
- 程序 IO 的状况下,RAID 卡的命中率高,尤其是设置了 RAID 预取
- 单盘自身程序 IO 也是磁盘工作最舒服的状态,因为节约了寻道的延时
- 当 IO 超过 RAID 条状大小的时候,IO 会扩散到多块盘上并行处理
随机读取测试
咱们作为开发者应用磁盘的时候,可能不肯定能保障永远都能让它工作在最舒服的状态,有些时候可能也必须得让它进行随机拜访。所以咱们明天也试一下我的磁盘阵列在随机状况下的体现,对于 fio 工具来说只须要设置 rw 参数为 randread 既可。不过 IO size 我只测试到了 128 就停了,因为再大了就越像程序 IO 了。
咱们还是先来看带宽,见图 4:
机械硬盘即便是组成了 RAID 阵列,而且还有缓存,貌似对随机 IO 也无可奈何。在随机 IO 的状况下,带宽吞吐蹩脚透了,在 IO size 比拟小的时候,居然只有零点几兆每秒。
咱们再来看延时,见图 5:
随机状况下延时根本都 5ms 左右,这就和咱们后面实践上的计算结果对上了。随机拜访导致更多的申请真正穿透到了机械轴上。
再来看 IOPS,这个指标也很差,也就是 200 左右吧。这个数据和图 5 的提早造成了响应,解决一次申请 5ms 左右,那么 1 秒可不就是只能解决 200 次左右么。所以硬盘厂家们天天给你吹风,说他家磁盘 IOPS 能达到几万几万。然而他们素来闭口不提随机 IO 状况下,其实特么的只有 200。
大家看到了我的万转机械硬盘组成 RAID5 阵列,在程序条件最好的状况下,带宽能够达到 1GB/ s 以上,均匀延时也非常低,最低只有 20 多 us。然而在随机 IO 的状况下,机械硬盘的短板就充沛裸露了,零点几兆的带宽,将近 5ms 的提早,IOPS 只有 200 左右。其起因是因为
- 随机拜访间接让 RAID 卡缓存成了个陈设
- 磁盘不能并行工作,因为我的机器 RAID 宽度 Strip Size 为 128 KB
- 机械轴也得在各个磁道之间跳来跳去。
了解了磁盘程序 IO 时候的几十 M 甚至一个 GB 的带宽,随机 IO 这个真的是太可怜了。
论断
从下面的测试数据中咱们看到了机械硬盘在程序 IO 和随机 IO 下的微小性能差别。在程序 IO 状况下,磁盘是最善于的程序 IO, 再加上 Raid 卡缓存命中率也高。这时带宽体现有几十、几百 M,最好条件下甚至能达到 1GB。IOPS 这时候能有 2 -3W 左右。到了随机 IO 的情景下,机械轴也被逼的跳来跳去寻道,RAID 卡缓存也生效了。带宽跌到了 1MB 以下,最低只有 100K,IOPS 也只有可怜巴巴的 200 左右。
如果你真正了解了以上试验中的数据,就能了解很多工程实际中的许多的事件。
复制文件夹 :咱们都晓得,在复制一个文件夹的时候,如果这个文件夹外面蕴含了许多堆碎文件,这时候复制起来十分慢。起因就是这时候机械硬盘大概率都是在随机 IO。怎么进步复制速度呢?很简略,就是把它们先打一个包。打包之后这个文件夹就变成一个大文件了,这时候再复制的话,磁盘就是执行的最善于的程序 IO 了,所以会快很多。
数据库事务 :所有的数据库在实现事务的时候,都要保障写数据落盘胜利能力返回。但为什么他们简直都是落盘到本人的事务日志文件里去就返回胜利的,而不是间接写入到数据表文件里。这背地的起因还是磁盘读写性能问题,事务只须要保证数据落地胜利就能够,至于写到哪里并不重要。写到数据文件中的话大概率就变成随机 IO 了。如果写到一个日志文件中,就是地地道道的程序 IO,性能就施展到极致。
Mysql 的 B + 树 :在下面的数据中大家还能够看到,无论是程序 IO 还是随机 IO,只有减少每次 IO 的单位,性能都会上涨。了解了这个,你就能真正了解为什么 Mysql 是采纳 B + 树当索引,而不是用其它的树了(比方二叉树)。因为 B + 树的节点更大,IO 起来会让磁盘工作更难受一些。
最初结尾我想分享一个 5 年前我在工程中理论性能优化的案例。过后接手了一个零碎,要用数以百万级的用户 imei,到 Mysql 中去查问用户的另一个字符串 id(clientid)数据。前开发的实现形式是传统的分批进行 Mysql 语句查问。这种实现下,且不说屡次的网络 RTT 耗时,单说 Mysql 查问,即便是有索引这时候也得须要进行大量的随机 IO,因为用户 imei 是随机散布的。我采纳的优化形式也非常简单,间接把 Mysql 用户整张用户表一次性通过程序 IO 的形式读出来,load 到内存中。在内存中用 HashTable 组织好,通过 Hash 的形式进行疾速查问。最终耗时优化掉了 90% 以上。
开发内功修炼之硬盘篇专辑:
- 1. 磁盘开篇:扒开机械硬盘坚挺的外衣!
- 2. 磁盘分区也是隐含了技术技巧的
- 3. 咱们怎么解决机械硬盘既慢又容易坏的问题?
- 4. 拆解固态硬盘构造
- 5. 新建一个空文件占用多少磁盘空间?
- 6. 只有 1 个字节的文件理论占用多少磁盘空间
- 7. 文件过多时 ls 命令为什么会卡住?
- 8. 了解格式化原理
- 9.read 文件一个字节理论会产生多大的磁盘 IO?
- 10.write 文件一个字节后何时发动写磁盘 IO?
- 11. 机械硬盘随机 IO 慢的超乎你的设想
- 12. 搭载固态硬盘的服务器到底比搭机械硬盘快多少?
我的公众号是「开发内功修炼」,在这里我不是单纯介绍技术实践,也不只介绍实践经验。而是把实践与实际联合起来,用实际加深对实践的了解、用实践进步你的技术实际能力。欢送你来关注我的公众号,也请分享给你的好友~~~