简介:
系统要限定用户的某个行为在指定的时间里只能允许发生 N 次,如何使用 Redis 的数据结构来实现这个限流的功能?
固定窗口
比如我们规定我们的一个接口一分钟只能访问10次的话。使用固定窗口计数器算法的话可以这样实现:给定一个变量counter来记录处理的请求数量,当1分钟之内处理一个请求之后让counter+1,1分钟之内的如果counter=100的话,后续的请求就会被全部拒绝。
但固定窗口有一个缺点,速率不一致,无法应对激增的并发请求。比如我们限制一个接口一分钟只能访问10次的话,前半分钟一个请求没有接收,后半分钟接收了10个请求。
该窗口利用redis的string即可实现
滑动窗口
为了解决上述所说的,流量激增问题,我们需要设计一个滑动窗口。它把时间以一定比例分片。例如我们的借口限流每分钟处理60个请求,我们可以把 1 分钟分为60个窗口。每隔1秒移动一次。当滑动窗口的格子划分的越多,滑动窗口的滚动就越平滑。
这一点可以使用redis的zset实现滑动窗口。zset的value存时间戳。
实现步骤:1.zadd 指令,存当前请求的次数 2.zremrangeByScore清除时间窗口以外的请求 3.zcard获取当前key的请求。
参考:https://zhuanlan.zhihu.com/p/342597134