Browse Source

Update auto_concurrency_limiter.md

Ge Jun 5 years ago
parent
commit
c2d34686cf
1 changed files with 14 additions and 11 deletions
  1. 14 11
      docs/cn/auto_concurrency_limiter.md

+ 14 - 11
docs/cn/auto_concurrency_limiter.md

@@ -35,13 +35,15 @@ server.MaxConcurrencyOf("example.EchoService.Echo") = "auto";
 ### 名词
 **concurrency**: 同时处理的请求数,又被称为“并发度”。
 
-**max_concurrency**: 允许的最大concurrency,又被称为“最大并发度”。并发的物理含义是任务处理槽位,天然具有上限。当超过最大并发时,任务将无法被及时处理而被缓存在各种队列中,系统也会进入拥塞状态
+**max_concurrency**: 设置的最大并发度。超过并发的请求会被拒绝(返回ELIMIT错误),在集群层面,client应重试到另一台server上去
 
-**noload_latency**: 单纯处理任务的延时,不包括排队时间。另一种解释是负载近零的延时。由于任务处理要耗费cpu和等待网络延时,noload_latency天然具有下限。
+**best_max_concurrency**: 并发的物理含义是任务处理槽位,天然存在上限,这个上限就是best_max_concurrency。若max_concurrency设置的过大,则concurrency可能大于best_max_concurrency,任务将无法被及时处理而暂存在各种队列中排队,系统也会进入拥塞状态。若max_concurrency设置的过小,则concurrency总是会小于best_max_concurrency,限制系统达到本可以达到的更高吞吐。
+
+**noload_latency**: 单纯处理任务的延时,不包括排队时间。另一种解释是低负载的延时。由于正确处理任务得经历必要的环节,其中会耗费cpu或等待下游返回,noload_latency是一个服务固有的属性。
 
 **min_latency**: 实际测定的latency中的较小值的ema,当并发度没有高于最大并发度时,min_latency和noload_latency接近。
 
-**peak_qps**: 极限qps。注意是处理或回复的qps而不是接收的qps。上限取决于max_concurrency / noload_latency,由于max_concurrency具有上限,noload_latency具有下限,qps天然有上限,和拥塞状况无关。
+**peak_qps**: 极限qps。注意是处理或回复的qps而不是接收的qps。上限取决于best_max_concurrency / noload_latency,这两个量都是服务的固有属性,故peak_qps也是服务的固有属性,和拥塞状况无关。
 
 **max_qps**: 实际测定的qps中的较大值。无论拥塞与否,max_qps都和peak_qps接近。
 
@@ -50,11 +52,11 @@ server.MaxConcurrencyOf("example.EchoService.Echo") = "auto";
 
 当服务没有超载时,随着流量的上升,latency基本稳定(接近noload_latency),qps和concurrency呈线性关系一起上升。
 
-当流量超过服务的极限qps时,则concurrency和latency会一起上升,而qps会稳定在极限qps。
+当流量超过服务的peak_qps时,则concurrency和latency会一起上升,而qps会稳定在peak_qps。
 
-假如一个服务的peak_qps和noload_latency都比较稳定,那么它的最佳max_concurrency = noload_latency * peak_qps。
+假如一个服务的peak_qps和noload_latency都比较稳定,那么它的best_max_concurrency = noload_latency * peak_qps。
 
-自适应限流就是要找到服务的noload_latency和peak_qps, 并将最大并发设置为靠近 noload_latency * peak_qps的一个值。
+自适应限流就是要找到服务的noload_latency和peak_qps, 并将最大并发设置为靠近两者乘积的一个值。
 
 ### 计算公式
 
@@ -70,7 +72,7 @@ max_qps是最近一段时间测量到的qps的极大值。
 
 min_latency是最近一段时间测量到的latency较小值的ema,是noload_latency的估算值。
 
-当服务处于低负载时,min_latency约等于noload_latency,此时计算出来的max_concurrency会高于实际并发,但低于真实并发,给流量上涨留探索空间。而当服务过载时,服务的qps约等于max_qps,同时latency开始明显超过min_latency,此时max_concurrency则会接近或小于实际并发,并通过定期衰减避免远离真实并发,保证服务不会过载。
+当服务处于低负载时,min_latency约等于noload_latency,此时计算出来的max_concurrency会高于concurrency,但低于best_max_concurrency,给流量上涨留探索空间。而当服务过载时,服务的qps约等于max_qps,同时latency开始明显超过min_latency,此时max_concurrency则会接近concurrency,并通过定期衰减避免远离best_max_concurrency,保证服务不会过载。
 
 
 ### 估算noload_latency
@@ -86,7 +88,7 @@ min_latency是最近一段时间测量到的latency较小值的ema,是noload_l
 
 方案3的问题在于,假如服务的性能瓶颈在下游服务,那么请求在服务本身的排队等待时间无法反应整体的负载情况。
 
