IO队列深度max_queue_depth对系统性能的影响

时间:2021-10-10 04:44:20

前段时间,发生了一个问题引起了我对IO队列深度的研究。

存储服务器中linux kernel的mpt2sas驱动模块,将max_queue_depth设置为1024时,引起系统加载驱动时卡死,而调整为512则没问题。

后来看了很多这方面的资料,终于弄明白了。

我们为了追求系统的性能,往往将max_queue_depth设置的很大。但是并不是越大对性能越有帮助。

以下内容全部出自转载,我偷下懒!

(1)

探秘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设备驱动层(可选)
  • SDD或SDDPCM或其他多路径驱动层(如果使用)
  • 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及以上版本,可用iostat和sar –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是平均响应队列长度。在等待队列中花费的平均等待时间是avgtime。sqfull值代表每秒钟向已满队列提交的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

avwait和avserv分别是花费在等待队列和响应队列的时间,avque在AIX 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等在hdisk或adapter驱动层
  2. 队列未满,IO响应时间短
  3. 队列未满,IO响应时间长
  4. 队列未满,IO提交速度快于存储处理速度并导致IO丢失

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

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

合理的平均IO响应时间:

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

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

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

(2)

queue_depth参数介绍及调整步骤

2011-08-25 10:01:30|  分类: AIX |举报 |字号 订阅

 
queue_depth参数大小    

AIX环境中,正确设置FAStT 逻辑磁盘的队列深度(queue_depth)对系统性能非常重要。
对于较大的FAStT配置,有许多卷和主机连接,这个设置对高可靠性来讲就更加关键。队列深度太大会导致文件系统的丢失或主机死机。下面介绍了如何正确设
置磁盘的队列深度及其计算方法。

我们可以使用如下的公式来决定最大的队列深度:

512 / (主机数 * 每个主机的LUN数 )

例如一个系统有4个主机, 每个有 32 LUNs (这是每个AIX主机的最大LUN数), 那么最大队列深度应该是4:

512 / ( 4 * 32 ) = 4

这时,你应该把hdiskX 的queue_depth 属性设为如下:

#chdev -l hdiskX -a queue_depth=4 -P

X代表相对应的磁盘号。

可以使用iostat -D查看

其中sqfull表示自系统启动以来queue_deeth超出的次数

IBM工程师建议queue_depth的值在40-128之间

如何设置:

queue_depth参数会影响disk i/o性能,特别是在数据库等i/o密集性应用中。适当调整设置此参数,会提高整体应用的性能。下面是在AIX 5.3,IBM ds4300上调整此参数的步骤及注意事项,记录一下。
下面物理磁盘hdisk2是基于IBM存储上的,做的raid 5,此盘属于vg datavg中。
一,首先备份datavg.在生产环境作任何调整,一定要切记安全第一,备份是必不可少的。
 #smit savevg
二,查看所需修改的hdisk2上queue_depth的值。
 #lsattr -El hdisk2|grep queue_depth
三,首先umount datavg上的文件系统。
 #umount /u2
 四,vary off vg。
 #varyoffvg datavg
 五,删除磁盘hdisk2.
 #rmdev -l hdisk2
 六,修改磁盘hdisk2 queue_depth参数.
#chdev -l hdisk2 -a queue_depth=16(此值为所需修改的具体queue_depth值) -P
 七,增加磁盘hdisk2.
 #mkdev -l hdisk2
 八,vary on vg.
 #varyonvg datavg
 九,mount datavg上文件系统
 #mount /u2
十,最后查看一下queue_depth参数是否修改成功。
 #lsattr -El hdisk2|grep queue_depth
如上面查看queue_depth值已变成所需值,则整个过程完成。如有条件,最好能重?一下机器。应注意的是此值如设置不合理,可能会导致系统hang住,或死机现象。

本人曾亲自踫到由于此值设置过大,导致系统出现异常,init进程始终占用cpu在20%左右,syscal长期在200k以上,waitqueue值也很高,严重影响了系统性能。因此,要注意此值调整以后应注意监测一段时间,直到调整到一个合适值。
 
引文地址:
http://www.360doc.com/content/10/1112/10/2245786_68687833.shtml