面试官:怎么实现Redis分布式锁?

面试官:怎么实现Redis分布式锁?
最新回答
远方小镇

2026-10-29 18:41:46

实现Redis分布式锁的核心在于利用Redis的单线程特性,通过原子操作确保互斥性,并结合过期时间、唯一标识等机制解决死锁、误解锁等问题。以下是具体实现方案及关键代码示例:

一、核心实现步骤1. 加锁逻辑
  • 原子性操作:使用SET key value NX PX expireTime命令(Redis 2.6.12+支持),确保“创建键+设置过期时间”的原子性。

    NX:仅当键不存在时才设置,保证互斥性。

    PX expireTime:设置键的过期时间(毫秒),防止死锁。

  • 唯一标识:value设为客户端唯一标识(如UUID或机器IP+线程ID),用于解锁时校验归属。
2. 解锁逻辑
  • 校验归属:通过Lua脚本原子性执行GET + DEL,确保只有锁的持有者能释放锁。if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end
  • 原子性保证:Lua脚本在Redis中单线程执行,避免竞态条件。
二、Java代码实现(基于Jedis)1. 依赖引入<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version></dependency>2. 加锁代码public boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) { try (Jedis jedis = jedisPool.getResource()) { String result = jedis.set(lockKey, requestId, "NX", "PX", expireTime); return "OK".equals(result); }}
  • 参数说明:

    lockKey:锁的键名(需全局唯一)。

    requestId:客户端唯一标识。

    expireTime:锁的过期时间(毫秒)。

3. 解锁代码public boolean releaseDistributedLock(String lockKey, String requestId) { try (Jedis jedis = jedisPool.getResource()) { String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " + "return redis.call('del', KEYS[1]) else return 0 end"; Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId)); return result.equals(1L); }}三、关键问题处理
  1. 死锁避免

    通过PX设置过期时间,即使客户端崩溃,锁也会自动释放。

  2. 误解锁防护

    解锁时校验value是否与requestId匹配,防止删除其他客户端的锁。

  3. 锁续期(可选)

    对于耗时操作,可使用Redisson等库的看门狗机制自动续期。

  4. Redis集群容错

    单节点Redis可能因故障导致锁丢失,需使用Redlock算法(需多数节点同意)增强可靠性。

四、注意事项
  • 锁粒度:避免锁住过多资源,影响并发性能。
  • 重试机制:加锁失败后应合理重试(如指数退避)。
  • 性能考量:频繁加解锁可能增加Redis负载,需评估业务场景。
五、完整示例调用String lockKey = "order_lock";String requestId = UUID.randomUUID().toString();int expireTime = 30000; // 30秒// 尝试加锁if (tryGetDistributedLock(lockKey, requestId, expireTime)) { try { // 执行业务逻辑 } finally { // 确保解锁 releaseDistributedLock(lockKey, requestId); }} else { // 获取锁失败处理}

通过以上方案,可实现一个满足互斥性、防死锁、防误删的Redis分布式锁。如需更高可靠性,建议结合Redisson库或Redlock算法。