cai*_*dme 3 database filesystems storage disk
就像在文件尾部附加日志条目,或者就像mysql记录其重做日志一样,人们总是说顺序写入比随机写入快得多。但为什么?我的意思是,当您在磁盘上写入数据时,寻道时间和旋转时间决定性能。但是在两次连续的顺序写入之间,可能还有很多其他写入请求(例如 nginx 记录 access.log)。这些写入请求可能会将磁头移动到其他磁道,当您的进程进行顺序写入时,它需要再次将磁头移回原处,并产生旋转时间。即使没有其他过程时,磁头可以静止不动,但也需要等待旋转。那么,顺序写入优于随机写入是否真的只是因为在许多情况下顺序写入不包含寻道时间,而随机写入总是包含寻道时间,但顺序写入和随机写入都包含旋转时间?
磁盘的写入性能受存储设备的物理属性(例如机械磁盘的物理旋转速度,以每分钟转数为单位)、磁盘 I/O 单元与 I/O 请求大小的比率以及操作系统的影响/应用。
传统机械磁盘的一个主要缺点是,为了满足 I/O 请求,磁头必须到达所需的起始位置(寻道延迟),而盘片必须到达所需的起始位置(旋转延迟)。
对于顺序 I/O 和随机 I/O 都是如此。然而,对于顺序 I/O,这种延迟变得相当不明显,因为无需重新定位磁头即可写入更多数据。“高级格式”硬盘的扇区大小为 4096 字节(最小的 I/O 单元),柱面大小为兆字节范围。无需重新定位磁头即可读取整个气缸。因此,是的,涉及寻道和旋转延迟,但无需进一步重新定位即可读取/写入的数据量要高得多。此外,从一个柱面移动到下一个柱面比从最里面的柱面移动到最外面的柱面(最坏情况查找)效率更高。
写入 10 个连续扇区涉及一次寻道和旋转延迟,写入分布在磁盘上的 10 个扇区涉及 10 次寻道和旋转延迟。
一般来说,顺序 I/O 和随机 I/O 都涉及寻道和旋转延迟。顺序 I/O 利用顺序局部性来最大限度地减少这些延迟。
如您所知,固态磁盘没有移动部件,因为它通常由闪存构建。数据存储在单元格中。多个单元形成一个页——最小的 I/O 单元,大小从 2K 到 16K 不等。多个页面以块的形式进行管理 - 一个块包含 128 到 256 个页面。
问题有两个方面。首先,一个页面只能写入一次。如果所有页都包含数据,则除非擦除整个块,否则无法再次写入它们。假设需要更新块中的页面并且所有页面都包含数据,则必须擦除并重写整个块。
其次,单个块的写周期数是有限的。为了防止某些块比其他块更快地接近或超过最大写入周期数,使用了一种称为磨损均衡的技术,以便将写入均匀地分布在所有块上,而与逻辑写入模式无关。这个过程还涉及块擦除。
为了减轻块擦除的性能损失,SSD 采用垃圾收集过程,通过将不包括过时页面的块页面写入新块并擦除原始块来释放标记为过时的已用页面。
这两个方面都可能导致物理读取和写入的数据多于逻辑写入所需的数据。全页写入可以触发 128 到 256 倍的读/写序列,具体取决于页/块关系。这称为写放大。随机写入可能比顺序写入命中更多的块,从而使它们的成本更高。
如前所述,磁盘对可参与读取和写入的 I/O 单元施加了最低要求。如果将单个字节写入磁盘,则必须读取、修改和写入整个单元。
与顺序 I/O 相比,随着 I/O 负载的增加,触发大量写入的可能性很高(例如,在数据库事务日志的情况下),随机 I/O 往往涉及较小的 I/O 请求。当这些请求变得小于最小 I/O 单元时,处理这些请求的开销就会增加,从而增加随机 I/O 的成本。这是由于存储设备特性而导致写入放大的另一个示例。但此时HDD和SSD场景都会受到影响。
操作系统具有多种机制来优化顺序 I/O 和随机 I/O。由应用程序触发的写入通常不会立即处理(除非应用程序通过同步/直接 I/O 或同步命令请求),更改将基于所谓的页面缓存在内存中执行并写入磁盘在稍后的时间点。
通过这样做,操作系统可以最大化可用数据总量和各个 I/O 的大小。执行效率低下的单个 I/O 操作可以聚合为一个潜在的大型、更高效的操作(例如,对特定扇区的多个单独写入可以变成单个写入)。该策略还允许 I/O 调度,选择最有效执行 I/O 的处理顺序,即使应用程序定义的原始顺序不同。
考虑以下场景:Web 服务器请求日志和数据库事务日志被写入同一磁盘。如果 Web 服务器写入操作按所涉及的应用程序发出的顺序执行,那么它们通常会干扰数据库写入操作。由于基于页缓存的异步执行,操作系统可以对这些 I/O 请求重新排序,以分别触发两个大型顺序写入请求。当这些正在执行时,数据库可以继续写入事务日志,没有任何延迟。
这里需要注意的是,虽然这对于 Web 服务器日志来说应该是正确的,但并非所有写入都可以随意重新排序。每当事务日志必须作为提交的一部分写入稳定存储时,数据库就会触发磁盘同步操作(fsync
在 Linux/UNIX 上、在 Windows 上)。FlushFileBuffers
然后,操作系统不能再延迟写入操作,并且必须立即执行所有先前对相关文件的写入。如果 Web 服务器执行相同的操作,可能会对性能产生明显影响,因为顺序由这两个应用程序决定。这就是为什么最好将事务日志放置在专用磁盘上,以便在存在其他磁盘同步/大量其他 I/O 操作的情况下最大化顺序 I/O 吞吐量(Web 服务器日志应该不是问题) )。否则,随着总 I/O 负载和/或磁盘同步数量的增加,基于页面缓存的异步写入可能无法再隐藏 I/O 延迟。