Redis 8.8 GA:原生 Array、窗口计数器 INCREX 与查询加速

2026-05-26 14 预计阅读时间:1 分钟
来源:oschina.net AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:8 分钟

Redis 8.8 正式 GA 了。如果你还在跑 8.6,这一版值得认真看——不是小修小补,而是核心数据结构层面的一次补位。Redis 之父 @antirez 亲自下场贡献了 Array 类型,窗口计数器 INCREX 填上了滑动窗口计数的空白,查询层也有多项提速。下面逐项拆开看。

Array:Redis 终于有了原生数组

过去在 Redis 里存一组有序元素,你能选的方案都不太舒服:List 是双端链表,中间插入 O(n);Sorted Set 按分数排序,不适合纯序号场景;用 JSON/HASH 包一层,又多了一层编解码开销。Array 直接解决了这个问题——原生、有序、支持按索引读写。

核心操作大致如下:

命令 作用
ARRAY.PUSH 尾部追加元素
ARRAY.POP 尾部弹出
ARRAY.INSERT 指定位置插入
ARRAY.RANGE 按索引范围读取
ARRAY.LEN 返回长度
ARRAY.SET 按索引覆写某位

一个典型场景:用户的消息收件箱,需要按时间顺序存储、支持分页拉取、偶尔插入一条置顶消息。

# 创建数组并追加消息
ARRAY.PUSH inbox:user:1001 "系统通知:您的订单已发货"
ARRAY.PUSH inbox:user:1001 "客服回复:退款已处理"
ARRAY.PUSH inbox:user:1001 "活动提醒:限时秒杀开始"

# 查看长度
ARRAY.LEN inbox:user:1001
# => 3

# 分页拉取最新 2 条(倒序 range)
ARRAY.RANGE inbox:user:1001 -2 -1
# => "客服回复:退款已处理"  "活动提醒:限时秒杀开始"

# 在第 0 位插入一条置顶消息
ARRAY.INSERT inbox:user:1001 0 "置顶:账户安全提醒"

# 覆写某条消息
ARRAY.SET inbox:user:1001 2 "活动提醒:秒杀已结束"

对比 List 的 LINSERT,Array 的 INSERT 在底层实现上做了优化,小规模数组中间插入的实际开销更低。如果你的有序集合长度在几百到几千这个量级、且需要按索引精准操作,Array 比 List 更合适。

注意:Array 是 8.8 新增命令,客户端库可能尚未封装,早期可直接用原始命令发送。生产上线前建议在测试环境验证内存占用与大数组操作延迟。

INCREX:滑动窗口计数,一行命令搞定

限流、风控、实时统计里最常见的需求:"过去 N 秒内发生了多少次"。以前的做法要么用 Sorted Set + 时间戳分数手动算窗口,要么靠 Lua 脚本拼凑,逻辑不复杂但每次都要写一遍。INCREX 把这件事变成了单命令操作。

基本语义:

INCREX key <timestamp> <window-size> [value]
  • timestamp:当前事件时间戳(毫秒或秒,取决于你选的精度)
  • window-size:窗口长度,同一单位
  • 可选 value:增量,默认 1

返回值是当前窗口内的累计计数。

一个实际例子——API 限流,每用户 60 秒内最多 100 次请求:

# 每次请求进来时执行
INCREX ratelimit:user:42 1720000000 60
# => 返回当前窗口累计值,比如 73

# 业务侧判断
if result > 100:
    return 429 Too Many Requests

对比传统 Sorted Set 方案:

# 旧方案:至少三步操作
ZADD ratelimit:user:42 1720000000 "req:1720000000"
ZREMRANGEBYSCORE ratelimit:user:42 -inf 1719999940
ZCARD ratelimit:user:42
# 还要定期清理过期成员,否则内存持续膨胀

INCREX 的优势很明显:一行命令,原子操作,窗口自动滑动,过期数据自动淘汰。不需要额外清理逻辑,也不需要 Lua 脚本保证原子性。

如果要做更精细的多级限流(比如同时限制每秒和每分钟),可以维护两个 key:

INCREX ratelimit:user:42:sec  1720000000 1    # 1 秒窗口
INCREX ratelimit:user:42:min  1720000000 60   # 60 秒窗口

查询优化与可观测性

8.8 在查询层做了几项务实改进:

  • 聚合查询加速:对 SUMMINMAX 等聚合操作的内部路径做了优化,大数据集下延迟明显下降。
  • 索引扫描改进:FT.SEARCH 在多条件组合查询时减少了不必要的全索引遍历,复合条件查询提速。
  • 运行时指标增强:新增了更细粒度的 INFO 字段和慢日志分类,可以区分是命令本身慢还是内部数据结构操作慢,排查性能问题不再只能靠猜。

一个快速验证查询提速的方式——用 redis-benchmark 对比 8.6 和 8.8:

# 在 8.6 和 8.8 上分别跑
redis-benchmark -h 127.0.0.1 -p 6379 -t zadd,zcard,zrange -q -c 50 -n 100000

# 对比 QPS 和平均延迟
# 8.8 在 zrange 大范围扫描上通常有 10-30% 提升(取决于数据规模)

上线前检查清单

项目 建议
客户端兼容性 确认所用客户端库已支持 ARRAY.* 和 INCREX 命令,不支持则用 raw command 发送
数据迁移 Array 是新类型,不涉及旧数据迁移,但新写入的 key 在 8.6 上无法读取,降级回滚需提前规划
内存预估 Array 在小规模时内存紧凑,万级以上需实测;INCREX 的窗口 key 过期后自动释放,内存可控
监控告警 更新 INFO 解析逻辑,关注新增的慢日志分类字段
灰度顺序 建议先在只读从库或低流量集群验证,再逐步放量到主写入节点

Redis 8.8 不是那种"改了几个默认值"的版本。Array 补上了原生有序容器的缺口,INCREX 把滑动窗口计数从手工拼装降到了单命令,查询优化让已有功能跑得更快。如果你的业务里有列表操作、限流计数、聚合查询这三类场景,8.8 的收益是直接的。


相关推荐