INCR 是什么
自增命令把字符串值当作六十四位整数做原子加减,并返回运算后的新值,计数、库存、限流、发号这类场景都用它。所谓原子,是指读取旧值、计算、写回整个过程在服务端一次完成,多个客户端并发调用不会丢更新——这正是它比应用层先读再写可靠的原因。小数的自增另有命令,但内部按浮点处理,会带累积误差。
基本信息
| 用途 | 字符串值的原子加减 |
|---|---|
| 语法 | 自增 键 / 自减 键 / 按量自增 键 增量 / 按量自减 键 减量 / 小数自增 键 增量 |
| 返回值 | 运算后的新值 |
| 取值范围 | 六十四位有符号整数,超出直接报错 |
| 键不存在 | 当作零处理,自增后得到一 |
| 典型用途 | 计数、库存、限流窗口、序列发号 |
典型使用场景
- 页面访问量与接口调用量计数
- 接口限流:按时间窗口累加请求次数并设置过期
- 库存扣减:把扣减做成原子操作避免超卖
- 生成每日流水号或递增序号
- 统计在线人数、任务完成数这类增量指标
- 幂等控制:按业务键自增并用首次返回结果判断
示例
示例
SET pv 0 # 先设初值,避免语义歧义
INCR pv # 返回 1
INCRBY pv 100 # 返回 101
DECRBY pv 1 # 返回 100
INCRBYFLOAT price 19.9 # 返回带小数的结果
INCR api:limit:1001:2026101212 # 限流窗口计数
EXPIRE api:limit:1001:2026101212 70 # 给窗口键设置过期,避免永久驻留限流写法要点
限流写法要点
# 先自增拿到当前窗口计数
INCR api:limit:1001:2026101212
# 返回值等于 1 说明是本窗口第一条,这时才设置过期
EXPIRE api:limit:1001:2026101212 70
# 返回值超过阈值即拒绝请求,窗口键靠过期自动回收命令与约束
| 命令 | 作用 | 注意 |
|---|---|---|
| 自增 / 自减 | 加一或减一 | 键不存在时按零处理 |
| 按量自增 / 自减 | 按指定整数加减 | 增量为负等价于减 |
| 小数自增 | 按小数加减 | 浮点累积误差,金额场景慎用 |
| 取值范围 | 六十四位有符号整数 | 超出范围直接报错 |
| 非数字值 | 对非数字字符串自增会报错 | 写键前先确认值确实为数字 |
| 返回值 | 运算后的新值 | 限流可用返回值判断窗口首条 |
| 过期设置 | 与自增分成两条命令 | 尽量保证同一窗口只设置一次过期 |
值不是数字或超出六十四位整数范围时命令直接报错;自增前建议先设置初值,或在业务层做容错初始化。
对不存在的键自增会按零开始,第一次结果看着符合预期,但如果业务期望的是「新用户首次访问」这类语义,需要另外标记,不能只看自增结果。
小数自增内部按浮点处理,多次累加会带误差;金额相关计数应改用最小整数单位累加,再在展示层做转换。
计数器使用清单
- 明确初值语义,必要时先写入初值
- 计数键要有过期或归档策略,避免无限增长
- 限流场景把窗口写进键名,靠过期回收
- 超出单机承载的计数要考虑分片或按维度拆分
- 关键计数不能只依赖内存,需要持久化或对账机制
- 关注热键问题:少数键承载全部流量会打爆单个分片
计数结果在故障切换或实例重启后是否保留,取决于持久化配置:对账类业务要确认持久化策略,或者把计数同时落到可靠存储里做二次校验。