Red Hat Training

A Red Hat training course is available for RHEL 8

第 30 章 影响 I/O 和文件系统性能的因素

存储和文件系统性能的适当设置高度依赖于存储用途。

I/O 和文件系统性能可能会受到以下任何因素的影响:

  • 数据写入或读取模式
  • 连续或随机
  • 缓冲或直接 IO
  • 与底层几metry 的数据一致
  • 块大小
  • 文件系统大小
  • 日志大小和位置
  • 记录访问时间
  • 确保数据可靠性
  • 预获取数据
  • 预分配磁盘空间
  • 文件碎片
  • 资源争用

30.1. 用于监控和诊断 I/O 和文件系统问题的工具

Red Hat Enterprise Linux 8 中提供了以下工具来监控系统性能,并诊断与 I/O、文件系统及其配置相关的性能问题:

  • vmstat 工具报告整个系统中进程、内存、分页、块 I/O、中断和 CPU 活动。它可以帮助管理员确定 I/O 子系统是否负责处理任何性能问题。如果使用 vmstat 分析显示 I/O 子系统负责降低性能,管理员可以使用 iostat 工具确定负责的 I/O 设备。
  • iostat 报告系统中的 I/O 设备负载。它由 sysstat 软件包提供。
  • blktrace 提供如何花费在 I/O 子系统中时间的详细信息。配套实用程序 blkparseblktrace 读取原始输出,并生成由 blktrace 记录的输入和输出操作人类可读概述。
  • btt 分析 blktrace 输出并显示 I/O 堆栈的每个区域中数据花费的时间,以便更容易发现 I/O 子系统中的瓶颈。这个工具作为 blktrace 软件包的一部分提供。由 blktrace 机制跟踪并由 btt 分析的一些重要事件有:

    • I/O 事件排队(Q)
    • 将 I/O 分配给驱动程序事件(D)
    • I/O 事件(C)
  • iowatcher 可以使用 blktrace 输出来图形 I/O。它侧重于磁盘 I/O 的逻辑块地址(LBA)、每秒吞吐量(以 MB 为单位)、每秒请求数和 I/O 操作数。这有助于识别何时达到设备的操作数秒限制。
  • BPF Compiler Collection(BCC)是一个库,它有助于创建扩展的 Berkeley Packet Filter(eBPF)程序。eBPF 程序在事件中触发,如磁盘 I/O、TCP 连接和进程创建。BCC 工具安装在 /usr/share/bcc/tools/ 目录中。以下 bcc-tools 有助于分析性能:

    • biolatency 总结了直方图中的块设备 I/O(磁盘 I/O)中的延迟。这允许研究发行版,包括两种设备缓存命中和缓存未命中模式,以及延迟延迟延迟。
    • biosnoop 是用于显示每个 I/O 事件以及发布进程 ID 和 I/O 延迟的基本块 I/O 跟踪工具。使用这个工具,您可以调查磁盘 I/O 性能问题。
    • biotop 用于内核中的块 i/o 操作。
    • filelife 工具跟踪 stat() 系统调用。
    • fileslower 跟踪较慢的同步文件读写。
    • filetop 可按进程显示文件的读取和写入.
    • ext4slowernfsslowerxfsslower 是显示文件系统操作比特定阈值慢的工具,其默认值为 10ms

      如需更多信息,请参阅使用 BPF Compiler Collection 分析系统性能

  • bpftaceeBPF 的追踪语言,用于分析性能问题。它还提供跟踪实用程序(如 BCC)进行系统观察,这对于调查 I/O 性能问题非常有用。
  • 以下 SystemTap 脚本在诊断存储或文件系统性能问题时可能有用:

    • disktop.stp: 检查每 5 秒读取或写入磁盘的状态,并输出该期间内前 10 个条目。
    • iotime.stp:打印读取和写入操作所需的时间,以及读取和写入的字节数。
    • traceio.stp:根据观察到的累计 I/O 流量打印前十个可执行文件,每秒.
    • traceio2.stp: 会在发生对指定设备的读取和写入时打印可执行名称和进程标识符。
    • Inodewatch.stp:每次对指定主设备或次要设备上的指定索引节点发生读或写时,打印可执行名称和进程标识符。
    • inodewatch2.stp:每次在指定主设备或次要设备上的指定索引节点上更改属性时,打印可执行名称、进程标识符和属性。

其它资源

30.2. 用于格式化文件系统的可用调整选项

在设备格式化后,无法更改一些文件系统配置决策。

以下是格式化存储设备前可用的选项:

Size
为您的工作负载创建适当大小的文件系统。较小的文件系统需要较少的时间和内存进行文件系统检查。但是,如果文件系统太小,其性能会受到高碎片影响。
Block size

块是文件系统的工作单元。块大小决定了单个块中可以存储多少数据,因此一次写入或读取的最小数据量。