-方案4是最通用的,也经过了大量实验的考验。缩小max_concurrency和公式中的alpha存在关联。让我们做个假想实验,若latency极为稳定并都等于min_latency,那么公式简化为max_concurrency = max_qps * latency * (1 + alpha)。根据little's law,qps最多为max_qps * (1 + alpha). alpha是qps的"探索空间",若alpha为0,则qps被锁定为max_qps,算法可能无法探索到”极限qps“。但在qps已经达到极限qps时,alpha会使延时上升(已拥塞),此时测定的min_latency会大于noload_latency,一轮轮下去最终会导致min_latency不收敛。定期降低max_concurrency就是阻止这个过程,并给min_latency下降提供”探索空间“
+方案4是最通用的,也经过了大量实验的考验。缩小max_concurrency和公式中的alpha存在关联。让我们做个假想实验,若latency极为稳定并都等于min_latency,那么公式简化为max_concurrency = max_qps * latency * (1 + alpha)。根据little's law,qps最多为max_qps * (1 + alpha). alpha是qps的"探索空间",若alpha为0,则qps被锁定为max_qps,算法可能无法探索到peak_qps。但在qps已经达到peak_qps时,alpha会使延时上升(已拥塞),此时测定的min_latency会大于noload_latency,一轮轮下去最终会导致min_latency不收敛。定期降低max_concurrency就是阻止这个过程,并给min_latency下降提供"探索空间"
 
 #### 减少重测时的流量损失
 
@@ -141,10 +143,11 @@ else:
 
 netflix中的gradient算法公式为:max_concurrency = min_latency / latency * max_concurrency + queue_size。
 
-其中latency是采样窗口的最小latency,min_latency是最近多个采样窗口的最小latency。min_latency / latency就是算法中的“梯度”,当latency大于min_latency时,max_concurrency会逐渐减少;反之,max_concurrency会逐渐上升,从而让max_concurrency围绕在真实的最大并发附近。
+其中latency是采样窗口的最小latency,min_latency是最近多个采样窗口的最小latency。min_latency / latency就是算法中的"梯度",当latency大于min_latency时,max_concurrency会逐渐减少;反之,max_concurrency会逐渐上升,从而让max_concurrency围绕在best_max_concurrency附近。
 
 这个公式可以和本文的算法进行类比:
 
-* gradient算法中的latency和本算法的不同,前者的latency是最小值,后者是平均值。netflix的原意是最小值能更好地代表noload_latency,但实际上只要不对max_concurrency做定期衰减,不管最小值还是平均值都有可能不断上升使得算法不收敛。最小值并不能带来额外的好处,反而会使算法更不稳定。
-* gradient算法中的max_concurrency / latency从概念上和qps有关联(根据little's law),但可能严重脱节。比如在min_latency重置前,若所有latency都小于min_latency,那么max_concurrency会不断下降甚至到0;但按照本算法,max_qps和min_latency仍然是稳定的,它们计算出的max_concurrency也不会剧烈变动。究其本质,gradient算法在迭代max_concurrency时,latency并不能代表实际并发为max_concurrency时的延时,两者是脱节的,所以max_concurrency / latency的实际物理含义不明,与qps可能差异甚大,最后导致了很大的偏差。
+* gradient算法中的latency和本算法的不同,前者的latency是最小值,后者是平均值。netflix的原意是最小值能更好地代表noload_latency,但实际上只要不对max_concurrency做定期衰减,不管最小值还是平均值都有可能不断上升使算法不收敛。最小值并不能带来额外的好处,反而会使算法更不稳定。
+* gradient算法中的max_concurrency / latency从概念上和qps有关联(根据little's law),但可能严重脱节。比如在重测
+min_latency前,若所有latency都小于min_latency,那么max_concurrency会不断下降甚至到0;但按照本算法,max_qps和min_latency仍然是稳定的,它们计算出的max_concurrency也不会剧烈变动。究其本质,gradient算法在迭代max_concurrency时,latency并不能代表实际并发为max_concurrency时的延时,两者是脱节的,所以max_concurrency / latency的实际物理含义不明,与qps可能差异甚大,最后导致了很大的偏差。
 * gradient算法的queue_size推荐为sqrt(max_concurrency),这是不合理的。netflix对queue_size的理解大概是代表各种不可控环节的缓存,比如socket里的,和并发度存在一定的正向关系情有可原。但在我们的理解中,这部分queue_size作用微乎其微,没有或用常量即可。我们关注的queue_size是给concurrency上升留出的探索空间: max_concurrency的更新是有延迟的,在并发从低到高的增长过程中,queue_size的作用就是在max_concurrency更新前不限制qps上升。而当concurrency高时,服务可能已经过载了,queue_size就应该小一点,防止进一步恶化延时。这里的queue_size和并发是反向关系。