Java面试21-请说一下你对分布式锁的理解以及分布式锁的实现

本文介绍了分布式锁的概念,将其与线程锁对比,阐述了其关键特性及在关系型数据库和Redis中的应用。重点讲解了Redis和Redisson的实现以及zookeeper和etcd在数据一致性下的锁管理。
摘要由CSDN通过智能技术生成

分布式锁,是一种一种跨进程的跨机器节点的互斥锁,它可以用来保证多机器节点对于共享资源访问的排他性

分布式锁和线程锁本质上是一样的,线程锁的生命周期是单进程多线程,分布式锁的声明周期是多进程多机器节点。在本质上,他们都需要满足锁的几个重要特性:1. 排他性,同一时刻只能有一个节点去访问共享资源;2. 可重入性,允许一个已经获得锁的进程,在没有释放锁之前再次重新获得锁;3. 锁的获取、释放的方法;4. 锁的失效机制、避免死锁的问题。只要能满足这些特性的技术组件都能够实现分布式锁。关系型数据库,可以使用唯一约束来实现锁的排他性,如果要针对某个方法加锁,就可以创建一个表包含方法名称字段,并且把方法设置成唯一的约束。那抢占锁的逻辑就是:往表里面插入一条数据,如果已经有其他的线程获得了某个方法的锁,那这个时候插入数据会失败,从而保证了互斥性。这种方式虽然简单,但是要实现比较完整的分布式锁,还需要考虑重入性、锁失效机制、没抢占到锁的线程要实现阻塞等,就会比较麻烦。

  1. Redis提供了SETNX命令可以实现锁的排他性,当key不存在就返回1,存在就返回0。然后还可以用expire命令设置锁的失效时间,从而避免死锁问题。当然有可能存在锁过期了,但是业务逻辑还没执行完的情况,这种情况可以写一个定时任务对指定的key进行续期。
  2. Redisson这个开源组件,就提供了分布式锁的封装实现,并且也内置了一个Watch Dog机制来对key做续期。
    Redis里面这种分布式锁设计已经能够解决99%的问题了,当然如果在Redis搭建了高可用集群的情况下出现主从切换导致key失效,这个问题也有可能造成多个线程抢占到同一个锁资源的情况,所以Redis官方也提供了一个RedLock的解决方法,但是实现会相对复杂一点。
  3. 分布式锁应该是一个CP模型,而Redis是一个AP模型,所以在集群架构下由于数据的一致性问题导致极端情况下出现多个线程抢占到锁的情况很难避免。基于CP模型又能实现分布式锁特性的组件,可以选择zookeeper或者etcd。在数据一致性方面,zookeeper用到了zab协议来保证数据的一致性,etcd用到了raft算法来保证数据一致性。在锁的互斥方面,zookeeper可以基于有序节点再结合Watch机制实现互斥和唤醒,etcd可以基于Prefix机制和Watch实现互斥和唤醒。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值