学习优化, 理解 IO 还是很重要的, 今天抽空整理了一下这块内容, 下面一起看看吧~
概述
学习优化, 理解 IO 还是很重要的, 今天抽空整理了一下这块内容, 下面一起看看吧~
下面这张经典的图源自 Linux Performance and Tuning Guidelines.PDF
各种 IO 监视工具在 Linux IO 体系结构中的位置
1 , 系统级 IO 监控
- 1.1,iostat
- iostat -xdm 1 # 个人习惯
%util 代表磁盘繁忙程度. 100% 表示磁盘繁忙, 0% 表示磁盘空闲. 但是注意, 磁盘繁忙不代表磁盘 (带宽) 利用率高
argrq-sz 提交给驱动层的 IO 请求大小, 一般不小于 4K, 不大于 max(readahead_kb, max_sectors_kb)
可用于判断当前的 IO 模式, 一般情况下, 尤其是磁盘繁忙时, 越大代表顺序, 越小代表随机
svctm 一次 IO 请求的服务时间, 对于单块盘, 完全随机读时, 基本在 7ms 左右, 既寻道 + 旋转延迟时间
1.2, 各统计量之间关系
%util = ( r/s + w/s) * svctm / 1000 # 队列长度 = 到达率 * 平均服务时间 avgrq-sz = ( rMB/s + wMB/s) * 2048 / (r/s + w/s) # 2048 为 1M / 512
1.3, 总结
iostat 统计的是通用块层经过合并 (rrqm/s, wrqm/s) 后, 直接向设备提交的 IO 数据, 可以反映系统整体的 IO 状况, 但是有以下 2 个缺点:
距离业务层比较遥远, 跟代码中的 write,read 不对应(由于系统预读 + pagecache + IO 调度算法等因素, 也很难对应)
是系统级, 没办法精确到进程, 比如只能告诉你现在磁盘很忙, 但是没办法告诉你是谁在忙, 在忙什么?
2 , 进程级 IO 监控
2.1, iotop 和 pidstat (仅 rhel6u 系列)
iotop 顾名思义, io 版的 top
pidstat 顾名思义, 统计进程 (pid) 的 stat, 进程的 stat 自然包括进程的 IO 状况
这两个命令, 都可以按进程统计 IO 状况, 因此可以知道:
1)当前系统哪些进程在占用 IO, 百分比是多少?
2)占用 IO 的进程是在读? 还是在写? 读写量是多少?
pidstat 参数很多, 介绍几个比较常用的:
pidstat -d 1 #只显示 IO
pidstat -u -r -d -t 1 # -d IO 信息, # -r 缺页及内存信息 # -u CPU 使用率 # -t 以线程为统计单位 # 1 1 秒统计一次
iotop, 很简单, 直接敲命令
2.2,block_dump, iodump
iotop 和 pidstat 都依赖于 / proc/pid/io 文件导出的统计信息, 这个对于老一些的内核是没有的, 比如 rhel5u2.
因此只好用以上 2 个命令来替代:
echo 1 > /proc/sys/vm/block_dump # 开启 block_dump, 此时会把 io 信息输入到 dmesg 中 # dmesg watch -n 1 "dmesg -c | grep -oP"w+(d+): (WRITE|READ)"| sort | uniq -c"
# 不停的 dmesg -c echo 0 > /proc/sys/vm/block_dump # 不用时关闭
2.3, 总结
从进程级 IO 监控 , 可以看出:
系统级 IO 监控不能回答的 2 个问题
距离业务层相对较近(例如, 可以统计进程的读写量)
但是也没有办法跟业务层的 read,write 联系在一起, 同时颗粒度较粗, 没有办法知道当前进程读写了哪些文件? 耗时? 大小 ?
3, 业务级 IO 监控
3.1,ioprofile
ioprofile 命令本质上是 lsof + strace,
ioprofile 可以解决以下三个问题:
当前进程某时间内, 在业务层面读写了哪些文件(read, write)?
读写次数是多少?(read, write 的调用次数)
读写数据量多少?(read, write 的 byte 数)
3.2, 实例
假设某个行为会触发程序一次 IO 动作, 例如: "一个页面点击, 导致后台读取 A,B,C 文件"
./io_event # 假设模拟一次 IO 行为, 读取 A 文件一次, B 文件 500 次, C 文件 500 次 ioprofile -p `pidof io_event` -c count # 读写次数
ioprofile -p `pidof io_event` -c times # 读写耗时
ioprofile -p `pidof io_event` -c sizes # 读写大小
注: ioprofile 仅支持多线程程序, 对单线程程序不支持. 对于单线程程序的 IO 业务级分析, strace 足以.
3.3, 总结
ioprofile 本质上是 strace, 因此可以看到 read,write 的调用轨迹, 可以做业务层的 io 分析.
4 , 文件级 IO 监控
文件级 IO 监控可以配合 / 补充 "业务级和进程级"IO 分析
文件级 IO 分析, 主要针对单个文件, 查看当前哪些进程正在对某个文件进行读写操作.
lsof 或者 ls /proc/pid/fd
inodewatch.stp 4.1,lsof
查看当前文件由哪些进程打开
lsof ../io # io 目录 当前由 bash 和 lsof 两个进程打开
lsof 命令 只能查看静态的信息, 并且 "打开" 并不一定 "读取", 对于 cat ,echo 这样的命令, 打开和读取都是瞬间的, lsof 很难捕捉
4.2,inodewatch.stp
可以用 inodewatch.stp 来弥补
stap inodewatch.stp major minor inode # 主设备号, 辅设备号, 文件 inode 节点号 stap inodewatch.stp 0xfd 0x00 523170 # 主设备号, 辅设备号, inode 号, 可以通过 stat 命令获得
来源: http://os.51cto.com/art/201906/597475.htm