探秘I/O队列对磁盘性能的影响

Zhang_Jiawen
4 Beryllium

探秘I/O队列对磁盘性能的影响

探秘I/O队列对磁盘性能的影响

转载请在文首保留原文出处:EMC中文支持论坛https://community.emc.com/go/chinese

介绍

信息传输过程中数据通常暂存于磁盘队列。实验表明,随着服务器性能的不断提高,磁盘I/O队列常常成为影响磁盘响应速度的首要瓶颈。本文以AIX系统为例,描述了I/O队列在磁盘中的工作原理、监测命令,以及如何对其进行优化以提升磁盘性能。

使用I/O队列的意义:

为何要对磁盘I/O进行并行处理呢?主要目的是提升应用程序的性能。这一点对于多物理磁盘组成的虚拟磁盘(或LUN)显得尤为重要。如果一次提交一个I/O,虽然响应时间较短,但系统的吞吐量很小。相比较而言,一次提交多个I/O既缩短了磁头移动距离(通过电梯算法),同时也能够提升IOPS。假如一部电梯一次只能搭乘一人,那么每个人一但乘上电梯,就能快速达到目的地(响应时间),但需要耗费较长的等待时间(队列长度)。因此一次向磁盘系统提交多个I/O能够平衡吞吐量和整体响应时间。


理论上,磁盘的IOPS取决于队列长度÷平均IO响应时间。假设队列长度为3,平均IO响应时间是10ms,则最大吞吐量是300 IOPS

IO队列位于何处:

AIX系统为例,从应用层到磁盘物理层的IO堆栈如下所示,IO按照从上至下的顺序遍历堆栈:

  • 应用程序层
  • 文件系统层(可选)
  • LVM设备驱动层(可选)
  • SDDSDDPCM或其他多路径驱动层(如果使用)
  • hdisk设备驱动层
  • adapter设备驱动层
  • 磁盘接口层
  • 磁盘子系统层
  • 磁盘层


AIX在每一层堆栈都会监测IO,因此堆栈的每一层都有IO队列。通常,如果当前各层执行的IO超过了队列长度所限制的最大数量,这些IO将暂存于等待队列中,直至获取申请资源。在文件系统层,文件系统缓存限制了各文件系统的最大可执行IO数量。LVM设备驱动层,可执行的最大IO数量受hdisk缓存的限制。在SDD层,如果dpo设备的qdepth_enable属性设置成yes,则会建立IO队列,但也有些版本无法设置队列。SDDPCM在将IO发送至磁盘设备驱动层之前没有进行队列处理。hdisk通过queue_depth参数设置最大响应IO数量, 而FC适配层的参数为num_cmd_elems。磁盘子系统层有IO队列,单块物理磁盘可接收多个IO请求但一次只能处理一个IO。

IO队列监测命令:

AIX为例,AIX 5.3及以上版本,可用iostatsar –d命令监测hdisk队列,iostat -D命令输出如下:

hdisk6 xfer: %tm_act bps tps bread bwrtn
4.7 2.2M 19.0 0.0 2.2M
read: rps avgserv minserv maxserv timeouts fails
0.0 0.0 0.0 0.0 0 0
write: wps avgserv minserv maxserv timeouts fails
19.0 38.9 1.1 190.2 0 0
queue: avgtime mintime maxtime avgwqsz avgsqsz sqfull
15.0 0.0 83.7 0.0 0.0 136


这里,avgwqsz是平均等待队列长度,avgsqsz是平均响应队列长度。在等待队列中花费的平均等待时间是avgtimesqfull值代表每秒钟向已满队列提交的IO数。对于有cache的磁盘子系统,IO响应时间会有所不同。iostat –D命令显示的是系统从启动后的统计数据。


从应用程序的角度来看,处理IO的总时间是响应时间加上在hdisk等待队列中的时间。

sar –d命令输出如下:

16:50:59     device    %busy    avque    r+w/s    Kbs/s   avwait   avserv
16:51:00     hdisk1      0      0.0        0        0      0.0      0.0
                    hdisk0      0      0.0        0        0      0.0      0.0

avwaitavserv分别是花费在等待队列和响应队列的时间,avqueAIX 5.3以上版本中,代表等待队列中的平均IO数量。

优化方法:

首先,不应盲目增加以上队列参数值。这样有可能造成磁盘子系统过载或在启动时引起设备配置报错。因此,仅增加hdisk的queue_depths值并不是最好的方法,而应该同时调整可提交最大IO数量。当queue_depths和发送至磁盘子系统的IO数量同时增加时,IO响应时间可能会增加,但同时吞吐量也得到了提升。当IO响应时间接近磁盘超时时间,则说明所提交IO超过了磁盘能够处理的界限。如果看到IO超时并在错误日志中报出IO无法完成,说明可能有硬件问题,或需要缩短队列。


调整queue_depths的一条法则是:对于随机读写或队列未满的情况,如果IO响应时间超过15ms,就不能再增加queue_depths值。一旦IO响应时间增加,瓶颈就从磁盘和adapter队列转移至磁盘子系统。调整队列长度应依据:1)实际应用程序产生的IO请求数,2)使用测试工具以观察磁盘子系统的处理能力。其中,1)为主要依据。


IO队列有以下四种状态:

  1. 队列已满,IO等在hdiskadapter驱动层
  2. 队列未满,IO响应时间短
  3. 队列未满,IO响应时间长
  4. 队列未满,IO提交速度快于存储处理速度并导致IO丢失


我们需要把队列调整为23的状态。情况3表明瓶颈不在hdisk驱动层,而很有可能在磁盘子系统自身,也有可能位于adapter驱动层或SAN


4种情况是应该避免的。受限于存储IO请求和数据的内存大小,所有磁盘和磁盘子系统都有IO执行数量的限制。当存储丢失IO时,主机端超时,IO将被重新提交,同时等待该IO的事件将被暂停。CPU为了处理IO多做了很多事情,这种情况应该避免。如果IO最终失败,将会导致应用程序崩溃或更严重的结果。所以必须仔细确认存储的处理极限。

合理的平均IO响应时间:

假设队列中没有IO,一次读操作将会占据015ms,取决于寻址时间,磁盘转速,以及数据传输时间。之后数据从存储移动至主机。有时数据位于磁盘读缓存,这种情况下IO响应时间约为1ms。对于大型磁盘系统在正常工作状态下,平均IO响应时间约为5-10ms。当随机读取小数据耗时超过15ms时,表明存储较为繁忙。


写操作通常将数据写入cache中,平均耗时不到2.5ms。但是也有例外:如果存储同步将数据镜像至远端,写操作将耗费更长时间。如果写入数据量较大(多于64KB)则数据传输时间会显著增加。没有cache的情况下,写时间的读时间差不多。


如果IO是大块顺序读写,除了传输时间较长,IO会暂存于磁盘物理层队列,IO响应时间远高于平均值。例如:应用提交50IO(5064KB顺序读),最初几个IO会获得较快的响应时间,而最后一个IO必须等待其他49个完成,从而耗费很长的响应时间。

参考

https://community.emc.com/docs/DOC-18970

https://community.emc.com/thread/129131

https://community.emc.com/thread/145929

应用于

UNIX系统

AIX系统

             

评论
Zhang_Jiawen

道理看似简单,监测命令比较实用。

liulei_it

太好了

Zhang_Jiawen

大家一起切磋讨论哈

版本历史
修订号
1 / 1
上次更新时间:
‎10-24-2013 11:49 PM
更新依据: