全国服务热线:18888889999
在线报名
欧陆注册CURRICULUM
欧陆资讯 NEWS CENTER
联系我们 CONTACT US
手机:
18888889999
电话:
0898-66889888
邮箱:
admin@youweb.com
地址:
海南省海口市玉沙路58号
欧陆资讯
你的位置: 首页 > 欧陆资讯
基础:磁盘IO性能优化的几个思路
2024-03-04 12:49:13 点击量:

找出磁盘IO的瓶颈之后,就可以进行性能优化了,也就是如何以最快的速度完成IO操作/减少甚至避免磁盘的IO操作。

那么,如何进行磁盘IO优化呢?

优化之前,先确定IO性能优化的目标。换句话说,这些IO性能指标(比如IOPS、吞吐量、延迟等),要达到多少才何时呢?

事实上,IO性能指标是没有具体标准的,因为应用场景、使用的文件系统和物理磁盘等不同。

为了更客观合理的评估优化效果,我们首先应该对磁盘和文件系统进行基准测试,得到文件系统或者磁盘IO的极限性能。

  • fio(flexible IO Tester)是最常用的文件系统和磁盘IO性能基准测试工具。
  • 它提供了大量的可定制化选项,可以用来测试,裸盘或者文件系统在各种场景下的IO性能,包括了不同块大小、不同IO引擎以及是否使用缓存等场景。

安装方法如下:

 

安装完成后,就可以执? man fio 查询它的使法。

一些比较常见的场景用法:

 

在这其中,有?个参数需要你重点关注?下。

  • direct,表示是否跳过系统缓存。上?示例中,我设置的 1 ,就表示跳过系统缓存。
  • iodepth,表示使?异步 I/O(asynchronous I/O,简称AIO)时,同时发出的 I/O 请求上限。在上?的示例中,设置的是64。
  • rw,表示 I/O 模式。示例中, read/write 分别表示顺序读/写,? randread/randwrite 则分别表示随机读/写。
  • ioengine,表示 I/O 引擎,它?持同步(sync)、异步(libaio)、内存映射(mmap)、?络(net)等各种 I/O 引擎。上?示例中,设置的 libaio 表示使?异步 I/O。
  • bs,表示 I/O 的。示例中,设置成了 4K(这也是默认值)。
  • filename,表示?件路径,当然,它可以是磁盘路径(测试磁盘性能),也可以是?件路径(测试?件系统性能)。示例中,设置成了磁盘 /dev/sdb。不过注意,?磁盘路径测试写,会破坏这个磁盘中的?件系统,所以在使?前,?定要事先做好数据备份。

下?是使? fio 测试顺序读的?个报告示例。

 

这个报告中,需要我们重点关注的是, slat、clat、lat ,以及 bw 和 iops 这。

先来看刚刚提到的前三个参数。事实上,slat、clat、lat 都是指 I/O 延迟(latency)。不同之处在于:

  • slat ,是指从 I/O 提交到实际执? I/O 的时?(Submission latency);
  • clat ,是指从 I/O 提交到 I/O 完成的时?(Completion latency);
  • ? lat ,指的是从fio 创建 I/O 到 I/O 完成的总时?。

这里需要注意的是,对同步IO来说,由于IO提交和IO完成是一个动作,所以slat实际上就是IO完成的时间,而clat是0。?从示例可以看到,使?异步 I/O(libaio)时,lat 近似等于 slat + clat之和。

再来看bw ,它代表吞吐量。在上?的示例中,你可以看到,平均吞吐量?约是 16 MB(17005 KiB/1024)。

最后的iops ,其实就是每秒 I/O 的次数,上?示例中的平均 IOPS 为 4250。

通常情况下,应用程序的IO都是读写并行的,而且每次的IO大小也不一定相同。所以,刚刚说的这几种场景,并不能精确模拟应用程序的IO模式。那么怎么才能精确模拟应用程序的IO模式呢?

fio支持IO的重放。借助blktrace,在配合上fio,就可以实现对应用程序IO模式的基准测试。

可以先用blktrace,记录磁盘设备的IO访问情况;然后使用fio,重放blktrace的记录。比如:

 

这样,我们就通过 blktrace+fio 的组合使?,得到了应?程序 I/O 模式的基准测试报告。

得到 I/O 基准测试报告后,然后找出 I/O 的性能瓶颈并优化,就是?到渠成的事情了。当
然, 想要优化I/O 性能,肯定离不开 Linux 系统的 I/O 栈图的思路辅助。
在这里插入图片描述
可以从应用程序、文件系统以及磁盘角度来优化IO

首先,我们来看一下,从应用程序的角度有哪些优化IO的思路。