默认块大小适用于大多数用例。但是,如果块大小或多个块的大小与通常一次读取或写入的数据量相同或略大,则文件系统性能更好,并且存储数据效率更高。个小文件仍然使用整个 块。文件可以分散到多个块中,但这会产生额外的运行时开销。

此外,某些文件系统仅限于特定数量的块,进而限制文件系统的最大大小。使用 mkfs 命令格式化设备时,块大小作为文件系统选项的一部分指定。指定块大小的参数因文件系统而异。

Geometry

文件系统 geometry 涉及文件系统中数据的分布。如果您的系统使用分条存储(如 RAID),您可以在格式化该设备时将数据和元数据与底层存储几兆对齐来提高性能。

许多设备会导出建议的 geometry,然后在设备使用特定文件系统格式化时自动设置。如果您的设备没有导出以上建议,或者您想要更改推荐的设置,那么当使用 mkfs 命令格式化该设备时,您必须手动指定 geometry。

指定文件系统地理位置的参数因文件系统而异。

External journals
日志文件系统记录了在执行操作之前,日志文件中写入操作期间将要进行的更改。这降低了存储设备在系统崩溃或电源故障时损坏的可能性,并加快恢复过程。
注意

红帽不推荐使用外部日志选项。

元数据密集型工作负载涉及非常频繁的日志更新。较大的日志使用更多的内存,但会降低写入操作的频率。此外,您可以通过将其日志放在专用存储中,使其与主存储快或快于主存储,从而缩短具有元数据密集型工作负载的设备的搜索时间。

警告

确保外部日志可靠。丢失外部日志设备会导致文件系统损坏。必须在格式时创建外部日志,并在挂载时指定日志设备。

其它资源

30.3. 用于挂载文件系统的可用调整选项

以下是大多数文件系统可用的选项,可指定为该设备:

Access Time

每次读取文件时,都会使用发生访问时更新其元数据(atime)。这涉及额外的写入 I/O。relatime 是大多数文件系统的默认 atime 设置。

但是,如果更新这个元数据非常耗时,且不需要准确的访问时间数据,您可以使用 noatime 挂载选项挂载文件系统。这会在文件读取时禁用对元数据的更新。它还启用 nodiratime 行为,它会在读取目录时禁用对元数据的更新。

注意

使用 noatime mount 选项禁用 atime 更新可能会破坏依赖它们的应用程序,例如备份程序。

Read-ahead

Read-ahead 行为通过预先抓取可能需要的数据并将其加载到页面缓存中来加快文件访问速度,其中的检索速度可以快于磁盘上。读-ad-head 值越大,系统预填充数据前面是另一个。

Red Hat Enterprise Linux 尝试根据它检测到的文件系统设置适当的读号值。但是,准确检测并不总是被允许。例如,如果存储阵列作为单个 LUN 向系统显示自己,则系统会检测到单个 LUN,且不会为阵列设置适当的读-ahead 值。

涉及大量流传输顺序 I/O 的工作负载通常得益于高读头值。红帽企业 Linux 提供的与存储相关的调优配置集提高了读头值,与使用 LVM 条带一样,这些调整并非始终足以满足所有工作负载的需要。

其它资源

  • mount(8)xfs(5)ext4(5) man page

30.4. 丢弃未使用块的类型

对于固态磁盘和精简置备的存储,建议定期丢弃文件系统未使用的块。

以下是丢弃未使用的块的两种方法:

Batch discard
这个丢弃是 fstrim 命令的一部分。它丢弃文件系统中的所有未使用块,这些块符合管理员指定的标准。Red Hat Enterprise Linux 8 支持在支持物理丢弃操作的 XFS 和 ext4 格式的设备上进行批量丢弃。
Online discard

这种丢弃操作在挂载时通过 discard 选项进行配置,并在用户不干预的情况下实时运行。但是,它只丢弃从已使用到空闲的块。Red Hat Enterprise Linux 8 支持在 XFS 和 ext4 格式的设备上进行在线丢弃。

红帽建议批量丢弃,除非需要在线丢弃才能保持性能,或者在系统工作负载无法使用批量丢弃的情况下。

预分配将磁盘空间标记为分配给文件,而不将任何数据写入该空间。这可用于限制数据碎片和读性能差。Red Hat Enterprise Linux 8 支持在 XFS、ext4 和 GFS2 文件系统上预分配空间。应用程序也可以从使用 fallocate(2) glibc 调用预先分配空间中受益。

其它资源

  • mount(8)fallocate(2) man page

30.5. 固态磁盘调优注意事项

固态磁盘(SSD)使用 NAND 闪存芯片,而不是旋转磁带来存储持久数据。SSD 为整个逻辑块地址范围内的数据提供恒定访问时间,而且不会像其对应人员那样产生可观的搜索成本。它们每 GB 存储空间的成本更高,存储密度也更低,但它们的延迟和吞吐量也比 HDD 更低。

