分布式锁总结

写在开始:一个搬砖程序员的随缘记录

一、为什么要用分布式锁

需要用到分布式锁的情况

有三台服务器,变量A存在三个服务器中。在三个服务器中都分配了内存,三个用户同时对变量A进行操作。这样变量A显示结果是不对的。
所以如果业务中出现这种业务情况,我们就需要用到分布式锁来进行处理。由于分布式系统多线程、多进程并且分布在不同的服务器上,所以需要用到分布式锁来进行处理。

二、分布式锁应该具备哪些条件

1、在分布式的环境中,一个方法在同一时间只能被一个机器的一个线程执行。
2、高可用的获取锁和释放锁
3、高性能的获取锁和释放锁
4、具备可重入特性
5、具备锁失效机制。防止死锁
6、具备非阻塞锁特性。即没有获取道锁直接返回获取锁失败

三、CAP理论

分布式场景中的一致性问题一直是一个很重要的话题。分布式的CAP理论告诉我们,任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition
tolerance),最多只能同时满足两项。所以在进行分布式系统设计时就要对这三者进行取舍。在互联网的绝大数的场景中,都需要牺牲强一致性来换取系统的高可用性,系统往往只能保证最终一致性,只要这个最终时间在用户的可接受范围内即可。

在很多场景中,我们为了保重数据的最终一致性,需要很多技术方案来进行解决。比如分布式事务、分布式锁等。有的时候,我们需要保证一个方法在同一个时间只能被同一个线程执行

四、分布式锁的三种实现方式

1、基于数据库

基于数据库的实现方式核心就是:在数据库中创建一张表,表字段包含方法名等字段,并给方法名这个字段加上唯一索引,想要执行某个方法,就在表中插入一条数据,成功插入数据则获取锁,方法执行完成后则删除数据释放锁。
实现思想:当我们想要执行一个方法时,向方法表中插入一条数据,因为我们对方法表中的方法名字段做了唯一约束,当其他线程来执行这个方法向数据库中插入数据时,会返回失败。这样就能保证只有一个线程对方法进行操作。保证数据的一致性。

一些问题和优化

1、因为是基于数据库实现的,数据库的可用性和性能将直接影响分布式锁的可用性和性能。
2、不具备可重入的特性,因为同一个线程在释放锁之前,行数据一直都存在,无法成功插入数据。所以需要在方法表中增加获取到锁的机器信息和线程信息,在再次获取锁的时候,先查询方法表中方法的锁的机器信息和线程信息和当前机器和线程信息是否相同。若相同则直接获取锁。
3、没有锁失效机制。因为有可能执行方法的数据插入数据库中,执行的服务器宕机了,对应的数据没有删除,其他线程就一直获取不到锁。所以需要在表中增加失效时间的字段,写定时任务对过了失效时间的数据进行清除。
4、不具备阻塞素锁特性,获取不到锁直接返回,所以需要优化获取锁逻辑,需要循环获取锁。

2、基于redis
1、选取redis进行分布式锁的原因

  • redis有很高的性能
  • redis命令对此支持很好,实现起来比较方便

2、需要使用到的命令

  • SETNX:SETNX key val:当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0
  • expire:expire key timeout:为key设置一个过期时间,单位为second,超过这个时间则会释放锁,避免造成死锁
  • delete:delete key:删除key
    在使用redis进行分布式锁主要用到这三个命令
    实现思想
    1、获取锁的时候,使用setnx加锁,并使用expire命令为锁加上过期时间,超过过期时间则自动释放锁,锁的value值为一个随机的UUID,通过UUID在释放锁的时候进行判断
    2、获取锁的时候还设置一个获取锁的超时时间,超过这个时间则不再进行获取
    3、释放锁的时候,通过UUID进行判断是否是该锁,如果是,则使用delete进行删除。

3、基于ZooKeeper
介绍

ZooKeeper是一个为分布式应用提供一致性服务的开源组件,它内部是一个分层的文件系统目录树结构,规定同一个目录只能有一个唯一文件名。

分布式锁实现步骤:

1、创建一个目录mylock
2、线程A想要获取锁就在mylock目录下创建临时顺序节点
3、获取mylock下所有的子节点,然后获取比自己小的的兄弟节点,如果不存在,则说明当前线程顺序号最小,获得锁。
4、线程B获取所有节点,判断自己不是最小节点,设置监听比自己次小的节点
5、线程A处理完,删除自己的节点,线程B监听到变更事件,判断自己是不是最小节点,是最小节点就获取锁。

优缺点

优点:具备高可用、可重入、阻塞锁特性。可解决死锁问题
缺点:因为需要频繁创建和删除节点,所以性能没有redis高

Over

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值