linux 时钟漂移,Redis 实现分布式锁之Redlock 算法浅析

本文深入探讨了分布式锁的实现,特别是针对Linux时钟漂移问题,分析了基于故障转移的实现不足,并详细介绍了Redlock算法。Redlock保证了分布式锁的安全性、无死锁和容错性,通过在多个独立的Redis节点上获取锁来提高可靠性。同时,讨论了单实例和分布式情况下的正确实现,以及防止锁错误删除的策略。最后,提到了时钟漂移对Redis过期时间的影响和解决方案。
摘要由CSDN通过智能技术生成

保证分布式锁有效的三个属性

Safety Properties:安全性,此处也就是互斥性,任意时刻只能有一个客户端可以持有锁

Liveness Property A:无死锁,即使持有锁的客户端崩溃或被分区,也可以获得锁

Liveness Property B:容错性,只要大多数 Redis 节点正常,客户端就能获取和释放锁

为什么基于故障转移(failover-based)的实现还不够

我们先来看看现有大多数 Redis 分布式锁的实现。

最简单的方案是在一个实例中创建一个 key,并给这个 key 设置过期时间,保证这个锁最终一定能够释放,当客户端释放锁的时候,删除这个 key

看上去可能不错,但是有个问题:当我们的 Redis 主节点挂掉时会发生什么?好,那我们增加一个从节点,当主节点不可用时自动切换到从节点。但不幸地是这不行,因为 Redis 复制是异步的,所以不能保证互斥性。

在这个方案下有一个明显的竞态条件:

客户端 A 在 master 节点获取锁;

在写 key 操作被传输到 slave 节点前 master 节点挂了;

slave 晋升为 master;

客户端 B 获取 A 其实刚刚已经获取到的锁;

SAFETY VIOLATION 违反了文章开头提到的安全属性

虽然有上述缺陷,但在一些特殊场景下,这种方案还是可以使用的。比如故障发生的时候,多个客户端同时持有锁对于系统运行或者业务逻辑没有太大影响,那么就可以使用这种基于复制的解决方案。否则最好还是使用本文后续将会提到的 Redlock 算法。

单实例情况下正确的实现

在解决单实例单点故障的限制前,我们先来看看如何正确地执行它

获取一个锁的方式:

set resource_name my_random_value NX PX 30000

解释:

在 resource_name 不存在(NX 选项)的时候创建它,并设置过期时间为 30000 毫秒。

值是一个随机值,而且这个值在每个客户端和每个锁请求中都是唯一的,这样做的目的是为了能够安全地释放锁,不会出现 A 客户端获取的锁被 B 客户端删除的情况。使用一段简单的 lua 代

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值