队列深度过浅有什么影响?

来源:互联网 发布:华为端口游戏打折 编辑:程序博客网 时间:2024/04/24 16:17

队列深度过浅有什么影响?

队列是流水线的润滑剂、缓冲棉。那么如果这层过于单薄,会出现什么效应呢?如下图所示,假设当前系统运行了8个线程,其中2个线程会发出IO请求,而其他6个线程则只计算,不产生IO请求。假设当前队列深度为2,可以看到,当线程1发出了2笔IO之后,队列就满了,于是线程1无事可做了,进入休眠状态,然后线程2立即开始被调度运行,由于底层存储系统处理IO是有一定时延的,这个时延远高于线程切换的时延,所以当线程2运行的一瞬间,队列依然是满的,底层还没来得及处理队列中的IO,那么线程2发现无事可做,也进入休眠态。后续系统开始运行线程3~8,由于这几个线程只是计算而不发出IO,所以当他们运行期间,队列中积存的两笔IO早已被底层处理完毕,假设当运行到线程5的时候,就已经处理完毕,那么在线程6/7/8运行期间,队列一直为空,那么这个期间,底层存储系统就无事可做,而线程1/2还都在等待被执行从而继续发出IO,整体吞吐量低下。



再来看一下如果适当增加队列深度,情况就变了,缓冲层变厚,就能抗拒更加剧烈的波动。当线程1运行的时候,向队列中充满IO,后续当线程2~8运行期间,这些积压的IO依然没有被处理完,再次轮到线程1执行时,其又可以继续向队列中充满IO请求,这样,任何时间底层在全速运行,吞吐量发挥到最高。



可以看到一个奇特的现象:线程2永远也得不到机会向队列中充入自己的IO请求,因为每次轮到它执行,队列总是满的,因为在它之前有线程1这个IO需求大户。经过一段时间之后,线程2对应的应用就会报IO超时错误,或者资源不足错误等,导致应用宕掉。这个效应被称为IO饿死。适当增加队列深度可以在一定几率上缓解IO饿死。比如上面这个例子,当把队列深度增加到超过线程1的胃口,也就是线程1每次发送完一批IO之后,队列中依然有空余位置,就可以容纳其他线程的IO了。但是不能根治,因为无法判断任意时刻线程1到底会发多少IO出来。根治的方法还是得通过IO Scheduler调度器,先把所有进程的IO收入到子队列,让所有线程都由机会发出IO,然后再有组织有计划的向总队列中充入这些IO,比如按照Round Robin方式一人一个,或者超过一定时间没轮到某个进程的IO被充入队列,则充入一定数量等等策略。这就像在一个多车道共同向单车道汇聚的路口,如果没有交警,靠车辆自己排队,恐怕最后就会乱套,因为司机们可不管这一套,谁抢着就是谁的,新手就吃亏了。


原创粉丝点击