当前位置:首页 > 文章列表 > 数据库 > Redis > Redis 8.8 INCREX 怎么做窗口限流:计数、上限和过期一次核对

Redis 8.8 INCREX 怎么做窗口限流:计数、上限和过期一次核对

来源:17golang原创 2026-07-21 11:42:03 0浏览 收藏

做登录接口每分钟100次的限流时,常规的老写法一般是先给Redis做计数累加,再单独给键设置过期时间。这两个操作中间一旦出现异常断开,或者刚好插进来并发请求,限流窗口就可能丢失TTL,后续的请求根本没法确认自己有没有正确拿到配额。Redis 8.8 的 INCREX 直接把计数校验、配额上限判断和过期时间设置整合成一个原子操作,刚好补上了这段很容易出bug的空隙。

要点速览
  • INCREX 从 Redis 开源版 8.8.0 开始正式提供,时间复杂度为 O(1)。
  • UBOUND 100 遇到第101次超限请求时会返回实际增量0,默认不会让计数突破预先设置的上限。
  • EX 60 ENX 只会在当前新窗口没有TTL的时候设置60秒过期,后续进来的请求不会反复重置续期时间。
  • 旧版本的Redis不识别这条命令,要提前保留Lua脚本或者“计数+过期原子封装”的兼容兜底路径。

Redis 8.8 为什么新增 INCREX

传统的固定窗口限流逻辑至少要走 INCREXPIRE 两个步骤。第一次请求创建计数键,第二步再设置窗口过期;如果客户端两步之间直接断开,或者多个客户端同时判断“这是个新键”,就会出现键没有过期时间、限流窗口被无限制拉长等问题。把这段逻辑塞进Lua脚本可以保证原子性,但每个项目都得单独维护脚本、参数传递规则和返回值约定,额外的维护成本不低。

INCREX 是Redis 8.8新增的原生命令,除了常规的累加增量之外,还支持直接设置 EXPXEXAT 或者 PXAT,在同一次请求操作里就能给计数加上上下边界限制。它会返回两个值:更新后的新计数、实际生效的增量,返回结果可以直接拿来判断“放行还是拦截”,不用再多做额外判断。

Redis 8.8 INCREX 窗口限流的请求、计数、UBOUND 检查与放行链路

60秒窗口限流的最小写法

下面的示例把用户ID拼进限流键名,实现每个用户60秒内最多放行100次的规则。先清理测试用的旧键,再分别观察首次请求、计数满额之后的返回结果。

redis-cli DEL ratelimit:user-42
redis-cli INCREX ratelimit:user-42 BYINT 1 UBOUND 100 EX 60 ENX
redis-cli TTL ratelimit:user-42
redis-cli INCREX ratelimit:user-42 BYINT 1 UBOUND 100 EX 60 ENX

第一次调用会创建全新的计数键,典型返回是 11;键的剩余TTL会非常接近60秒。同一个窗口内再次调用,计数会正常累加但TTL不会被重置回60秒。等到计数涨到100之后,下一次调用会直接返回当前计数值和 0,应用层拿到这个结果就可以直接返回HTTP 429限流响应。

1) (integer) 1
2) (integer) 1
1) (integer) 60
2) (integer) 0

这里的 ENX 参数非常关键:它要求只有在键当前不存在过期时间的时候才写入TTL。要是漏掉这个参数,每次请求都可能重新覆盖写入窗口过期时间,原本的固定窗口就会变成“最后一次请求结束后再等60秒”的类滑动窗口效果,完全不符合固定限流的预期。

UBOUND、SATURATE 和实际增量怎么选

不带 SATURATE 参数的时候,请求越过 UBOUND 上限的操作会被直接拒绝,键的计数值和原有TTL都保持不变,返回的实际增量是0。这是限流场景最常用的行为,上层调用方只需要判断第二个返回值是不是大于0就能知道有没有拿到配额。

如果业务侧希望计数值最多停在设定的上限,不要把越界的操作直接当成失败,就可以加上 SATURATE

redis-cli SET quota:team-a 99
redis-cli INCREX quota:team-a BYINT 5 UBOUND 100 SATURATE
redis-cli GET quota:team-a

执行结果会直接把值封顶到100,返回的实际增量是1。这个选项更适合“累计消耗不超过总预算”这类场景,不能直接拿来判断请求有没有拿到本次的限流名额;常规限流场景还是建议保留默认的越界拒绝语义更稳妥。

选项用途边界行为
UBOUND设置计数值上限越过边界默认不改写键值,实际增量返回0
LBOUND设置计数值下限适合带负增量调整的余额或者配额扣减场景
SATURATE对数值执行封顶或封底返回截断之后实际生效的增量
ENX只给新建窗口设置TTL键已经有TTL的时候不会做续期操作

