redis string类型通过incr/incrby命令实现原子性自增,自动处理键初始化与类型校验,结合expire或lua脚本可支持周期性计数器,java中需用stringredistemplate配合setifabsent规避空值异常。

直接用 INCR 实现 +1 自增
这是最基础也最常用的计数方式。Redis 会自动处理键不存在的情况:
- 若 key 不存在,Redis 先将其设为 "0",再执行 +1,返回 1;
- 若 key 已存在且值为合法整数(如 "123"),则解析后 +1,返回新值;
- 若 key 存在但值不是整数(如 "hello"),命令会报错(
(error) ERR value is not an integer or out of range)。
命令示例:
127.0.0.1:6379> INCR page:views:home<br>(integer) 1<br>127.0.0.1:6379> INCR page:views:home<br>(integer) 2
用 INCRBY 控制步长和正负增减
当需要非单位变化时(比如一次加 5、减 3),用 INCRBY key increment 更灵活:
-
INCRBY counter 5→ 加 5; -
INCRBY counter -3→ 减 3(等价于 DECRBY counter 3); - 同样兼容键初始化:key 不存在时先设为 0,再运算。
Java 中用 StringRedisTemplate 安全自增
Spring 生态下推荐使用 StringRedisTemplate,但要注意空值风险:
- 直接调用
opsForValue().increment(key, 1)可能抛出IllegalArgumentException: Cannot increment a null value; - 稳妥做法是先确保 key 初始化为 "0":
stringRedisTemplate.opsForValue().setIfAbsent(key, "0");stringRedisTemplate.opsForValue().increment(key, 1); - 也可用
increment(key, 0)读取当前值(不变更),用于校验或兜底。
配合过期时间实现周期性计数器
很多业务需要“每日/每小时重置”的计数器(如日活、限流窗口),可组合 EXPIRE:
- 每次自增后设置 TTL:
redis.incr("daily:login:count");redis.expire("daily:login:count", 24, TimeUnit.HOURS); - 注意:TTL 需在每次 incr 后重新设置(因为 incr 不会刷新过期时间),否则可能因 key 持久存在导致数据累积;
- 更健壮的做法是用 Lua 脚本将 incr + expire 封装为原子操作,避免竞态。











