概述

在性能测试中,IO是一个非常重要的指标。我这里整理了一部分关于IO的内容,用来加深自己的印象。
所谓IO,其实就是磁盘的读写。读IO,就是发出指令,从磁盘读取某段扇区的内容。指令首先告诉磁盘开始的扇区位置,然后给出需要从这个初始扇区往后读取的连续扇区的个数,同时会告知磁盘动作是读,还是写。磁盘收到指令之后就会按照指令的要求,读或者写数据。控制器发出指令+数据读/写,就是一次IO。

iostat 磁盘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。

iostat 磁盘io使用率_数据_02

 

 

通常直接IO与异步IO组合使用,会极大提高系统性能

IO瓶颈分析

vmstat 命令

 

iostat 磁盘io使用率_数据_03

 

其中关于IO的几个指标解释如下:
bi:读磁盘的速度,单位 KB/秒
bo:写磁盘的速度
wa:IO的时间
瓶颈分析:
1:wa并不能反应磁盘的瓶颈,实际反应的是cpu的io等待时间
2:bi+bo 参考值为 1000,如果超过 1000,而且 wa 值比较大,表示系统磁盘 IO存在瓶颈

 

iostat命令

 

iostat 磁盘io使用率_iostat 磁盘io使用率_04

 

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负载过高:

  1. 如果服务器用来做日志分析,注意随机读和顺序写,避免定期的压缩、解压大日志。
  2. 如果是前端应用服务器,要避免程序频繁打本地日志、或者异常日志
  3. 如果是存储服务(mysql、nosql),尽量将服务部署在单独的节点上,做读写分离降低压力

IO调度器选择

cat /sys/block/sda/queue/scheduler
括号中的就是默认的IO调度器

iostat 磁盘io使用率_用户空间_05

 

 

echo noop > /sys/block/sdb/queue/scheduler
修改调度器

iostat 磁盘io使用率_用户空间_06