存储和文件系统性能的适当设置高度依赖于存储用途。
I/O 和文件系统性能可能受以下任一因素影响:
- 数据写入或读取模式
- 顺序或随机
- 缓冲或直接 IO
- 数据与基础几何图形对齐
- 块大小
- 文件系统大小
- 期刊大小和位置
- 记录访问时间
- 确保数据可靠性
- 预取数据
- 预分配磁盘空间
- 文件碎片
- 资源争夺
33.1.用于监视和诊断 I/O 和文件系统问题的工具
红帽企业 Linux 8 中提供了以下工具,用于监控系统性能并诊断与 I/O、文件系统及其配置相关的性能问题:
-
vmstat
该工具报告整个系统的进程、内存、分页、块 I/O、中断和 CPU 活动。它可以帮助管理员确定 I/O 子系统是否造成任何性能问题。如果分析vmstat
表明 I/O 子系统导致性能下降,管理员可以使用该iostat
工具来确定负责的 I/O 设备。 -
iostat
报告系统中的 I/O 设备负载。它是由sysstat
包提供的。 -
blktrace
提供有关 I/O 子系统如何花费时间的详细信息。配套实用程序blkparse
读取 的原始输出blktrace
,并生成由 记录的输入和输出操作的人类可读摘要blktrace
。 -
btt
分析blktrace
输出并显示数据在 I/O 堆栈的每个区域中花费的时间量,从而更容易发现 I/O 子系统中的瓶颈。该实用程序作为软件包的一部分提供blktrace
。该blktrace
机制跟踪并分析的一些重要事件btt
包括:- I/O 事件排队 (
Q
) - 将 I/O 分派给驱动程序事件 (
D
) - I/O 事件完成 (
C
)
- I/O 事件排队 (
-
iowatcher
可以使用blktrace
输出来绘制随时间变化的 I/O 图表。它重点关注磁盘 I/O 的逻辑块地址 (LBA)、每秒兆字节的吞吐量、每秒的查找次数以及每秒的 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 跟踪工具,用于显示每个 I/O 事件以及发出的进程 ID 和 I/O 延迟。使用此工具,您可以调查磁盘 I/O 性能问题。 -
biotop
用于内核中的块 I/O 操作。 -
filelife
工具跟踪stat()
系统调用。 -
fileslower
跟踪缓慢的同步文件读取和写入。 -
filetop
按进程显示文件读取和写入。 -
ext4slower
、nfsslower
、 和xfsslower
是显示文件系统操作慢于某个阈值(默认为 )的工具10ms
。
-
-
bpftace
是一种eBPF
用于分析性能问题的跟踪语言。它还提供用于系统观察的 BCC 等跟踪实用程序,这对于调查 I/O 性能问题非常有用。 -
以下
SystemTap
脚本可能有助于诊断存储或文件系统性能问题:disktop.stp
:每5秒检查一次磁盘读写状态,并输出该期间的前10条记录。iotime.stp
:打印读写操作所花费的时间,以及读写的字节数。traceio.stp
:每秒根据观察到的累积 I/O 流量打印前十个可执行文件。traceio2.stp
:在对指定设备进行读取和写入时打印可执行文件名称和进程标识符。Inodewatch.stp
:每次对指定主设备或次设备上的指定 inode 进行读取或写入时,打印可执行文件名称和进程标识符。inodewatch2.stp
:每次在指定主设备或次设备上的指定 inode 上更改属性时,打印可执行文件名称、进程标识符和属性。
其他资源
vmstat(8)
、iostat(1)
、blktrace(8)
、blkparse(1)
、btt(1)
、bpftrace
和iowatcher(1)
手册页
33.2.用于格式化文件系统的可用调整选项
设备格式化后,某些文件系统配置决策将无法更改。
以下是格式化存储设备之前可用的选项:
Size
为您的工作负载创建适当大小的文件系统。较小的文件系统需要较少的时间和内存来进行文件系统检查。但是,如果文件系统太小,其性能会因碎片过多而受到影响。
Block size
块是文件系统的工作单元。块大小决定了单个块中可以存储多少数据,因此决定了一次写入或读取的最小数据量。
默认块大小适合大多数用例。但是,如果块大小或多个块的大小与通常一次读取或写入的数据量相同或稍大,则文件系统的性能会更好,并且存储数据的效率会更高。小文件仍然使用整个块。文件可以分布在多个块上,但这会产生额外的运行时开销。
此外,某些文件系统仅限于一定数量的块,这反过来又限制了文件系统的最大大小。使用该命令格式化设备时,块大小被指定为文件系统选项的一部分mkfs
。指定块大小的参数因文件系统而异。
Geometry
文件系统几何结构与数据在文件系统中的分布有关。如果您的系统使用条带存储(例如 RAID),则可以在格式化设备时通过将数据和元数据与底层存储几何结构对齐来提高性能。
许多设备会导出推荐的几何形状,然后在使用特定文件系统格式化设备时自动设置该几何形状。如果您的设备不导出这些建议,或者您想要更改建议的设置,则在使用命令格式化设备时必须手动指定几何形状mkfs
。
指定文件系统几何结构的参数因文件系统而异。
External journals
日志文件系统在执行操作之前将写入操作期间将进行的更改记录在日志文件中。这降低了存储设备在系统崩溃或电源故障时损坏的可能性,并加快了恢复过程。
元数据密集型工作负载涉及非常频繁的日志更新。较大的日志使用更多内存,但会降低写入操作的频率。此外,您可以将元数据密集型工作负载的日志放置在与主存储一样快或更快的专用存储上,从而缩短设备的寻道时间。
确保外部期刊的可靠性。丢失外部日志设备会导致文件系统损坏。外部日志必须在格式化时创建,并在安装时指定日志设备。
33.3。用于挂载文件系统的可用调整选项
以下是大多数文件系统可用的选项,并且可以在安装设备时指定:
Access Time
每次读取文件时,其元数据都会根据访问发生的时间进行更新 ( atime
)。这涉及额外的写入 I/O。这是大多数文件系统的 relatime
默认设置。atime
但是,如果更新此元数据非常耗时,并且不需要准确的访问时间数据,则可以使用noatime
mount 选项挂载文件系统。这会在读取文件时禁用元数据更新。它还启用了nodiratime
在读取目录时禁用元数据更新的行为。
atime
使用该选项 禁用更新noatime mount
可能会破坏依赖更新的应用程序,例如备份程序。
Read-ahead
Read-ahead
这种行为通过预取可能很快需要的数据并将其加载到页面缓存中来加速文件访问,在页面缓存中检索数据比在磁盘上更快。预读值越高,系统预取数据的时间越早。
红帽企业 Linux 尝试根据检测到的文件系统内容设置适当的预读值。然而,准确的检测并不总是可能的。例如,如果存储阵列将自身作为单个 LUN 呈现给系统,则系统会检测到该单个 LUN,并且不会为阵列设置适当的预读值。
涉及大量顺序 I/O 流的工作负载通常受益于高预读值。红帽企业 Linux 提供的与存储相关的调整配置文件提高了预读值,就像使用 LVM 条带化一样,但这些调整并不总是足以满足所有工作负载。
其他资源
mount(8)
、xfs(5)
、 和ext4(5)
手册页
33.4。丢弃未使用块的类型
对于固态磁盘和精简配置存储,建议定期丢弃文件系统未使用的块。
以下是丢弃未使用块的两种方法:
Batch discard
这种类型的丢弃是fstrim
命令的一部分。它会丢弃文件系统中符合管理员指定条件的所有未使用的块。红帽企业 Linux 8 支持在支持物理丢弃操作的 XFS 和 ext4 格式设备上进行批量丢弃。
Online discard
这种类型的丢弃操作是在安装时使用丢弃选项进行配置的,并且无需用户干预即可实时运行。但是,它仅丢弃从已用状态转换为空闲状态的块。红帽企业 Linux 8 支持 XFS 和 ext4 格式设备上的在线丢弃。
红帽建议批量丢弃,除非需要在线丢弃来维持性能,或者批量丢弃对于系统工作负载不可行。
预分配将磁盘空间标记为已分配给文件,而不将任何数据写入该空间。这对于限制数据碎片和较差的读取性能很有用。红帽企业 Linux 8 支持在 XFS、ext4 和 GFS2 文件系统上预分配空间。应用程序还可以通过使用调用来从预分配空间中受益fallocate(2) glibc
。
其他资源
mount(8)
和fallocate(2)
手册页
33.5。固态硬盘调优注意事项
固态硬盘 (SSD) 使用 NAND 闪存芯片而不是旋转磁盘来存储持久数据。 SSD 在整个逻辑块地址范围内为数据提供恒定的访问时间,并且不会像旋转的同类产品那样产生可测量的寻道成本。它们每 GB 存储空间的价格更高,并且存储密度更低,但它们也比 HDD 具有更低的延迟和更高的吞吐量。
当 SSD 上使用的块接近磁盘容量时,性能通常会下降。性能下降的程度因供应商而异,但所有设备在这种情况下都会经历性能下降。启用丢弃行为有助于缓解这种退化。
默认 I/O 调度程序和虚拟内存选项适合与 SSD 一起使用。配置可能影响 SSD 性能的设置时,请考虑以下因素:
I/O Scheduler
任何 I/O 调度程序都有望在大多数 SSD 上表现良好。但是,与任何其他存储类型一样,红帽建议进行基准测试以确定给定工作负载的最佳配置。使用 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_ratio
和vm_dirty_ratio
设置,因为增加的写出活动通常不会对磁盘上其他操作的延迟产生负面影响。然而,这种调整可以生成更多的总体 I/O,因此在没有特定于工作负载的测试的情况下通常不建议这样做。
Swap
SSD 还可以用作交换设备,并且可能产生良好的页出和页入性能。
33.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
文件中。文件内容是监控I/O工具(如或 )/sys/diskstats
的I/O信息来源。因此,如果禁用设备的参数,该设备将不再出现在 I/O 监视工具的输出中。 sar``iostats``iostats
max_sectors_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 大小的倍数的 I/O。
read_ahead_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核处于同一CPU组中。要仅在发出 I/O 请求的处理器上执行完成,请将rq_affinity
设为2
。要禁用上述两个功能,请将其设置为0
。
scheduler
要为特定存储设备设置调度程序或调度程序首选项,请编辑该文件,其中_devname_是要配置的设备的名称。 /sys/block/_devname_/queue/scheduler