Hotdry.

Article

Redis 8.8 原生数组与内置限流器:替代 Lua 脚本的性能与原子性优化

Redis 8.8 引入原生数组结构与窗口计数器限流器,通过 INCREX 命令和 ARRING 等原子操作替代传统 Lua 脚本方案,在随机访问场景实现 5 倍性能提升,环形缓冲区操作吞吐量翻倍。

2026-06-06systems

Redis 8.8 在 2026 年 5 月正式发布,带来了两个对系统架构影响深远的新特性:原生数组(Array)数据结构与内置窗口计数器限流器(Window Counter Rate Limiter)。这两项功能直指长期以来依赖 Lua 脚本实现的典型场景 —— 稀疏索引存储与分布式限流,通过服务器端原生支持消除了脚本执行的开销与原子性隐患。

原生数组:填补 List 与 Hash 之间的结构空白

Redis 传统提供 List、Hash、Set、Sorted Set 等核心数据结构,但在特定场景下各有局限。List 擅长队列操作却难以实现 O (1) 的随机访问;Hash 支持字段级访问却需要为每个键值对维护额外的元数据开销。Array 的引入填补了这一空白。

Array 是一种索引可寻址的字符串值集合,支持从 0 到 2⁶⁴−1 的超大索引范围。与固定长度的传统数组不同,Redis Array 具有动态扩容能力,元素可在任意索引位置设置,数组会根据需要自动扩展或收缩。更重要的是,Array 支持稀疏存储—— 索引无需连续,内存占用与实际元素数量成正比,而非与最大索引相关。

在性能表现上,Array 展现出明显优势。根据官方在 Intel Sapphire Rapids m7i.metal-24xl 实例上的基准测试,在 10 万元素、1KB 值的场景下:

操作 Array List Hash
随机读取 675K ops/sec 133K ops/sec 626K ops/sec
随机写入 757K ops/sec 137K ops/sec 689K ops/sec
随机删除 841K ops/sec 730K ops/sec

Array 在随机访问场景下比 List 快 5 倍以上,相比 Hash 也有 8–15% 的吞吐优势。这一性能差距源于 List 的链表本质 —— 随机访问需要 O (n) 遍历,而 Array 与 Hash 均提供 O (1) 的索引定位能力。

环形缓冲区与服务器端聚合

Array 的另一核心能力是原生支持 ** 环形缓冲区(Ring Buffer)** 语义。传统上使用 List 实现滑动窗口需要组合 RPUSHLTRIM 两条命令,而 Array 提供单条 ARRING 命令完成相同操作。测试数据显示,ARRING 的插入吞吐量达到 1.12M ops/sec,是 List 方案(528K ops/sec)的 2.1 倍,且性能不受窗口大小影响。

对于数值型数据,Array 支持服务器端聚合计算,包括 SUMMINMAX 等统计操作,以及针对二进制标志的 ANDORXOR 布尔运算。结合环形缓冲区语义,这为实现滑动窗口实时分析提供了原子性保障 —— 传感器数据流、金融行情、日志事件等场景可在服务端完成窗口聚合,无需往返传输原始数据。

此外,Array 支持文本搜索能力,可通过精确匹配、Glob 模式或正则表达式在数组元素中查找目标内容。这使得 Array 可作为行索引的日志存储结构,每条日志占据一个索引位置,支持按行号快速访问与内容检索。

内置限流器:INCREX 替代 Lua 脚本

分布式限流是 Redis 的经典应用场景,传统实现依赖 Lua 脚本在服务器端原子执行计数与过期判断逻辑。Redis 8.8 引入的 INCREX 命令将这一能力原生内置,支持固定窗口、滑动窗口等多种限流策略。

INCREX 的设计围绕三个核心参数展开:

  • 窗口时长EX/PX):定义计数器的时间窗口
  • 容量上限UBOUND):限制窗口内的最大令牌数
  • 增量值BYINT):每次请求消耗的令牌数,默认为 1

相比传统 INCR 家族命令,INCREX 引入了三项关键能力:

  1. 双值返回:命令返回计数器新值与实际增量,调用方可立即判断是否触发限流
  2. ENX 语义:仅在 Key 不存在时设置过期时间,确保窗口生命周期不被后续请求重置
  3. 边界控制SATURATE 模式允许请求被部分接受,计数器被钳制在上限值,而非直接拒绝

这一设计消除了 Lua 脚本带来的序列化开销与脚本缓存管理复杂性,同时保证了操作的原子性。INCREX 还可视为 INCRINCRBYINCRBYFLOATDECRDECRBY 的通用化实现,通过负增量支持递减场景。

内存与适用性权衡

Array 并非在所有场景下都是最优选择。内存占用方面,在 10 万元素测试中,Array 每元素比 List 多消耗约 18% 内存(100 字节元素:122 vs 104 字节;1KB 元素:1290 vs 1035 字节),Hash 则比 List 多消耗 30–46%。

适用场景

  • 需要 O (1) 随机访问或索引范围查询
  • 滑动窗口与服务器端聚合需求
  • 基于行号的文本检索(如日志分析)

不适用场景

  • 需要频繁在头部 / 尾部插入删除(应使用 List)
  • 基于字段名的键值访问(应使用 Hash)
  • 内存极度敏感且仅需顺序遍历的场景

迁移与调优建议

对于现有基于 Lua 的限流实现,迁移至 INCREX 需关注以下参数配置:

INCREX ratelimit:user:123 EX 60 UBOUND 100 BYINT 1 SATURATE ENX

上述命令表示:60 秒窗口内允许最多 100 个请求,每次消耗 1 个令牌,超出部分被饱和处理,窗口过期时间仅在首次创建时设置。

对于 Array 的采用,建议优先评估以下指标:

  • 当前使用 List 实现滑动窗口的 QPS 是否成为瓶颈
  • 是否存在大量随机访问模式(如按用户 ID 稀疏索引的配置数据)
  • 是否需要服务器端聚合减少网络往返

监控层面,需关注 Array 的内存增长曲线与 INCREX 的拒绝率 / 饱和率指标,结合业务峰值调整窗口时长与容量配置。

结语

Redis 8.8 的原生数组与内置限流器代表了从 "脚本扩展" 向 "原生能力" 的演进方向。Array 通过索引寻址与稀疏存储提供了 List 与 Hash 之外的第三种选择,在随机访问与滑动窗口场景实现显著性能提升;INCREX 则将分布式限流这一高频需求纳入核心命令集,消除了 Lua 脚本的维护负担与潜在的原子性风险。对于需要高吞吐限流或稀疏索引存储的系统,这两项特性值得在升级计划中优先考虑。


参考来源

  • Redis 官方博客《Redis 8.8: New array data structure & open source features》(2026-05-28)
  • Redis 8.8 官方文档与命令参考

systems

内容声明:本文无广告投放、无付费植入。

如有事实性问题,欢迎发送勘误至 i@hotdrydog.com