性能测试连载 (28)-简单聊聊 IO 瓶颈
https://pan.baidu.com/s/1df1HDkFzChYNAbsSazizpw 提取码:hhn7
jmeter 全系列文档资料
https://pan.baidu.com/s/1rD3H9EGbu0u11E8ofpAl3A 提取码:8q65
性能测试初级到高级系列资料
概述
在性能测试中,IO 是一个非常重要的指标。我这里整理了一部分关于 IO 的内容,用来加深自己的印象。
所谓 IO,其实就是磁盘的读写。读 IO,就是发出指令,从磁盘读取某段扇区的内容。指令首先告诉磁盘开始的扇区位置,然后给出需要从这个初始扇区往后读取的连续扇区的个数,同时会告知磁盘动作是读,还是写。磁盘收到指令之后就会按照指令的要求,读或者写数据。控制器发出指令+数据读/写,就是一次 IO。
IO 大小
IO 大小指的是指令给出的连续读取扇区数目的多少。如果数目很大,比如 128k,64k 等等,算是大块 IO,如果很小,比如 1k, 4k 等等,算是小块 IO。
注:
平均 IO 尺寸=吞吐量/IO 数目;
吞吐量/硬盘传输数据的速度:传输数据=读出数据 + 写入数据
IOPS(每秒 IO 数):一次磁盘的连续读或连续写称为一次磁盘 IO。IOPS 表示磁盘每秒连续读和连续写次数
IO 模式
连续/随机 IO
连续和随机,取决于本次 IO 的初始扇区地址,和上一次 IO 的结束扇区地址是否连续。如果是,则本次 IO 是一个连续 IO;如果不连续,算一次随机 IO。
连续 IO:因为本次初始扇区和上次结束扇区相隔很近,则磁头几乎不用换道或换道时间极短;
随机 IO:磁头需要很长的换道时间,如果随机 IO 很多,导致磁头不停换道,效率会大大降底
顺序/并发 IO
磁盘控制器每一次对磁盘组发出的指令是一条还是多条。
顺序 IO:一条指令,缓存中的 IO 队列,只能一个一个的执行,
并发 IO:控制器同时对磁盘组中的多块磁盘,同时发出指令,则每次可以执行多个 IO。并发 IO 模式提高了效率和速度
平均 IO 尺寸小于 32k,可认为磁盘 IO 模式以随机为主
平均 IO 尺寸大于 32k,则以顺序 IO 为主
缓存 IO
在 Linux 的缓存 I/O 机制中,数据先从磁盘复制到内核空间的缓存区,然后从内核空间缓存区复制到应用程序的用户空间。
读 IO:操作系统检查内核的缓存区有没有需要的数据,如果有,那么就直接从缓存中返回;否则从磁盘中读取,然后再复制到操作系统的缓存中。
写 IO:将数据从用户空间复制到内核空间的缓存中。这时对用户程序来说写 IO 就已经完成。
缓存 I/O 的优点:
1)在一定程度上分离了内核空间和用户空间,保护系统的运行安全
2)可以减少读盘的次数,从而提高系统性能。
缓存 I/O 的缺点:
在缓存 I/O 机制中,数据直接从磁盘读到缓存中,或者将数据从缓存直接写回磁盘,而不能直接在用户空间和磁盘之间进行直接的数据传输。数据会在传输过程中需要在用户空间和内核空间之间进行多次数据拷贝操作,每一次数据拷贝都需要内核和用户空间进行上下文切换,而频繁的上下文切换则会导致 cpu 和内存资源的大量消耗。
直接 IO
直接 IO 就是应用程序直接访问磁盘数据,不经过内核缓存区,这样做的目的是减少从内核缓存区到用户空间的数据拷贝次数。比如数据库这类应用更倾向于选择自身的缓存机制,因为数据库管理系统比操作系统更了解自身存放的数据。它可以提供一种更加有效的缓存机制来提高数据的存取性能。
同步/异步 IO
磁盘发出指令:把数据写入到内存中,写完之后再发出通知。这种操作叫做直接内存访问(Direct memory access),整个过程不需要 CPU 参与。这个过程中 CPU 有两个选择:等待或者去继续做其他事。前者就是同步 IO,后者就是异步 IO。
通常直接 IO 与异步 IO 组合使用,会极大提高系统性能
IO 瓶颈分析
vmstat 命令
其中关于 IO 的几个指标解释如下:
bi:读磁盘的速度,单位 KB/秒
bo:写磁盘的速度
wa:IO 的时间
瓶颈分析:
1:wa 并不能反应磁盘的瓶颈,实际反应的是 cpu 的 io 等待时间
2:bi+bo 参考值为 1000,如果超过 1000,而且 wa 值比较大,表示系统磁盘 IO 存在瓶颈
iostat 命令
rrqm/s: 每秒对该设备的读请求被合并次数,文件系统会对读取同块 (block) 的请求进行合并
wrqm/s: 每秒对该设备的写请求被合并次数
r/s: 每秒完成的读次数
w/s: 每秒完成的写次数
rkB/s: 每秒读数据量 (kB 为单位)
wkB/s: 每秒写数据量 (kB 为单位)
avgrq-sz:平均每次 IO 操作的数据量 (扇区数为单位)
avgqu-sz: 是平均请求队列的长度。队列长度越短越好
await: 平均每次 IO 请求等待时间 (包括等待时间和处理时间,毫秒为单位)。一般地系统 IO 响应时间应该低于 5ms
svctm: 平均每次 IO 请求的处理时间 (毫秒为单位)
%util: 1 秒中有百分之多少的时间用于 I/O 操作。该参数表示了设备的繁忙程度
瓶颈分析:
1:CPU 会拿出一部分时间来等待 IO(iowait)。如果磁盘的利用率已经满了(util%),即使 CPU 使用率不高,但是系统整体 QPS 已经上不去了,如果继续加大流量,会导致单次 iowait 持续增加(IO 请求都堵在队列里),从而使整体性能塌方。
2:高 iowait 并不代表磁盘的瓶颈。唯一能说明磁盘是系统瓶颈的方法是很高的 svctm(IO 请求的处理时间),一般来说超过 20ms,就代表了不太正常的磁盘性能。只要大于 20ms,就必须考虑是否磁盘读写的次数太多,导致磁盘性能降低。
3:svctm 一般要小于 await。svctm 的大小和磁盘性能有关,请求过多也会导致 svctm 的增加。await 的大小一般取决于 svctm 以及 I/O 队列的长度。如果 svctm 接近 await,说明 I/O 几乎没有等待时间;如果 await 远大于 svctm,说明 I/O 队列太长,应用的响应时间变慢,如果响应时间超过了用户可以容许的范围,需要考虑更换更快的磁盘;调整内核 elevator 算法;优化应用;升级 CPU
举例形容 IO
超市排队付款
1:首先看排的队人数,5 个人比 20 人要快
2:看前面人购买的东西多少,如果前面的人购买了一个月的物品,可以考虑换个队伍排
3:看收银员的速度,如果碰上了新手,那等待时间会很久
与 IO 的对比:
r/s+w/s 类似于排队的人员总数
平均队列长度 (avgqu-sz) 相当于单位时间里平均排队的人数
平均服务时间 (svctm) 相当于收银员的收款速度
平均等待时间 (await) 相当于平均每人的等待时间
平均 I/O 数据 (avgrq-sz) 相当于平均每人所买的东西多少
I/O 操作率 (%util) 相当于收款台前有人排队的时间比例
经验总结
1:提高 IO 效率原则: 顺序写,随机读
2:重点监控 rkB/s 和 和 wkB/s
3:%util 接近 100%,说明产生的 I/O 请求太多,I/O 系统已经满负荷,该磁盘可能存在瓶颈
4:await 与 svctm 相差很大的时候,要注意磁盘的 IO 性能。差值越小,说明队列时间越短,反之则队列时间越长。说明系统出了问题。
规避 IO 负载过高:
- 如果服务器用来做日志分析,注意随机读和顺序写,避免定期的压缩、解压大日志。
- 如果是前端应用服务器,要避免程序频繁打本地日志、或者异常日志
- 如果是存储服务(mysql、nosql),尽量将服务部署在单独的节点上,做读写分离降低压力
IO 调度器选择
cat /sys/block/sda/queue/scheduler
括号中的就是默认的 IO 调度器
echo noop > /sys/block/sdb/queue/scheduler
修改调度器