1个不稳定版本
使用旧的Rust 2015
0.2.2 | 2018年7月31日 |
---|
#1487 in 数据库接口
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
每个数组项的含义是
- 操作是否受到限制
0
表示允许操作。1
表示操作受到限制/阻止。
- 关键字的限制总数(
max_burst
+ 1)。这与常见的X-RateLimit-Limit
HTTP头部等效。 - 关键字的剩余限制。相当于
X-RateLimit-Remaining
。 - 用户应重试的秒数,如果操作被允许,则总是
-1
。相当于Retry-After
。 - 限制重置到最大容量的秒数。相当于
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