问题背景
今天在参与面试的时候,候选人提到了一个他们项目做的一个项目中使用的限制系统的设计。大致思路如下,通过一个配置中心去获取每台机器的配额,然后本地做限流。当时就被挑战了这个思路,如果其他机器挂了,如何快速感知?马上就没答上来了。基于这个话题,今天想来简单分析一下,一个限流系统的设计思路。
基本算法
1、先讨论最简单的场景,单台机器,用什么方式来限制流量?通常一个非常简单的做法,暂且叫它为时间哈希法。
描述如下:例如每秒100次,那我用时间戳做key, 每次请求对这个key进行自增操作,并判断这个value值是否会会大于100这个值,如果是大于,则触发限流逻辑。
存在问题:
1)如果在t=0.9s~1.0s这0.1S内,收到了100次请求,不会触发限流。如果t=1.0S到1.1S内,收到100次请求,由于是一个新的时间key,也不会触发限流,那在t=0.2S到1.2S这1S时间内,则收到了200次请求,超出了限流值。
2)或者你会想到,那我把时间粒度再切分细一些,按0.1S允许10个请求。这样又会引入另一个问题。我如果在1S内,前0.9S没有请求,最后0.1S如果来100个,那就会有90个被限制,无法应对突发流量问题。
2、令牌桶算法
这是网络中处理流控的一个经典算法。这个算法的描述参考维基百科token bucket,这里简单描述如下:
A token is added to the bucket every 1/r seconds.
The bucket can hold at the most b tokens. If a token arrives when the bucket is full, it is discarded.
When a packet (network layer PDU) of n bytes arrives,