聊聊RPC的拥塞控制
前言
这个话题的背景源自于Hadoop内部的底层RPC处理过程,但是笔者认为针对所有其它RPC处理场景中也会碰到类似的拥塞问题,所以可以拿出来简单讲讲。首先来解释一下这里的名词,这里的RPC拥塞指的是系统被大量的用户特定的请求堵住了,导致没办法有资源来处理其它用户的正常请求,这里我们假设请求是被扔到一个请求队列中的。这里我们姑且不讨论发起大量请求的用户操作行为是否合理,但是在这种情况下,确实使得其它RPC被堵住了。本文,我们就来讨论这个在分布式系统中经常会遇到的问题,以及对应的解决思路。
拥塞控制的解决方案
此方案思路来源于HADOOP-9640中提到的FairCallQueue的设计,更加详细的设计细节可详见此JIRA。OK,下面笔者来简单阐述下拥塞控制的解决思路。
优先级分级
我们说RPC发生拥塞现象,它实际上是一种资源请求相互影响的结果,而这个相互影响的最根本原因是我们没有对它们进行更一步的分离,而是冗余在了一起进行处理。这里首先要改进的是划分出优先级关系,每个优先级对应一个队列,比如Q0,Q1,Q3,然后定义一个规则,数字越小的,优先级越高。
队列优先级确定
队列优先级划分好之后,很重要的一个操作就是优先级的确认,在这里我们当然不会人工的设置请求的优先级,一种比较通用的,比较智能是算法是根据请求发生频率确定优先级,对于用户而言,要做的是指定这个规则,具体地来说,比如3个队列,Q1队列的请求,请求频率在0~10%之间,Q2则是10~50%,剩余50以上的为Q3队列,转变为实际数量的话,就是100个请求内,请求了50次以上的归为Q2优先级队列,10次以内的为Q0队列。重新再来看之前看到的拥塞现象,导致拥塞现象的大部分请求,就会被分到同样的队列了,从而在后续的处理中,可以减少对于其它优先级队列的影响了。
其次在这里,频率的计数统计还要考虑到时限的问题,因为频率统计是要针对在一定时间内的,比如A时段的频率不可能完全与B时段的一样,也不可能一直被延用。在这里HADOOP-9640提到了一种衰减算法,前面时段内的计数结果通过衰减因子在下一轮的计算中,占比逐步衰减,这种做法比完全清零统计要平滑许多。
队列优先级权重设置
其实各个请求被分到各个优先级队列中后,后面的处理就有很多样的玩法了。比如说,最简单的,用轮询的方式从各个队列中取出一定的批次请求。在这里,我们提到一种更加灵活的做法,在轮询的大背景下,再针对各个队列设置一个理论保障比重。比如3个优先级队列,Q0,Q1,Q2,配置权重比如9,4,1。意为在一次轮询处理中,在后面的15个请求内,保证处理掉Q0队列的9次请求,Q1的4次请求,以及Q2的一次请求。
以上就是本文分享的主要内容,大家在实际使用中可以借鉴借鉴里面的解决思路。
参考资料
[1].https://issues.apache.org/jira/browse/HADOOP-9640. RPC Congestion Control with FairCallQueue