redis分布式锁问题
推荐方案:SET EX PX NX + 校验唯一随机值【线程id】, 再释放锁。
java
String keyResourceId = "your_key_here";
String uniRequestId = "your_unique_request_id_here";
int expireTimeInSeconds = 100;
String result = jedis.set(keyResourceId, uniRequestId, "NX", "EX", expireTimeInSeconds);
if ("OK".equals(result)) { // 如果设置成功,获取到了锁
try {
// 做业务处理
// do something
} catch (Exception e) {
// 处理异常
} finally {
// 获取当前锁的值,如果是当前线程设置的锁,则释放锁
String currentValue = jedis.get(keyResourceId);
if (uniRequestId.equals(currentValue)) {
jedis.del(keyResourceId); // 释放锁
}
}
}
redis分布式锁致命4问
看看你设计的redis锁能经得住几问
1.锁过期释放,业务未执行完
解决方案:设置锁续约机制,假设线程A获取了锁开始执行业务,我们可以开启一个守护线程,守护线程每过一段时间就检测线程A的执行情况,如果A为执行完,我们就给锁做一个续约操作。
PS:Redisson中实现了看门狗机制。
2.锁被其它线程释放
通过校验唯一值解决,上述方案已解决。
3.加锁和释放锁都不是原子操作,问题应该如何解决
加锁和释放锁的所有业务一起执行
4.主master节点挂机,导致主从节点同时对一个key加锁
场景:生产环境下,我们使用redis主从+哨兵模式,主节点对一个key加锁后挂掉了,然后新的主节点产生,但之前并没有同步到锁,导致又加了一次锁,重复加锁。
解决方案:
Red Lock(红锁),会对所有实例申请加锁,超过半数节点加锁成功,红锁申请成功,反之失败。这样及时主节点挂掉,也不会对我们的锁产生影响。
我们上述方案可以解决2,3两问。