为什么在硬盘上顺序写入比随机写入要快

时间:2020-05-12 07:18:57

标签: database filesystems storage disk

就像在文件的末尾添加日志条目一样,或者就像mysql记录其重做日志一样,人们总是说顺序写入比随机写入要快得多。但为什么?我的意思是,当您在磁盘上写入数据时,寻道时间和旋转时间决定了性能。但是在两次连续的连续写入之间,可能还有许多其他写入请求(例如nginx记录access.log)。这些写请求可能会将磁头移到其他磁道,并且当您的过程执行顺序写操作时,它需要再次将磁头移回,并花费旋转时间。即使没有其他过程,磁头也可以静止不动,您还需要等待旋转。 那么,在很多情况下,顺序写入不包含寻道时间,而随机写入总是包含寻道时间,而先后写入和随机写入都包含轮换时间,那么顺序写入是否比随机写入更好呢? / p>

1 个答案:

答案 0 :(得分:2)

性能受存储设备的物理属性(例如,机械HDD情况下每分钟的物理旋转速度),扇区与I / O请求大小之比和OS /应用程序的影响。

存储设备的物理属性

正如您在问题中概述的那样,传统机械硬盘驱动器的一个主要缺点是,要满足I / O请求,磁头必须达到所需的起始位置(寻找延迟),而盘片必须达到所需的起始位置(旋转延迟)。

对于顺序和随机I / O,这是正确的。但是,使用顺序I / O时,此延迟变得不那么明显,因为无需重新放置磁头就可以写入更多数据。 “高级格式”硬盘的扇区大小为4096字节(最小的I / O单元),柱面大小在兆字节范围内。无需重新定位磁头即可读取整个圆柱体。因此,是的,这涉及到寻道和旋转延迟,但是无需进一步重新定位就可以读取/写入的数据量要高得多。而且,从一个圆柱体移到另一个圆柱体比从最里面的圆柱体移到最外面的圆柱体(最坏情况的搜索)要有效得多。

连续写入10个扇区涉及一次寻道和旋转延迟,写入磁盘上的10个扇区涉及10个寻道和旋转延迟计数。

所以,你是对的。通常,顺序I / O和随机I / O都包含寻道和旋转延迟。顺序I / O利用顺序局部性来最大程度地减少这些延迟。

扇区到I / O请求的大小

如前所述,扇区是最小的I / O单元-512字节或4096字节,具体取决于磁盘。如果将单个字节写入磁盘,则必须读取,修改和写入扇区。

与顺序I / O相比,在顺序I / O中,随着I / O负载增加,触发大写操作的可能性很高(例如,在数据库事务日志的情况下),随机I / O往往涉及较小的I / O请求。随着这些请求变得小于最小的I / O单元,处理这些请求的开销会增加,从而增加了随机I / O的成本。

操作系统/应用程序

操作系统具有多种优化顺序I / O和随机I / O的机制。 通常不会立即处理由应用程序触发的写操作(除非应用程序通过同步/直接I / O或同步命令进行请求),更改是基于所谓的页面缓存在内存中执行并写入的磁盘在以后的某个时间点。

通过这样做,操作系统可以最大化可用数据总量和单个I / O的大小。执行起来效率不高的单个I / O操作可以汇总为一个潜在的大型高效操作(例如,对特定扇区的几次单独写入可以变成一次写入)。

此策略还允许进行I / O调度,选择一个执行I / O效率最高的处理顺序,即使一个或多个应用程序定义的原始顺序不同。这就是您的示例发挥作用的地方。假设nginx日志和数据库日志都被写入同一磁盘,则nginx写入操作通常会干扰数据库写入操作(如果它们按相关应用程序的顺序执行)。由于基于页面缓存的异步执行,OS可以对这些I / O请求重新排序,以分别触发两个大的顺序写入请求。在执行这些操作时,数据库可以继续写入事务日志,而不会出现任何延迟。

一个警告是,尽管对于nginx日志应该如此,但是并非所有写入都可以随意重新排序。每当事务日志必须作为提交的一部分写入稳定存储时,数据库就会触发磁盘同步操作(在Linux / UNIX上为fsync)。然后,OS无法再延迟写入操作,而必须立即执行所有先前对相关文件的写入。如果nginx这样做,可能会对性能产生明显影响,因为顺序是由这两个应用程序决定的。这就是为什么通常将事务日志放置在专用磁盘上以在存在其他磁盘同步/大量其他I / O操作的情况下最大化顺序I / O吞吐量的一个好主意的原因(nginx日志应该不是问题)。否则,随着总I / O负载和/或磁盘同步数的增加,基于页面缓存的异步写入可能不再能够隐藏I / O延迟。

相关问题