6.3. 工具
有一些工具可用来帮助您诊断 I/O 子系统中的性能问题。vmstat 提供系统性能的粗略概述。以下栏与 I/O 相关:
si
(换入),so
(换出),bi
(阻止进入),bo
(阻止外出),以及wa
(I/O 等待时间)。当您的交换空间与数据分区同在一个设备中时 si
和 so
有用,且表示总体内存压力。si
和 bi
是读取操作,so
和 bo
是写入操作。这些分类以 Kb 为单位报告。wa
是停滞时间,表示在等待 I/O 完成时哪部分运行队列被阻断。
使用 vmstat 分析系统可让您了解 I/O 子系统是否对性能问题负责。
free
、buff
和 cache
栏最值得关注。cache
值会随着 bo
值增加,随着 cache
的降低 free
值会增大,表示系统正在执行写回操作,且无法使用页缓存。
注:
vmstat
报告的 I/O 数是集合了所有设备的 I/O 总数。如果您确定 I/O 子系统中可能有性能问题,则可以使用 iostat 做进一步的检查,该程序可以根据设备报告 I/O 情况。您还可以搜索更多详细信息,比如平均需求大小,每秒读取和写入数以及正在进行的 I/O 合并数量。
使用平均请求大小和平均队列大小(
avgqu-sz
)可预估如何使用在描述存储性能时生成的图表执行存储。可采用一些概括估计方法:例如,如果平均请求大小为 4KB,且平均队列大小为 1,则不大可能有非常高的性能。
如果性能值与您期待的性能值不同,可使用 blktrace 执行更详细的分析。blktrace 工具套件给出 I/O 子系统使用时间的详情。blktrace 的输出结果是一组二进制跟踪文件,可以使用其他工具进行后处理,比如 blkparse。
blkparse 是 blktrace 的配伍工具。它读取跟踪的原始输出并生成一手文字版本。
以下是 blktrace 输出结果示例:
8,64 3 1 0.000000000 4162 Q RM 73992 + 8 [fs_mark] 8,64 3 0 0.000012707 0 m N cfq4162S / alloced 8,64 3 2 0.000013433 4162 G RM 73992 + 8 [fs_mark] 8,64 3 3 0.000015813 4162 P N [fs_mark] 8,64 3 4 0.000017347 4162 I R 73992 + 8 [fs_mark] 8,64 3 0 0.000018632 0 m N cfq4162S / insert_request 8,64 3 0 0.000019655 0 m N cfq4162S / add_to_rr 8,64 3 0 0.000021945 0 m N cfq4162S / idle=0 8,64 3 5 0.000023460 4162 U N [fs_mark] 1 8,64 3 0 0.000025761 0 m N cfq workload slice:300 8,64 3 0 0.000027137 0 m N cfq4162S / set_active wl_prio:0 wl_type:2 8,64 3 0 0.000028588 0 m N cfq4162S / fifo=(null) 8,64 3 0 0.000029468 0 m N cfq4162S / dispatch_insert 8,64 3 0 0.000031359 0 m N cfq4162S / dispatched a request 8,64 3 0 0.000032306 0 m N cfq4162S / activate rq, drv=1 8,64 3 6 0.000032735 4162 D R 73992 + 8 [fs_mark] 8,64 1 1 0.004276637 0 C R 73992 + 8 [0]
如您所见,该输出结果非常紧凑且很难读懂。在这个结果中您可以看到负责向您的设备发出 I/O 的进程,是很有用的。但 blkparse 会在其概述中以容易理解的方式给出一些附加信息。blkparse 的概述信息在输出结果的最后面:
Total (sde): Reads Queued: 19, 76KiB Writes Queued: 142,183, 568,732KiB Read Dispatches: 19, 76KiB Write Dispatches: 25,440, 568,732KiB Reads Requeued: 0 Writes Requeued: 125 Reads Completed: 19, 76KiB Writes Completed: 25,315, 568,732KiB Read Merges: 0, 0KiB Write Merges: 116,868, 467,472KiB IO unplugs: 20,087 Timer unplugs: 0
概述显示平均 I/O 速度、合并活动,并对比读负载和写负载。但 blkparse 输出结果因太过繁琐而变得没有意义。还好有一些工具可以帮助您解析这些数据:
btt 提供对 I/O 在 I/O 栈中不同区域所花费时间的分析。这些区域为:
- Q — 将块 I/O 排队
- G — 获得请求新排队的块不能作为与现有请求合并的人选,因此会分配一个新的块层请求。
- M — 将 I/O is 与现有请求合并。
- I — 在设备队列中插入一个请求。
- D — 已向设备发出一个请求。
- C — 驱动程序已完成请求。
- P — 已插上块设备队列以便允许整合请求。
- U — 已撤销设备队列,允许向该设备发出整合的请求。
btt 将消耗在每个区域以及在各个区域间转换的时间分段,比如:
- Q2Q — 将请求发送到块层的时间
- Q2G — 从将块 I/O 排队到为其分配一个请求之间所需要的时间
- G2I — 从为其分配一个请求到将其插入设备队列之间所需时间
- Q2M — 将块 I/O 排队到将其与现有请求合并之间所需时间
- I2D — 从将请求插入设备队列到实际向该设备发出请求之间所需时间
- M2D — 从将块 I/O 与现有请求合并到向该设备发出该请求之间所需时间
- D2C — 该设备请求的服务时间
- Q2C — 为一个请求消耗在块层中的时间总量
您可以从上述表格中推断处大量有关负载的信息。例如:如果 Q2Q 比 Q2C 大很多,则意味着程序没有以快速连续法式发出请求。因此您的性能问题可能与 I/O 子系统无关。如果 D2C 很高,那么该设备服务请求的时间就很长。这可能表示该设备只是超载了(可能是由共享资源造成的),或者是因为发送给给设备的负载未经优化。如果 Q2G 很高则意味着队列中同时有大量请求。这可能代表该存储无法承担 I/O 负载。
最后,seekwatcher 消耗 blktrace 二进制数据并生成一组绘图,其中包括逻辑块地址(LBA),流量,每秒查找次数以及每秒的 I/O 量(IOPS)。
图 6.2. seekwatcher 输出结果示例
所有绘图都使用时间作为 X 轴。LBA 图用不同的颜色显示读操作和写操作。关注吞吐量与每秒查询次数图很有意思。对查询敏感的存储这两个图形是反的。如果您没有从设备中获得预期的流量,但已达到 IOPS 极限,则需要查看 IOPS 图。