Redis原理及实践之分布式限流

1. 分布式限流

  • Redis + Lua : Redis进行每秒请求计数(Redis计数器功能),达到限流目的。其中,Redis key的设置精确到秒,并且需要对该key设置过期时间为2秒。
-- lua脚本保证redis组合操作的原子性
--lua 下标从 1 开始
-- 限流 key
local key = KEYS[1]
-- 限流大小
local limit = tonumber(ARGV[1])

-- 获取当前流量大小
local curentLimit = tonumber(redis.call('get', key) or "0")

if curentLimit + 1 > limit then
    -- 达到限流大小 返回
    return 0;
else
    -- 没有达到阈值 value + 1
    redis.call("INCRBY", key, 1)
    redis.call("EXPIRE", key, 2)
    return curentLimit + 1
end
  • Redis-Cell
    Redis 4.0提供了一个限流Redis模块,称为Redis-Cell。该模块使用了漏斗算法,并提供了原子的限流指定。
    cl.throttle命令介绍:
> cl.throttle laoqian:reply 15 30 60 1
                      ▲     ▲  ▲  ▲  ▲
                      |     |  |  |  └───── need 1 quota (可选参数,默认值也是1)
                      |     |  └──┴─────── 30 operations / 60 seconds 这是漏水速率
                      |     └───────────── 15 capacity 这是漏斗容量
                      └─────────────────── key laoqian...

// 执行cr.throttle命令返回结果含义如下所示
> cl.throttle laoqian:reply 15 30 60
1) (integer) 0   # 0 表示允许,1表示拒绝
2) (integer) 15  # 漏斗容量capacity
3) (integer) 14  # 漏斗剩余空间left_quota
4) (integer) -1  # 如果拒绝了,需要多长时间后再试(漏斗有空间了,单位秒)
5) (integer) 2   # 多长时间后,漏斗完全空出来(left_quota==capacity,单位秒)

其中,上述参数代表的含义是每60s最多允许30次操作,且初始时刻允许15个并发操作。在该命令执行被拒绝时,可以采用同步阻塞或异步定时方式进行重试。

你可能感兴趣的:(Redis原理及实践之分布式限流)