Redis 8.8:INCREX 一条命令做窗口限流,hash 字段级通知漏配 h 就收不到
项目信息
- 官方发布博客:https://redis.io/blog/announcing-redis-8-8/
- 8.8 新特性文档:https://redis.io/docs/latest/develop/whats-new/8-8/
- Release notes:https://github.com/redis/redis/releases/tag/8.8.0
- Docker 镜像:https://hub.docker.com/_/redis
- snap:https://github.com/redis/redis-snap
- brew:https://github.com/redis/homebrew-redis
- RPM:https://github.com/redis/redis-rpm
- APT:https://github.com/redis/redis-debian
Redis 8.8 已在 Redis Open Source 中正式发布。相对 8.6 的主要变化:
- 新数据结构:Array(@antirez)
- hash 字段的 subkey 通知(字段级通知)
- INCREX:窗口计数器限流器,把 INCR、INCRBY、INCRBYFLOAT、上下界和过期合并成一条原子命令
- XNACK:新的 streams 命令,允许消费者显式释放 pending 消息
- ZUNION、ZINTER、ZUNIONSTORE、ZINTERSTORE:新增 COUNT 聚合器
- JSON.SET:新增 FPHA 参数,为同构浮点数组指定 FP 类型
- TS.RANGE、TS.REVRANGE、TS.MRANGE、TS.MREVRANGE:单条命令返回多个聚合结果
- FT.HYBRID KNN 子句:新增参数限制每分片候选数
- FT.PROFILE HYBRID:为 FT.HYBRID 提供性能分析
- 性能改进
支持的操作系统:Ubuntu 22.04/24.04/26.04,Rocky Linux 8.10/9.7/10.1,AlmaLinux 8.10/9.7/10.1,Debian 12.13/13.4,Alpine 3.23,macOS 14.8.4/15.7.4/26.3(Intel 与 ARM)。
INCREX:窗口计数器限流
在 Redis 8.8 之前,实现窗口计数器限流通常要写 Lua 脚本。8.8 引入新命令:
INCREX key
[ increment]
[LBOUND lowerbound] [UBOUND upperbound] [SATURATE]
[EX sec | PX msec | EXAT unix-time-sec | PXAT unix-time-msec | PERSIST]
[ENX]
思路:每个窗口有一个时长(EX 或 PX 指定)和一个令牌容量(UBOUND 指定)。请求的令牌数用 BYINT increment 指定,默认 1。INCREX 尝试把计数器增加请求的令牌数,key 不存在就创建。
几个语义要点:
- INCREX 同时返回新的计数器值和应用后的增量,用来判断请求应放行还是拒绝。
- 带 ENX 时,只有 key 原本没有 TTL 才设置过期时间。保证窗口 TTL 只在窗口新建时设置,后续不被改动。
- SATURATE 表示饱和,即达到上界后不再增长。LBOUND / UBOUND 分别设置下界与上界。
- 相关提交:#15045。
Streams:XNACK 显式 NACK 消息
XNACK key group [SILENT|FAIL|FATAL] IDS numids id [id ...]
消费者可以显式把消息释放回 stream,使其立即可被重新投递。三种模式对应不同场景:FATAL 用于畸形、毒药或潜在恶意的消息,投递计数器会被推高,便于识别并路由到死信队列。
Hash:subkey 字段级通知
Redis 7.4 引入 hash 字段过期,采用率很高。常见后续需求是字段级通知——因为 key 级通知不带字段名。8.8 引入 subkey 级通知,从 Hash 开始,客户端可以订阅字段级事件:字段更新、删除、过期。
subkey 通知包含 key、subkeys(对 hash 就是字段名)和事件类型。
8.8 新增四种频道类型:
- Subkeyspace 通知:订阅某个具体 key,每条消息包含事件类型和字段名。
- Subkeyevent 通知:订阅某个具体事件类型,每条消息包含 key 名和字段名。
- Subkeyspaceitem 通知:订阅具体的 key+字段 组合,每条消息包含事件类型。
- Subkeyspaceevent 通知:订阅具体的事件+key 组合,每条消息包含字段名。
hash 字段会发出的事件:hset、hdel、hexpire、hexpired、hpersist、hincrby、hincrbyfloat。
这里有个容易踩的配置坑:要启用 hash 字段级通知,notify-keyspace-events 必须同时包含数据类型标志和频道类型标志。例如只执行
CONFIG SET notify-keyspace-events STIV
只开启了频道类型(S T I V),缺少最关键的 hash 数据类型标志 h,收不到通知。正确做法:
redis-cli config set notify-keyspace-events hSTIV
或启用所有常用数据类型与所有子键频道类型:
redis-cli config set notify-keyspace-events AKEhSTIV
这里的 h 不是指某种数据结构,而是表示会发出这些通知的 hash 子键事件。
新数据结构 Array
Redis 8.8 引入原生 Array 数据结构,支持 O(1) 索引读写,存储紧凑。相关提交 #15162,作者 @antirez。
Docker 启动
docker run -d \
--name redis-8.8.1 \
--restart unless-stopped \
-p 6379:6379 \
-v /opt/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf:ro \
-v /opt/redis/data:/data \
redis:8.8.1 \
redis-server /usr/local/etc/redis/redis.conf
镜像尽量用最新,别用 8.8.0。conf 里可加:
# 开启 Hash 字段级通知(需包含 K 和 h,且开启细分事件)
notify-keyspace-events "KEA"
注意:上面这行只有 K、E、A,缺少 h 时同样收不到字段级通知,按前文说明补 h 与频道标志。
其他
- ZUNION/ZINTER/ZUNIONSTORE/ZINTERSTORE 新增 COUNT 聚合器,可统计元素在输入集合中出现的次数(#14892)。
- JSON.SET 新增 FPHA 参数,显式指定同构浮点数组的内部类型(MOD-13577)。
- 时序查询单命令返回多个聚合结果(#T1916)。
- FT.HYBRID 的 KNN 子句新增 CANDIDATES_PER_SHARD,限制每分片候选向量数,降低集群开销;FT.PROFILE 支持 HYBRID 分析。
- 8.8 GA 相对 8.8-RC1 的修复:#15237 INCREX 语法更新、#15005 非集群模式可运行时开启内存跟踪、集群多分片命令期间拓扑变化未处理(MOD-14439)、RedisBloom RDB 加载内存泄漏(MOD-15418)。