Redis 分布式锁的几种实现方式
是的,Redis 实现分布式锁确实有多种方式,不仅仅是 Redisson,还有 Jedis、Lettuce 等都可以实现,下面我来详细说明各种实现方式、对比及推荐:
✅ 一、Redis 分布式锁的几种实现方式
|
实现方式 |
框架/工具 |
特点 |
推荐度 |
|---|---|---|---|
|
1️⃣ 原生方式 |
手动用 Jedis / Lettuce 操作 Redis |
自定义 SET NX PX 实现锁逻辑 |
⭐⭐⭐(适合学习或轻量应用) |
|
2️⃣ Redisson |
高级封装,支持可重入锁、红锁、信号量等 |
功能强大,易于集成 Spring Boot |
⭐⭐⭐⭐⭐(企业级推荐) |
|
3️⃣ Spring Data Redis |
使用 StringRedisTemplate 手动实现锁 |
和 Spring 集成紧密,需自行管理续期 |
⭐⭐⭐ |
|
4️⃣ RedLock |
Redis 作者提出的分布式锁算法,用于 Redis 多节点环境 |
容错强、适合跨数据中心,但实现较复杂 |
⭐⭐⭐⭐(重要场景才需) |
✅ 二、各方式具体示例
1. ✅ 原生手动实现(适合 Jedis / Lettuce)
// 加锁
String lockKey = "lock:test";
String requestId = UUID.randomUUID().toString();
String result = jedis.set(lockKey, requestId, "NX", "PX", 30000);
if ("OK".equals(result)) {
// 加锁成功
}
// 解锁(确保是当前线程持有锁)
if (requestId.equals(jedis.get(lockKey))) {
jedis.del(lockKey);
}
缺点:不支持可重入、不自动续期、可能死锁。
2. ✅ Redisson(推荐)
RLock lock = redissonClient.getLock("myLock");
try {
lock.lock(); // 默认30秒自动续期,支持可重入
// 执行业务逻辑
} finally {
lock.unlock(); // 解锁
}
配置简单,支持:
-
可重入锁
-
公平锁
-
红锁(RedLock)
-
自动过期续期
-
分布式读写锁、信号量、CountDownLatch
3. ✅ Spring Data Redis 方式(手动)
Boolean success = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, 30, TimeUnit.SECONDS);
if (Boolean.TRUE.equals(success)) {
// 获取成功
}
缺点同样是不可重入、不支持自动续期,需要自己扩展逻辑。
4. ✅ RedLock 分布式红锁算法
适用于部署在多个 Redis 实例(至少 5 个)时的场景,提高可靠性。
Redisson 已经内置支持 RedLock:
RLock lock1 = redisson.getLock("lock1");
RLock lock2 = redisson.getLock("lock2");
RLock lock3 = redisson.getLock("lock3");
RedissonRedLock redLock = new RedissonRedLock(lock1, lock2, lock3);
redLock.lock();
✅ 三、总结推荐
|
使用场景 |
推荐方案 |
|---|---|
|
本地 Redis 单实例 |
Redisson 普通锁(最简单好用) |
|
多节点、跨机房 Redis |
Redisson 的 RedLock |
|
轻量场景,已有 Jedis/Lettuce |
手动 SET NX PX + Lua 脚本解锁 |
|
Spring Boot 项目 |
强烈推荐使用 Redisson Starter |
✅ Spring Boot 集成 Redisson 简要配置
pom.xml:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.23.5</version>
</dependency>
application.yml:
redisson:
config: |
singleServerConfig:
address: "redis://127.0.0.1:6379"
浙公网安备 33010602011771号