性能通常降级为 SSD 上使用的块,即磁盘容量。降级程度因供应商而异,但所有设备在这种情况下都会出现降级情况。启用丢弃行为有助于缓解这种降级。如需更多信息,请参阅丢弃未使用的块的类型

默认 I/O 调度程序和虚拟内存选项适合用于 SSD。在配置可影响 SSD 性能的设置时,请考虑以下因素:

I/O Scheduler

大多数 SSD 预期任何 I/O 调度程序都能正常工作。但是,与任何其他存储类型一样,红帽建议采用基准测试来确定给定工作负载的最佳配置。在使用 SSD 时,红帽建议仅更改 I/O 调度程序以测试特定工作负载。有关如何在 I/O 调度程序间切换的说明,请参考 /usr/share/doc/kernel-version/Documentation/block/switching-sched.txt 文件。

对于单队列 HBA,默认 I/O 调度程序是 deadline。对于多个队列 HBA,默认的 I/O 调度程序是 none。有关如何设置 I/O 调度程序的详情,请参考 设置磁盘调度程序

Virtual Memory
与 I/O 调度程序一样,虚拟内存(VM)子系统不需要特殊调优。鉴于 SSD 上 I/O 的快速性质,请尝试关闭 vm_dirty_background_ratiovm_dirty_ratio 设置,因为增加的写入活动通常不会对磁盘中其他操作的延迟造成负面影响。不过,这种调优可能会产生更多整体 I/O,因此在未进行特定于工作负载的测试的情况下,通常不建议这样做。
Swap
SSD 也可以用作交换设备,并且可能会生成良好的 page-out 和 page-in 性能。

30.6. 通用块设备调优参数

本节中列出的通用调优参数包括在 /sys/block/sdX/queue/ 目录中。

以下列出的调优参数与 I/O 调度程序调整分开,并适用于所有 I/O 调度程序:

add_random
一些 I/O 事件对 /dev/random 的熵池贡献贡献。如果这些贡献的开销可以相当长,则可以将此参数设置为 0
iostats

默认情况下启用 iostats,默认值为 1。将 iostats 值设置为 0 可禁用为该设备收集 I/O 统计,这会删除 I/O 路径的少量开销。将 iostats 设置为 0 可能会稍为提高非常高性能设备的性能,比如某些 NVMe 固态存储设备。建议不要启用 iostats,除非厂商为给定的存储模型另有指定。

如果您禁用 iostats,该设备的 I/O 统计信息将不再出现在 /proc/diskstats 文件中。/sys/diskstats 文件的内容是监控 I/O 工具的 I/O 信息来源,如 sariostats。因此,如果您为设备禁用 iostats 参数,则 I/O 监控工具输出中不再存在该设备。

max_sectors_kb

以 KB 为单位指定 I/O 请求的最大大小。默认值为 512 KB。此参数的最小值由存储设备的逻辑块大小决定。这个参数的最大值由 max_hw_sectors_kb 的值决定。

红帽建议 max_sectors_kb 始终是最佳 I/O 大小的倍数,以及内部纠删块大小。如果参数为零或者未由存储设备指定,则为任一参数使用 logical_block_size 值。

nomerges
大多数工作负载均可从请求合并中受益。但是,禁用合并对于调试很有用。默认情况下,nomerges 参数被设置为 0,这将启用合并。要禁用简单的一次性合并,将 nomerges 设置为 1。要禁用所有类型的合并,将 nomerges 设置为 2
nr_requests
它是已排队 I/O 的最大允许数。如果当前的 I/O 调度程序是 none,则这个数字只能减少,否则可以增加或减少这个数量。
optimal_io_size
有些存储设备通过此参数报告最佳 I/O 大小。如果报告这个值,红帽建议应用程序尽可能在最佳 I/O 大小的倍数中与 I/O 一致。
read_ahead_kb

定义操作系统可在后续读取操作期间提前读取的最大 KB 数。因此,下一个顺序读取的内核页面缓存中已存在必要的信息,这提高了读取 I/O 性能。

设备映射器通常受益于高 read_ahead_kb 值。128 每个设备映射的 KB 都是一个不错的起点,但将 read_ahead_kb 值增加到请求队列的 max_sectors_kb 可能会改进在进行连续读取大型文件的应用程序环境中的性能。

rotational
有些固态磁盘无法正确公布其固态状态,而是作为传统旋转磁盘挂载。手动将 rotational 值设置为 0,以禁用调度程序中不必要的搜索尝试逻辑。
rq_affinity
rq_affinity 的默认值是 1。它在一个 cpu 核心上完成 I/O 操作,它位于发布的 cpu 核心的同一个 cpu 组中。要只在发出 I/O 请求的处理器中执行完成,将 rq_affinity 设置为 2。要禁用上述两个能力,请将其设置为 0
scheduler
要为特定存储设备设置调度程序或调度程序首选顺序,编辑 /sys/block/devname/queue/scheduler 文件,其中 devname 是您要配置的设备的名称。