Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
B
brpc
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
brpc
Commits
c2d34686
Unverified
Commit
c2d34686
authored
Aug 21, 2018
by
Ge Jun
Committed by
GitHub
Aug 21, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update auto_concurrency_limiter.md
parent
3dcf51d6
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
14 additions
and
11 deletions
+14
-11
auto_concurrency_limiter.md
docs/cn/auto_concurrency_limiter.md
+14
-11
No files found.
docs/cn/auto_concurrency_limiter.md
View file @
c2d34686
...
...
@@ -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和并发是反向关系。
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment