redis专题08 redis分布式限流之redis-cell
  热度 °
redis4.0
以后开始支持扩展模块,redis-cell
是一个用rust
语言编写的基于令牌桶算法
的的限流模块,提供原子性的限流功能,并允许突发流量,可以很方便的应用于分布式环境中。
令牌桶限流算法原理
令牌桶算法的原理是定义一个按一定速率产生token
的桶,每次去桶中申请token
,若桶中没有足够的token
则申请失败,否则成功。在请求不多的情况下,桶中的token
基本会饱和,此时若流量激增,并不会马上拒绝请求,所以这种算法允许一定的流量激增。
1.定义一个令牌桶1
2
3
4
5令牌桶其拥有几个关键属性为,
桶容量
令牌产生速率
当前桶中令牌数
最近一次取(生成)令牌时间
2.从桶中申请令牌,这一步中有两个关键动作
根据上一次生成令牌时间到现在的时间,及生成速率计算出当前令牌桶中的令牌数
判断令牌桶中是否有足够的令牌,并返回结果
这几个步骤可以采用redis
提供的原生命令去实现,但是高并发的时候数据会不一致,所以redis-cell
将这个过程原子化,完美解决了分布式环境下数据的一致性问题。
redis-cell
模块只提供了一个命令cl.throttle
示例1
127.0.0.1:6379>cl.throttle test 100 500 20 1
参数依次说明
test
表示redis key
100
官方叫·max_burst·,其值为令牌桶的容量-1
, 首次执行时令牌桶会默认填满500
与下一个参数一起,表示在指定时间窗口内允许访问的次数20
指定的时间窗口,单位:秒1
表示本次要申请的令牌数,不写则默认为1
以上命令表示从一个初始值为100的令牌桶中取1个令牌,该令牌桶的速率限制为500次/20秒。
结果示例1
2
3
4
5
6127.0.0.1:6379> CL.THROTTLE test 100 500 20 1
1) (integer) 0
2) (integer) 101
3) (integer) 98
4) (integer) -1
5) (integer) 0
1)
是否成功,0:成功,1:拒绝2)
令牌桶的容量,大小为初始值+13)
当前令牌桶中可用的令牌4)
若请求被拒绝,这个值表示多久后才令牌桶中会重新添加令牌,单位:秒,可以作为重试时间5)
表示多久后令牌桶中的令牌会存满
由于
redis-Cell
是基于Rust语言写的插件,因此在安装插件前要先安装rust, 具体可参看官方README github
总结
- 从限制用户行为频率场景出发,引入
redis-cell
分布式限流解决方案,阐述了其算法原理及步骤,并给出实例说明; - 频率限制的实现有多种方式,例如
Nginx
和Haproxy
都有限制模块、通过Redis来实现也是常见的方式之一; - 除了引入
redis-cell
分布式限流模块, 也可以将上述令牌通的实现思路通过Lua
脚本实现,然后嵌入到redis
中执行, 实际上在redis
还不支持redis-cell
模块时, 实际使用场景中大多采用redis+lua
方式来实现限流策略; - 将
redis-cell
限流应用于微服务接口访问频次上也灰常方便;
作者署名:朴实的一线攻城狮
本文标题:redis专题08 redis分布式限流之redis-cell
本文出处:http://researchlab.github.io/2018/10/05/redis-08-redis-cell/
版权声明:本文由Lee Hong创作和发表,采用署名(BY)-非商业性使用(NC)-相同方式共享(SA)国际许可协议进行许可,转载请注明作者及出处, 否则保留追究法律责任的权利。