文章目录
  1. 1. 令牌桶限流算法原理
  2. 2. 总结

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
6
127.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) 令牌桶的容量,大小为初始值+1
  • 3) 当前令牌桶中可用的令牌
  • 4) 若请求被拒绝,这个值表示多久后才令牌桶中会重新添加令牌,单位:秒,可以作为重试时间
  • 5) 表示多久后令牌桶中的令牌会存满

由于redis-Cell是基于Rust语言写的插件,因此在安装插件前要先安装rust, 具体可参看官方README github

总结
  • 从限制用户行为频率场景出发,引入redis-cell分布式限流解决方案,阐述了其算法原理及步骤,并给出实例说明;
  • 频率限制的实现有多种方式,例如NginxHaproxy都有限制模块、通过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)国际许可协议进行许可,转载请注明作者及出处, 否则保留追究法律责任的权利。

@一线攻城狮

关注微信公众号 @一线攻城狮

总访问:
总访客: