分布式锁

博客介绍了分布式锁需满足互斥性、不死锁、容错性、加解锁同一客户端四个条件。还阐述了三种实现方式:数据库乐观锁,通过查询和更新版本号实现;基于Zookeeper的分布式锁,利用创建临时有序子节点判断;基于Redis的分布式锁,用setNx和expire命令操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.分布式锁条件

为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件:

  1. 互斥性。在任意时刻,只有一个客户端能持有锁。

  2. 不会发生死锁。即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。

  3. 具有容错性。只要大部分的Redis节点正常运行,客户端就可以加锁和解锁。

  4. 解铃还须系铃人。加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。

2.分布式锁一般有三种实现方式:

  1. 数据库乐观锁

  2. 基于Redis的分布式锁

  3. 基于Zookeeper的分布式锁

3.数据库乐观锁

     数据库乐观锁的实现方式是先使用SELECT语句查询某字段的值(版本号),该字段即理解为要获取的分布式锁。然后在使用         UPDATE语句对正常业务数据进行更新,在UPDATE语句执行时一定要用WHERE条件对版本号进行判断,若版本号在这段时间       内并没有发生变化则该语句默认执行成功,否则循环执行即可。

4.基于Zookeeper的分布式锁

    基于Zookeeper实现分布式锁的算法思路大致如下假设锁空间的根节点为/lock: 

  1. 客户端连接zookeeper,并在/lock下创建临时的且有序的子节点,第一个客户端对应的子节点为/lock/lock-0000000000,第二个为/lock/lock-0000000001,以此类推。

  2. 客户端获取/lock下的子节点列表,判断自己创建的子节点是否为当前子节点列表中序号最小的子节点,如果是则认为获得锁,否则监听/lock的子节点变更消息,获得子节点变更通知后重复此步骤直至获得锁。

  3. 执行业务代码。

  4. 完成业务流程后,删除对应的子节点释放锁。

5.基于Redis的分布式锁

    需要的命令:
    setNx:当key不存在时返回1,当key存在时返回0,我们可以根据这个来判断是否存在锁。
    expier:使用这个命令为key设置一个过期时间,超过这个时间锁会自动释放,避免死锁。

实现思想:
    1.获取锁的时候,使用setNx加锁,并使用expire命令给这个锁设置一个过期时间,
        过期自动释放锁,锁的value值是一个UUID的随机数,在释放锁的时候判断是不是同一个锁。
    2.获取锁的时候还要设置一个超时获取时间,如果超过这个时间就放弃获取这个锁。
    3.释放锁的时候,根据UUID判断是不是同一个锁,如果是同一个锁,使用delete命令进行锁释放。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值