当前位置:首页 > 文章列表 > 数据库 > Redis > Redis 8.8 INCREX 怎么替代简单的 Lua 限流计数

Redis 8.8 INCREX 怎么替代简单的 Lua 限流计数

来源:17golang原创 2026-09-09 03:48:17 0浏览 收藏

如果旧的 Redis 限流脚本只是“给某个用户的计数器加 1、限制上限、设置固定窗口过期时间”,Redis 8.8 可以优先考虑 INCREX。它把计数、上限、过期和“只在新窗口设置 TTL”放进一个原子命令,返回值还会告诉你本次实际增加了多少。达到上限时默认返回实际增量 0,应用可以直接拒绝请求,不必再额外读取一次。

迁移边界很明确:单键固定窗口适合 INCREX;滑动窗口、多键联动、复杂条件和需要写入业务结果的脚本,仍然保留 Lua 或应用层编排。

要点速览
  • INCREX key BYINT 1 UBOUND 100 EX 60 ENX 可表达“60 秒最多 100 次,窗口内不续期”。
  • 返回数组的第一个元素是新值,第二个元素是实际增量;实际增量为 0 时表示这次没有拿到额度。
  • 默认越过上限会跳过更新;只有明确需要截断到边界时才使用 SATURATE

先看旧 Lua 限流到底解决了什么

经典固定窗口通常把计数和过期拆成两条命令:先对 rate:user:42 执行 INCR,第一次创建时再执行 EXPIRE,最后读取计数判断是否超过上限。问题在于,多个客户端可能在这几步之间交错,计数、TTL 和放行判断不一定处在同一个原子边界里,所以常见做法是把它们包进 Lua。

INCREX 的价值不是“所有限流都不用脚本”,而是把这个最小单键场景直接下沉到 Redis 命令。官方文档将它标为 O(1),并说明不存在的 key 会先按 0 参与计算。

用一个 INCREX 表达固定窗口限流

下面的命令表示:用户 42 在一个固定的 60 秒窗口内最多消耗 100 个整数额度;窗口第一次建立时设置 TTL,后续请求只增加计数,不把窗口重新延长。

# 每次请求消耗 1 个额度;只有新窗口才设置 60 秒 TTL
redis-cli INCREX rate:user:42 BYINT 1 UBOUND 100 EX 60 ENX

# 查看窗口剩余寿命,确认后续请求没有反复续期
redis-cli TTL rate:user:42

这里的 UBOUND 100 是上限,EX 60 是窗口长度,ENX 表示只有 key 当前没有 TTL 时才应用这次过期参数。不要把 EXENX 混为“每次都刷新 60 秒”:没有 ENX 时,每次命令都可能重设过期时间,窗口会变成滑动的“最后一次请求后 60 秒”。

Redis INCREX 将请求计数器、BYINT 增量、UBOUND 上限与 EX ENX 窗口时间域关联的静态技术框图
图1:INCREX 把额度计数、上限和窗口生命周期放在同一个原子命令边界中。

根据实际增量决定放行还是拒绝

INCREX 返回两个元素:第一个是更新后的值,第二个是实际应用的增量。比如当前值为 99,再申请 1 次,返回可以理解为 [100, 1];继续申请 1 次,默认越过上限,返回类似 [100, 0],key 和 TTL 都不变。

客户端应优先读取第二个元素,而不是仅看第一个元素。第一个元素只能说明窗口中的当前计数,第二个元素才直接回答“本次请求有没有成功占用额度”。伪代码可以写成:

# 第二个返回值代表本次真正增加的额度
new_value, actual_increment = redis_client.execute_command(
    "INCREX", "rate:user:42", "BYINT", 1,
    "UBOUND", 100, "EX", 60, "ENX"
)

# 实际增量为 0,说明已经触及上限
if actual_increment == 0:
    return reject_request("rate limit exceeded")
return allow_request(new_value)

如果业务需要一次消耗多个额度,把 BYINT 1 换成相应的整数即可;如果使用 BYFLOAT,返回值会按浮点数处理。计数 key 必须保持数值字符串,否则会收到类型或数值解析错误。

