一、Redisson 和 RedisTemplate 有什么不同?
功能层面
Redisson:
Redisson 是一个功能强大的 Redis 客户端,封装了大量高级分布式工具,如:
- 分布式锁(支持可重入、公平锁、自旋锁、读写锁等)
- 分布式集合(List、Set、Map、Queue、BlockingQueue 等)
- 原子变量(AtomicLong、AtomicDouble)
- 分布式服务(定时调度器、远程调用等)
这些功能大大简化了我们开发分布式系统时的代码量。例如下面是使用 Redisson 实现分布式锁的方式:
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient redisson = Redisson.create(config);
RLock lock = redisson.getLock("myLock");
try {
lock.lock(); // 加锁
System.out.println("执行加锁后的业务逻辑");
} finally {
lock.unlock(); // 解锁
}
redisson.shutdown(); // 关闭客户端
Redisson 支持异步调用(如 lockAsync()
),可提升系统吞吐量,特别适合高并发场景。
RedisTemplate:
RedisTemplate 是 Spring Data Redis 提供的 Redis 操作模板,更侧重于对 Redis 基础数据类型的封装(String、Hash、List、Set、ZSet 等)。
例如操作 Hash 类型:
HashOperations<String, String, Object> hashOps = redisTemplate.opsForHash();
hashOps.put("myHash", "key", "value");
相比 Redisson,RedisTemplate 更加底层、通用,对于复杂的分布式场景(如分布式锁)通常需要开发者自己实现逻辑。
性能对比
- Redisson:功能强大但封装较重,在极端高并发或对性能极敏感的场景下可能稍有开销。但它支持异步调用,并发处理能力强。
- RedisTemplate:轻量、性能较优,更适合简单操作或对性能要求极高的应用。
使用场景
场景 | 推荐使用 |
---|---|
实现分布式锁、调度任务、远程调用等复杂分布式功能 | Redisson |
简单的缓存存储与读取(如键值操作) | RedisTemplate |
开发体验
- Redisson:API 设计合理、上手快,功能调用简单,封装程度高,适合快速开发分布式系统。
- RedisTemplate:更接近 Redis 原生操作,适合熟悉 Spring Data Redis 的开发者,灵活度高但编写量大。
社区和维护
- Redisson:独立项目,更新频繁,分布式特性支持全面。
- RedisTemplate:由 Spring 社区维护,更新节奏依赖 Spring 官方。
二、不同 Redis 部署模式下 Redisson 的使用差异
Redisson 可支持多种 Redis 部署方式:单机模式、集群模式、哨兵模式。以下是各模式的配置方式及区别:
1. 单机模式
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
适合开发测试或小型项目,配置简单但存在单点故障问题。
2. 集群模式(分片)
config.useClusterServers().addNodeAddress(
"redis://127.0.0.1:7000",
"redis://127.0.0.1:7001",
"redis://127.0.0.1:7002"
);
适合大规模高并发系统,Redisson 会自动处理节点分片和通信,提高可用性和扩展性。
3. 哨兵模式
config.useSentinelServers()
.addSentinelAddress("redis://127.0.0.1:26379")
.setMasterName("mymaster");
用于高可用场景,主节点故障时自动切换到新主节点,避免服务中断。
总结对比:
模式 | 特点 | 适用场景 |
---|---|---|
单机模式 | 简单易配置,存在单点故障 | 开发、测试 |
集群模式 | 高性能、高扩展性 | 大型业务系统 |
哨兵模式 | 自动故障转移、适中配置复杂度 | 生产环境高可用需求 |
三、RLock 对象和 lock 方法的区别
RLock lock = redisson.getLock("myLock"); // 获取锁对象
lock.lock(); // 执行加锁
区别如下:
方法 | 含义 |
---|---|
getLock | 获取一个锁对象,仅创建或查找锁,不会加锁 |
lock() | 真正发起加锁请求,与 Redis 通信,尝试获取锁,可能会阻塞 |
四、Redisson 提供的多种锁类型及使用场景
锁类型 | 方法 | 特点 | 适用场景 |
---|---|---|---|
普通可重入锁 | getLock() | 支持重入、可设置超时 | 通用分布式锁 |
自旋锁 | getSpinLock() | 获取失败会持续尝试(适合锁时间很短) | 锁竞争轻微、高并发 |
RedLock | getRedLock() | 基于多 Redis 实例,提升可靠性 | 高一致性需求场景 |
读写锁 | getReadWriteLock() | 读写互斥,读可并发 | 读多写少的缓存/数据场景 |
公平锁 | getFairLock() | 按请求顺序分配锁,避免“插队” | 排队、调度任务等 |
五、Redisson 如何设置 Redis 密码?
在生产环境中 必须设置 Redis 密码 来保障安全。
设置方法:
单机模式:
config.useSingleServer()
.setAddress("redis://127.0.0.1:6379")
.setPassword("yourPassword");
集群模式:
config.useClusterServers()
.addNodeAddress("redis://127.0.0.1:7000")
.setPassword("yourPassword");
哨兵模式:
config.useSentinelServers()
.addSentinelAddress("redis://127.0.0.1:26379")
.setMasterName("mymaster")
.setPassword("yourPassword");
六、Redisson 公平锁和非公平锁的区别
类型 | 方法 | 特点 |
---|---|---|
公平锁 | getFairLock() | 锁按照线程请求顺序分配,避免“饿死” |
非公平锁 | getLock() | 谁抢到算谁的,可能导致某些线程长期得不到锁 |
- 公平锁 适用于任务调度、排队系统。
- 非公平锁 性能更高,适合对顺序要求不严格的高并发系统。
七、安全释放 Redisson 锁的方法
问题:
当锁因过期自动释放后,如果还执行 unlock()
会报错。
正确做法:
public void releaseLock(RLock lock){
if (lock != null && lock.isHeldByCurrentThread()) {
lock.unlock();
}
}
这样可以有效避免异常,提高系统健壮性。
总结
比较项 | Redisson | RedisTemplate |
---|---|---|
封装程度 | 高,抽象出丰富的分布式工具 | 低,操作基础数据类型 |
使用门槛 | 简单,API 好用 | 偏底层,需了解 Redis 命令 |
使用场景 | 分布式系统、微服务、任务调度 | 简单缓存、数据读写 |
性能 | 较高(异步支持好) | 更轻量,适合基础场景 |
适配部署 | 支持单机、集群、哨兵 | 同样支持 |
安全性 | 支持密码设置 | 支持 |
如果你要构建一个分布式服务系统,建议使用 Redisson。如果只是做基础的缓存或对 Redis 有特定操作控制的需求,RedisTemplate 可能更合适。