#rate-limiting #redis #rate-limit #module #command #single #cell

redis-cell

一个Redis模块,提供Redis中的速率限制作为单个命令

1个不稳定版本

使用旧的Rust 2015

0.2.2 2018年7月31日

#1487 in 数据库接口

MIT 协议

68KB
1.5K SLoC

redis-cell 构建状态

一个Redis模块,提供Redis中的速率限制作为单个命令。实现了相对复杂的通用单元速率算法 (GCRA),提供滚动时间窗口且不依赖于后台滴答过程。

Redis暴露的原始操作非常适合进行速率限制工作,但由于它不是内置的,因此公司和组织通常会在Redis之上使用基本命令和Lua脚本(例如我在Heroku和Stripe都见过)实现自己的速率限制逻辑。这通常会导致一些简单的实现,可能需要多次尝试才能正确完成。redis-cell的宗旨是提供一个语言无关的速率限制器,可以轻松地集成到许多云架构中。

非正式基准测试 显示,redis-cell非常快,运行时间大约是基本Redis SET 命令的两倍以下(从Redis客户端看来大约为0.1毫秒每条命令)。

安装

关于稳定性的说明:虽然测试结果令人鼓舞,但应注意的是,redis-cell尚未在广泛的生产环境中得到验证。请谨慎使用。

redis-cell的二进制文件适用于Mac和Linux。如果有兴趣在目前不支持的平台或操作系统上获得二进制文件,请提出问题。

下载并解压缩库,然后将其移动到Redis可以访问的地方(注意,对于Mac版本,扩展名将是.dylib而不是.so

$ tar -zxf redis-cell-*.tar.gz
$ cp libredis_cell.so /path/to/modules/

或者,从源代码克隆并构建项目。为此,您需要安装Rust(如果您在Mac上,这可能就像一个brew install rust命令一样简单)。

$ git clone https://github.com/brandur/redis-cell.git
$ cd redis-cell
$ cargo build --release
$ cp target/release/libredis_cell.dylib /path/to/modules/

请注意,需要Rust 1.13.0+。

运行指向新构建模块的Redis

redis-server --loadmodule /path/to/modules/libredis_cell.so

或者,将以下内容添加到 redis.conf 文件中

loadmodule /path/to/modules/libredis_cell.so

用法

从Redis(尝试运行 redis-cli)使用模块加载的新的 CL.THROTTLE 命令。用法如下

CL.THROTTLE <key> <max_burst> <count per period> <period> [<quantity>]

其中 key 是用于速率限制的标识符。例如可能包括

  • 用户账户的唯一标识符。
  • 传入请求的原始IP地址。
  • 静态字符串(例如 global),用于限制整个系统中的操作。

例如

CL.THROTTLE user123 15 30 60 1
               ▲     ▲  ▲  ▲ ▲
               |     |  |  | └───── apply 1 token (default if omitted)
               |     |  └──┴─────── 30 tokens / 60 seconds
               |     └───────────── 15 max_burst
               └─────────────────── key "user123"

响应

这意味着应该将单个令牌(最后参数中的 1)应用于 user123 关键字的速率限制。在60秒内允许该关键字的30个令牌,最大初始突发令牌数为15。每次调用都提供速率限制参数,以便可以轻松地实时重新配置限制。

该命令将以整数数组响应

127.0.0.1:6379> CL.THROTTLE user123 15 30 60
1) (integer) 0
2) (integer) 16
3) (integer) 15
4) (integer) -1
5) (integer) 2

每个数组项的含义是

  1. 操作是否受到限制
    • 0 表示允许操作。
    • 1 表示操作受到限制/阻止。
  2. 关键字的限制总数(max_burst + 1)。这与常见的 X-RateLimit-Limit HTTP头部等效。
  3. 关键字的剩余限制。相当于 X-RateLimit-Remaining
  4. 用户应重试的秒数,如果操作被允许,则总是 -1。相当于 Retry-After
  5. 限制重置到最大容量的秒数。相当于 X-RateLimit-Reset

多个速率限制

通过使用不同的键名实现不同类型的速率限制

CL.THROTTLE user123-read-rate 15 30 60
CL.THROTTLE user123-write-rate 5 10 60

在Rust中

redis-cell是用Rust编写的,并使用语言的FFI模块与Redis自己的模块系统交互。Rust非常适合这里,因为它不需要GC,并且只需要极小的运行时即可启动。

该库的作者认为,在Rust中而不是C中编写模块将传达类似的表现特性,但结果是一个更不可能出现许多C程序中常见的错误和内存陷阱的实现。

许可证

这是一个根据MIT许可证条款提供的免费软件(有关详细信息,请参阅文件 LICENSE)。

依赖关系

~0.7–1MB
~17K SLoC