从 INCR 加 EXPIRE 迁移时要留意什么

第一个要过的门槛是服务端版本校验。INCREX 从Redis开源版8.8.0开始提供,正式升级之前可以先执行下面的命令确认目标实例能不能正常识别这条命令:

redis-cli COMMAND INFO INCREX
redis-cli INFO server | grep redis_version

生产环境如果还有7.x或者更早版本的实例,不要直接把新命令全量下发到所有节点。可以先在客户端侧按实例版本做分支选择:8.8版本走 INCREX ... UBOUND ... EX ... ENX 新命令,旧版本继续用之前已经跑稳了的Lua原子脚本。灰度观察阶段重点关注限流命中率、429响应数量、限流键的TTL分布,以及有没有出现“命令不存在”的报错。

第二个要注意的门槛是客户端返回值解析。很多官方客户端暂时没有给这条新命令封装专属方法,需要用通用自定义命令的接口调用,再把返回的数组拆成两个单独的数值字段。不要只取返回的第一个计数字段做判断,不然计数满100之后很容易把“当前值是100”误判成“本次请求成功拿到配额”。

Redis INCR 加 EXPIRE 与 Redis 8.8 INCREX 的原子窗口限流对照

上线前的四个检查点

  • 键名要带上稳定的业务限流维度,比如 ratelimit:user-42,不要把所有用户的请求都统计到同一个公共键里。
  • 窗口时长要和业务对外公示的规则对齐,EX 60 是从第一次请求进入时开始计时,不是按自然整分钟的起点对齐。
  • 逻辑里要明确判断只有第二个返回值大于0的时候才放行,返回0的时候直接映射成明确的限流响应。
  • Redis集群版本和所用客户端都要确认支持8.8新命令,仍在运行旧版本的节点要提前准备好可回退的兼容路径。

常见问题

INCREX 和 INCRBY、EXPIRE 有什么区别?

INCRBY 只负责修改计数值,EXPIRE 单独负责操作TTL,两个命令组合使用需要额外做原子性封装;INCREX 在一次原生命令里就能完成计数累加、边界判断和过期设置三个动作。

为什么窗口限流要加 ENX?

没有加 ENX 参数的话,每次请求都可能重新写入过期时间,导致限流窗口不断向后移动。ENX 可以保证TTL只有在窗口第一次创建的时候才会被写入。

返回的第二个数字为 0 代表什么?

一般代表请求越过了预先设置的上下边界,计数值没有被实际修改。固定窗口限流的场景下,这个返回值就是“本次没有拿到可用配额”的直接信号。

Redis 7 能使用 INCREX 吗?

不能直接使用。Redis 7 要继续用已经验证过的兼容实现,在客户端侧提前根据服务端版本或者能力探测的结果自动选择对应执行路径即可。

最后的落地判断

如果线上服务已经在运行Redis 8.8,做固定窗口限流可以优先用 INCREX + UBOUND + EX + ENX 这组最小参数组合:单命令原子操作、O(1)复杂度、直接返回实际增量,代码里的放行判断逻辑也会更清晰简洁。要是环境还跑在旧版本上,先保留之前已经验证稳定的原子脚本,等灰度确认好客户端返回解析逻辑和核心监控指标之后再逐步切换就行。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
PHP Webhook 如何防重放攻击:签名时间窗、nonce 与幂等记录的完整流程PHP Webhook 如何防重放攻击:签名时间窗、nonce 与幂等记录的完整流程
上一篇
PHP Webhook 如何防重放攻击:签名时间窗、nonce 与幂等记录的完整流程
MySQL JSON 字段怎么给列表筛选提速:生成列、索引与 NULL 边界
下一篇
MySQL JSON 字段怎么给列表筛选提速:生成列、索引与 NULL 边界
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之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测试功能,助您快速选择最适合项目的高性能大语言模型。
    61次使用
  • SuperCLUE中文大模型评测基准:功能、能力维度与应用指南
    SuperCLUE
    SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
    213次使用
  • C-Eval中文评测基准:大语言模型多学科能力评估指南
    C-Eval
    深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
    144次使用
  • AI Prompt Library:免费AI提示词库,助力ChatGPT高效创作与营销
    AI Prompt Library
    探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
    77次使用
  • Generrated:DALL·E 2/3 AI绘画提示词灵感库与图像对比平台
    Generrated
    Generrated汇集9300+张DALL·E生成图像及对应提示词,支持查看完整图集、对比DALL·E 2与3版本差异,是AI绘图新手学习Prompt设计与获取创作灵感的实用工具。
    55次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码