默认拒绝和 SATURATE 不是一回事

写法越过 UBOUND 时适合场景
默认模式跳过更新,返回实际增量 0,TTL 保持不变请求限流、额度扣减失败即拒绝
SATURATE把结果截到上限,返回被截断后的实际增量允许“最多累计到上限”的计量或展示值

固定窗口限流通常选择默认模式,因为“拒绝本次请求”比“把计数写到上限后再猜是否放行”更容易表达。SATURATE 只是改变越界处理,不会把命令变成滑动窗口,也不能替代业务幂等。

哪些限流场景仍然应该保留 Lua

如果一次判断只涉及一个 key、一个固定窗口和一个上限,迁移到 INCREX 通常能减少脚本维护与参数拼接。但以下情况不要为了追求“少一段 Lua”而硬迁移:

  • 多键联动:同时检查用户、IP、接口和租户四个计数器,并要求全部成功后再一起扣减。
  • 滑动窗口:需要按时间戳集合统计最近 N 秒,而不是一个固定 TTL 的计数器。
  • 业务副作用:放行后还要写入队列、记录审计字段或更新另一类 Redis 数据结构。
  • 复杂回滚:一组条件中部分成功时需要恢复多个 key 的原值。
Redis INCREX 单键固定窗口适用区与多键限额滑动窗口和业务副作用 Lua 保留区的边界分析图
图2:单键固定窗口适合 INCREX,多键规则、滑动窗口和业务副作用仍位于 Lua 或应用编排边界。

迁移前的检查清单

  1. 确认服务端实际运行 Redis 8.8 或更高版本,并在目标部署形态中检查 INCREX 是否可用。
  2. 确认原 Lua 脚本确实只有单 key 固定窗口计数,不要把多 key 业务规则误判成简单限流。
  3. 固定 key 命名、窗口长度、上限和每次消耗量,先在灰度流量下比较拒绝率与 TTL 行为。
  4. 客户端按数组解析返回值,特别测试首次创建、达到上限、窗口过期和错误类型四个分支。

相关问题

INCREX 能完全替代 Redis Lua 限流吗?

不能。它主要替代单 key 固定窗口计数这一类脚本;多 key、滑动窗口、复杂副作用仍需要 Lua 或应用层方案。

为什么要用 ENX?

ENX 让 TTL 只在没有过期时间时设置,避免每次请求都刷新窗口。固定窗口限流通常需要这个语义。

达到 UBOUND 后还会延长 TTL 吗?

默认越界会跳过操作,key 和 TTL 都保持不变;窗口自然过期后,下一次请求才会开始新窗口。

小结:把旧脚本先拆成“单 key、固定窗口、一次计数、一次上限判断”四个条件。四项都满足时,用 INCREX + UBOUND + EX + ENX 表达最直接;只要出现多键协同或时间序列统计,就保留原有脚本边界。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go private module 下载提示 404 时怎么配置 GOPRIVATEGo private module 下载提示 404 时怎么配置 GOPRIVATE
上一篇
Go private module 下载提示 404 时怎么配置 GOPRIVATE
Go io/fs.ReadFileFS 读取嵌入资源失败怎么排查
下一篇
Go io/fs.ReadFileFS 读取嵌入资源失败怎么排查
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    34次使用
  • SuperCLUE中文大模型评测基准:功能、能力维度与应用指南
    SuperCLUE
    SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
    188次使用
  • C-Eval中文评测基准:大语言模型多学科能力评估指南
    C-Eval
    深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
    127次使用
  • AI Prompt Library:免费AI提示词库,助力ChatGPT高效创作与营销
    AI Prompt Library
    探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
    50次使用
  • Generrated:DALL·E 2/3 AI绘画提示词灵感库与图像对比平台
    Generrated
    Generrated汇集9300+张DALL·E生成图像及对应提示词,支持查看完整图集、对比DALL·E 2与3版本差异,是AI绘图新手学习Prompt设计与获取创作灵感的实用工具。
    35次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码