redis的incr/decr是生产环境最常用可靠的计数器方案,因其原子性免锁、自动初始化、支持过期管理;需注意数值范围、浮点精度、生命周期及string与hash选型差异。

适合,而且是生产环境里最常用、最可靠的计数器方案之一。
INCR 和 DECR 的原子性是关键
Redis 的 INCR 和 DECR 命令天然原子,不需要加锁或事务就能保证并发安全。这点和数据库自增字段或应用层 synchronized 完全不同——它在服务端一次完成读+写+返回,中间不会被其他请求打断。
- 如果 key 不存在,
INCR会先初始化为0再 +1,不用提前SET - 值必须能转成 64 位有符号整数,超出范围(±9223372036854775807)会报错
(error) ERR value is not an integer or out of range - 不支持浮点数自增,要用
INCRBYFLOAT,但注意精度问题(底层用 double 存储)
计数器生命周期管理容易被忽略
很多线上 bug 来自“只增不设过期”,导致 key 永久存在、内存持续上涨。尤其像接口调用量、临时统计类指标,必须搭配过期时间。
Redis 8.2.3 是一款安全优先的高性能键值存储系统。该版本紧急修复了可能引发远程代码执行(RCE)的高危漏洞(CVE-2025-62507),并解决了 HyperLogLog 及 Cuckoo Filter 等数据结构在特定场景下的崩溃问题。建议所有用户立即升级,以保障生产环境的系统稳定与数据安全。
- 推荐用
INCR+EXPIRE组合,比如INCR api_count_192.168.1.100后立刻EXPIRE api_count_192.168.1.100 60 - 避免用
SETEX初始化,因为SETEX是“设置并设过期”,但后续INCR不会延续过期时间,得额外维护 - 如果用 Spring 的
StringRedisTemplate,opsForValue().increment()返回的是 Long,但不会自动续期,过期逻辑得自己补
和 Hash 类型计数器的取舍
单个指标用 String 没问题;但多个关联字段(比如用户维度的 followCount、fanCount、articleCount)更适合用 Hash。
- String:每个 key 单独存一个数,查/增/删都快,适合全局唯一指标(如总访问量、订单号生成)
- Hash:一个 key 下多个 field,节省 key 数量,网络传输更省,适合对象聚合计数(如
user_statistic:1001下存多个统计项) - 注意:
HINCRBY也是原子的,但 field 名拼写错误或大小写不一致会导致新 field 被悄悄创建,排查困难
真正难的不是怎么写 INCR,而是想清楚这个计数要不要持久化、要不要归零、要不要按时间窗口滚动——这些业务逻辑决定了你该用 String 还是 ZSet,或者是否要加消息队列兜底。










