帮助中心/最新通知

质量为本、客户为根、勇于拼搏、务实创新

< 返回文章列表

【服务器相关】使用Redis实现令牌桶算法原理解析

发表时间:2025-09-24 16:09:00 小编:主机乐-Yutio

在限流算法中有一种令牌桶算法,该算法可以应对短暂的突发流量,这对于现实环境中流量不怎么均匀的情况特别有用,不会频繁的触发限流,对调用方比较友好。

例如,当前限制10qps,大多数情况下不会超过此数量,但偶尔会达到30qps,然后很快就会恢复正常,假设这种突发流量不会对系统稳定性产生影响,我们可以在一定程度上允许这种瞬时突发流量,从而为用户带来更好的可用性体验。这就是使用令牌桶算法的地方。

令牌桶算法原理

如下图所示,该算法的基本原理是:有一个容量为X的令牌桶,每Y单位时间内将Z个令牌放入该桶。如果桶中的令牌数量超过X,那么它将被丢弃。处理请求时,需要先从令牌桶中取出令牌,如果拿到了令牌,则继续处理;如果拿不到令牌,则拒绝请求。

可以看出,在令牌桶算法中设置X,Y和Z的数量尤为重要。Z应该比每Y单位时间内的请求数稍大,系统将长时间处于此状态;X是系统允许的瞬时最大请求数,并且系统不应该长时间处于此状态,否则就会频繁触发限流,此时表明流量出现了超预期的情况,需要及时调查原因并采取相应措施。

Redis实现令牌桶算法

之前看过有些程序实现的令牌桶,其向桶中放入令牌的方法是启动一个线程,每隔Y单位时间增加一次令牌数量,或者在Timer中定时执行这一过程。我不太满意这种方法, 原因有二,一是浪费线程资源,二是因为调度的问题执行时间不精确。

这里确定令牌桶中令牌数量的方法是通过计算得出,首先算出从上次请求到这次请求经过了多长时间,是否达到发令牌的时间阈值,然后增加的令牌数是多少,这些令牌能够放到桶中的是多少。

Talk is cheap!

下边就来看看Redis中怎么实现的,因为涉及到多次与Redis的交互,这里为了提高限流处理的吞吐量,减少程序与Redis的交互次数,采用了Redis支持的Lua script,Lua script的执行是原子的,所以也不用担心出现脏数据的问题。

代码节选自 FireflySoft.RateLimit ,它不仅支持普通主从部署Redis,还支持集群Redis,所以吞吐量可以通过水平扩展的方式进行提升。为了方便阅读,这里增加一些注释,实际是没有的。

普适性:原则上可以满足任何需要限流的场景。

Github开源地址:https://github.com/bosima/FireflySoft.RateLimit/blob/master/README.zh-CN.md

到此这篇关于使用Redis实现令牌桶算法的文章就介绍到这了,更多相关Redis令牌桶算法内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


联系我们
返回顶部