RedisTemplate 和 Redisson 怎么选:缓存 API、分布式锁和 Redlock 边界

4次阅读
没有评论

Java 项目接 Redis 时,经常会同时看到 RedisTemplate、StringRedisTemplate、Jedis、Lettuce、Redisson。它们名字都像客户端,但定位不同。用错倒不一定马上出事故,却会让序列化、锁、连接池和排障变得混乱。

我的理解是:RedisTemplate 管“怎么存取 Redis 数据”,Redisson 管“多实例之间怎么借 Redis 协作”。

RedisTemplate 解决普通读写

RedisTemplate 是 Spring Data Redis 提供的模板 API。它把 Redis 命令封装成几类操作:

  • opsForValue
  • opsForHash
  • opsForList
  • opsForSet
  • opsForZSet

它底层依赖 RedisConnectionFactory,连接实现可以是 Lettuce,也可以是 Jedis。Template 自己不直接代表某个网络客户端,它更多是 Spring 风格的命令封装和序列化入口。

普通缓存、简单 KV、Hash、List、计数器、过期时间,这类场景用 RedisTemplate 或 StringRedisTemplate 就够了。

StringRedisTemplate 为什么常用

StringRedisTemplate 可以理解成 RedisTemplate<String, String>。它默认 key 和 value 都按字符串序列化,和 redis-cli 里看到的内容最接近。

很多线上问题来自序列化不一致:

  • key 用了 JDK 序列化,redis-cli 看到乱码。
  • value 原来是 JDK 序列化,后来改 JSON,旧数据读不出来。
  • JSON 里带类型信息,跨语言读取困难。
  • Long、Integer、String 混用导致反序列化类型异常。

所以如果只是存简单字符串、ID、状态、计数,StringRedisTemplate 更直接。复杂对象再明确选择 JSON 序列化,并把 key serializer 和 value serializer 分开配置。

RedisTemplate 的坑主要在序列化

RedisTemplate 默认序列化如果没配好,很容易留下长期包袱。

几个建议:

  1. key 尽量用 String 序列化。
  2. value 不要随意在 JDK 序列化和 JSON 之间切换。
  3. 对象结构变化要考虑旧数据兼容。
  4. ID、编号、状态这类数据能用字符串就别存复杂对象。
  5. 不要把超大对象塞进 Redis。

如果 Jackson 报 UnrecognizedPropertyException,不只要看字段,还要看 getter。某些 getXxx() 方法即使没有真实字段,也可能被识别成 JSON 属性。

Redisson 解决分布式协作

Redisson 是另一类东西。它也是 Redis 客户端,但重点不是简单命令封装,而是分布式对象和协调能力。

常见能力包括:

  • RLock:分布式锁。
  • RMap:分布式 Map。
  • RQueue:队列。
  • RDelayedQueue:延迟队列。
  • RRateLimiter:限流器。
  • RSemaphore:信号量。
  • RBloomFilter:布隆过滤器。

如果只是 get/set,上 Redisson 反而显得重。如果要可重入锁、自动续期、延迟队列、限流等能力,Redisson 会省很多自写 Lua 和边界处理。

Redis 分布式锁的基本要求

自己写 Redis 锁时,至少要满足:

  1. 加锁必须原子:set key value nx px timeout
  2. value 必须是唯一随机值,标识锁归属。
  3. 解锁必须校验 value 后删除,避免删掉别人的锁。
  4. 锁必须有过期时间,避免进程挂掉后永远不释放。
  5. 业务执行时间不能长期超过锁过期时间。

错误写法是先 setnx 再单独 expire。如果中间进程挂了,锁可能没有过期时间。

解锁也不能直接 del key,要用 Lua 保证“比较 value + 删除”是原子的。

Redisson 的看门狗机制

Redisson 的 RLock 有一个常被提到的能力:watchdog 自动续期。

如果加锁时没有指定固定 lease time,业务线程还活着,Redisson 会周期性延长锁过期时间,避免业务还没执行完锁就过期。

这能降低误释放风险,但也不是万能的。比如:

  • 业务线程卡死。
  • JVM 长时间 Stop The World。
  • Redis 网络抖动。
  • 主从切换丢数据。

锁的正确性不能只靠客户端续期,还要看业务是否支持幂等、超时和补偿。

Redlock 要谨慎表达

Redlock 是 Redis 作者提出的一种多节点锁算法,用多个独立 Redis 实例提高锁安全性。但它在分布式系统语义上有争议,尤其在网络分区、时钟漂移、暂停等情况下。

工程里可以这样判断:

  • 普通防重复提交、低风险任务:单 Redis 锁加唯一 value、Lua 解锁通常够用。
  • 资金、库存、强一致核心链路:不要只依赖 Redis 锁,要结合数据库约束、状态机、幂等表或更强一致组件。
  • 多机房强一致:需要重新审视架构,不要把 Redlock 当万能答案。

分布式锁是降低并发冲突概率和控制入口,不是替代数据一致性的最终防线。

怎么选

简单选择规则:

  • 普通缓存读写:StringRedisTemplate。
  • 复杂对象缓存:配置明确的 RedisTemplate。
  • Spring Cache:RedisCacheManager。
  • 分布式锁、延迟队列、限流:Redisson。
  • 强一致状态变更:数据库约束和事务优先,Redis 锁只能辅助。

最后记一句:Template 管数据访问,Redisson 管分布式协作。先分清目标,再选工具。

正文完
 0
bdspAdmin
版权声明:本站原创文章,由 bdspAdmin 于2026-06-30发表,共计2207字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)