IO流程
整个Block I/O框架可以分为三层:VFS、Block和I/O设备驱动。
一个I/O请求进入block layer之后,可能会经历下面的过程:
- Remap: 可能被DM(Device Mapper)或MD(Multiple Device, Software RAID)
remap到其它设备。 - Split: 可能会因为I/O请求与扇区边界未对齐、或者size太大而被分拆(split)成多个物理I/O。
- Merge: 可能会因为与其它I/O请求的物理位置相邻而合并(merge)成一个I/O。 被IO
Scheduler依照调度策略发送给driver。 - 被driver提交给硬件,经过HBA、电缆(光纤、网线等)、交换机(SAN或网络)、最后到达存储设备,设备完成IO请求之后再把结果发回。
blktrace 能够记录下IO所经历的各个步骤:
Q------->G------------>I--------->M------------------->D----------------------------->C
|-Q time-|-Insert time-|
|--------- merge time ------------|-merge with other IO|
|----------------scheduler time time-------------------|---driver,adapter,storagetime--|
|----------------------- await time in iostat output ------------------------------
----|
Q – 即将生成IO请求
|
G – IO请求生成
|
I – IO请求进入IO Scheduler队列
|
D – IO请求进入driver
|
C – IO请求执行完毕
IO处理阶段:
Q2Q:相邻两次进入通用块层的I/O间隔
Q2G:I/O进入block layer到I/O请求(request)生成的时间。生产IO请求耗费的时间,生成IO请求所消耗的时间,包括remap和split的时间。
G2I:I/O请求生成到被插入I/O请求队列(request queue)的时间。IO请求进行IO调取所耗费的时间,IO请求进入IO Scheduler所消耗的时间,包括merge的时间。
Q2M:I/O进入block层到该I/O被和已存在的I/O请求合并的时间
I2D:I/O请求进入request queue队到分发到设备驱动的时间。IO请求在IO调度中所耗费的时间。IO请求在IO Scheduler中等待的时间。
M2D:I/O合并成I/O请求到分发到设备驱动的时间
D2C:I/O分到到设备驱动到设备处理完成时间。IO请求在硬件设备中耗费的时间,IO请求在driver和硬件上所消耗的时间。
Q2C:整个IO请求所消耗的时间(Q2I + I2D + D2C = Q2C),相当于iostat的await。
在上述过程中,Q2M、M2D两个阶段不是必然发生的,只有可以merge的I/O才会进行合并。
如果I/O性能慢的话,以上指标有助于进一步定位缓慢发生的地方:
D2C可以作为硬件性能的指标;I2D可以作为IO Scheduler性能的指标。
blktrace的用法
使用blktrace需要挂载debugfs。由之前的blktrace工作原理可知,blktrace需要借助内核经由debugfs文件系统(debugfs文件系统在内存中)来输出信息
所以用blktrace工具之前需要先挂载debugfs文件系统
mount -t debugfs debugfs /sys/kernel/debug
或者在/etc/fstab中添加下面一行以便在开机启动的时候自动挂载
debug /sys/kernel/debug debugfs default 0 0
如果没有挂载则可能出现下面的情况:
# blktrace -d /dev/sda6 -o - | blkparse -i -
Invalid debug path /sys/kernel/debug: 0/Success
# blktrace -d /dev/sda6 -o - | blkparse -i -
Debugfs is not mounted at /sys/kernel/debug
终端输出
利用blktrace查看实时数据的方法,比如要看的硬盘是sdb:
blktrace -d /dev/sdb -o – | blkparse -i –
上面是抓取一段时间后,需要停止的时候,按Ctrl-C中止。也可以指定时间:-w
输出到终端用“-”表示,可是都是一堆二进制东西,没法看,所以需要实时blkparse来解析
Blkparse 的“-i”后加文件名,blktrace输出为“-“代表终端(代码里面写死了,就是用这个符号来代表终端),blkparse也用“-”来代表终端解析
- 第一个字段:8,0 这个字段是设备号 major device ID和minor device ID。
- 第二个字段:3 表示CPU。
- 第三个字段:11 序列号。
- 第四个字段:0.009507758 Time Stamp是时间偏移。
- 第五个字段:PID 本次IO对应的进程ID。
- 第六个字段:Event,这个字段非常重要,反映了IO进行到了那一步。
- 第七个字段:R表示 Read&