应用程序处于整个IO栈的最上端,它可以通过系统调用,来调整IO模式(顺序/随机、同步/异步),同时,它也是IO数据的最终来源。常见优化方法:

  • (1)可以使用追加写代替随机写,减少寻址开销,加快IO写的速度
  • (2)可以借助缓存IO,充分利用系统缓存,降低实际IO的次数
  • (3)可以在应用程序内部构建自己的缓存,或者用redis这类外部缓存系统。
    • 这样,一方面,能够在应用程序内部,控制缓存的数据和生命周期;
    • 另一方面,也能降低其他应用程序使用缓存对自身的影响。
    • 比如,C标准库提供的fopen、fread等函数,都会利用标准库的缓存,减少磁盘的操作。如果直接使用open、read等系统调用时,就只能利用操作系统提供的页缓存和缓冲区等,而没有库函数的缓存可用。
  • (4)在需要频繁读写同一块磁盘空间时,可以用mmap代替read/write,减少内存的拷贝次数
  • (5)在需要同步写的场景中,尽量将写请求合并,而不是让每个请求都同步写入磁盘,即可以利用fsync() 取代 O_SYNC。
  • (6)在多个应用程序共享相同磁盘时,为了保证IO不被某个应用完全占用,推荐使用cgroups的IO子系统,来限制进程/进程组的IOPS以及吞吐量
  • (7)在使? CFQ 调度器时,可以? ionice 来调整进程的 I/O 调度优先级,特别是提?核?应?的 I/O 优先级。ionice ?持三个优先级类:Idle、Best-effort 和 Realtime。其中, Best-effort 和 Realtime 还分别?持 0-7 的级别,数值越?,则表示优先级别越?。

应用程序访问普通文件时,实际是由文件系统间接负责文件在磁盘中的读写。所以,跟文件系统中相关的也有很多优化IO性能的方式:

  • (1) 可以根据实际负载场景的不同,选择最合适的文件系统

    • ?如Ubuntu 默认使? ext4 ?件系统,? CentOS 7 默认使? xfs ?件系统。
    • 相?于 ext4 ,xfs ?持更?的磁盘分区和更?的?件数量,如 xfs ?持?于16TB 的磁盘。但是 xfs ?件系统的缺点在于?法收缩,? ext4 则可以。
  • (2)在选好?件系统后,还可以进?步优化?件系统的配置选项,包括?件系统的特性(如ext_attr、dir_index)、?志模式(如journal、ordered、writeback)、挂载选项(如noatime)等等。

    • ?如, 使?tune2fs 这个?具,可以调整?件系统的特性(tune2fs 也常?来查看?件系统超级块的内容)。
    • ?通过 /etc/fstab,或者 mount 命令?参数,我们可以调整?件系统的?志模式和挂载选项等。
  • (3) 可以优化?件系统的缓存。

    • ?如,可以优化 pdflush 脏?的刷新频率(?如设置 dirty_expire_centisecs 和dirty_writeback_centisecs)以及脏?的限额(?如调整 dirty_background_ratio 和 dirty_ratio等)。
    • ?如,可以优化内核回收?录项缓存和索引节点缓存的倾向,即调整vfs_cache_pressure(/proc/sys/vm/vfs_cache_pressure,默认值100),数值越?,就表示越容易回收。
  • (4)在不需要持久化时,还可以利用内存文件系统fs,以获得更改的IO性能。

    • tmpfs把数据直接保存在内存中,而不是在磁盘中。
    • 比如/dev/shm/ ,就是?多数 Linux 默认配置的?个内存?件系统,它的默认为总内存的?半。

数据的持久化存储,最终还是要落在具体的物理磁盘中,同时,磁盘也是整个IO栈的最底层。从磁盘角度出发,自然也有很多有效的优化方法

  • (1)最简单有效的优化方法,就是换用更好的磁盘,比如用SSD替代HDD
  • (2)我们可以使用RAID,把多个磁盘组成一个逻辑磁盘,构成冗余独立磁盘阵列。这样做既可以提高数据的可靠性,又可以提高数据的访问性能
  • (3)针对磁盘和应用程序IO模式的特性,我们可以选择最合适的IO调度算法。比如,SSD和虚拟机中的磁盘,通常用noop调度算法;而数据库应用建议使用deadline算法
  • (4)我们可以对应用程序的数据,进行磁盘级别的隔离。比如,我们可以为日志、数据库等IO压力比较重的应用,配置单独的磁盘
  • (5)在顺序读比较多的场景中,我们可以增大磁盘的预读数据,?如,你可以通过下?两种?法,调整 /dev/sdb 的预读。
    • 调整内核选项 /sys/block/sdb/queue/read_ahead_kb,默认是 128 KB,单位为KB。
    • 使? blockdev ?具设置,?如 blockdev --setra 8192 /dev/sdb,注意这?的单位是 512B(0.5KB),所以它的数值总是read_ahead_kb 的两倍。
  • (6)我们可以优化内核块设备IO的选项。?如,可以调整磁盘队列的?度 /sys/block/sdb/queue/nr_requests,适当增?队列?度,可以提升磁盘的吞吐量(当然也会导致 I/O 延迟增?)。
  • (7)最后要注意,磁盘本身出现硬件错误,也会导致IO性能急剧下降,所以发现磁盘性能急剧下降时,先确定,磁盘本身是不是出现了硬件错误。
    • ?如,可以查看 dmesg 中是否有硬件 I/O 故障的?志。
    • 还可以使? badblocks、smartctl等?具,检测磁盘的硬件问题,或? e2fsck 等来检测?件系统的错误。如果发现问题,你可以使? fsck 等?具来修复。

发现 I/O 性能问题后,不要急于动?优化,?要先找出最重要的、可以最?程度提升性能的问题,然后再从 I/O 栈的不同层,考虑具体的优化?法。

记住,磁盘和文件系统的IO,通常是整个系统中最慢的一个模块。所以,在优化IO问题时,除了可以优化IO的执行流程,还可以接祖更快的内存、网络、CPU等,减少IO调用

?如,你可以充分利?系统提供的 Buffer、Cache ,或是应?程序内部缓存, 再或者Redis 这类的外部缓存系统