分布式锁实现

基于数据库:
        基于数据库的实现方式的核心思想是:在数据库中创建一个表,表中包含自定义业务名字段并在其上创建唯一索引,想要执行某段业务,就使用这个业务名向表中插入数据,成功插入则获取锁,执行完成后删除对应的行数据释放锁
        使用基于数据库的这种实现方式很简单,但是对于分布式锁应该具备的条件来说,它有一些问题需要解决及优化:
            因为是基于数据库实现的,数据库的可用性和性能将直接影响分布式锁的可用性及性能
            不具备可重入的特性,因为同一个线程在释放锁之前,行数据一直存在,无法再次成功插入数据,所以需要在表中新增一列,用于记录当前获取到锁的机器和线程信息,在再次获取锁的时候,先查询表中机器和线程信息是否和当前机器和线程相同,若相同则直接获取锁
            没有锁失效机制,因为有可能出现成功插入数据后,服务器宕机了,对应的数据没有被删除,当服务恢复后一直获取不到锁,所以需要在表中新增一列,用于记录失效时间,并且需要有定时任务清除这些失效的数据
            不具备阻塞锁特性,获取不到锁直接返回失败,所以需要优化获取逻辑,循环多次去获取

基于缓存(Redis):
        redis通常可以使用setnx来实现分布式锁:
            setnx来创建一个key,如果key不存在则创建成功返回1,如果key已经存在则返回0,依照上述来判定是否获取到了锁
            获取到锁的执行业务逻辑,完毕后删除lock_key,来实现释放锁,其他未获取到锁的则进行不断重试,直到自己获取到了锁
            当获取到锁的客户端挂了,没有执行释放锁的操作,则其他客户端就无法获取到锁,可以通过设置过期时间特性实现过期自动释放锁

基于zookeeper:
        zookeeper通过临时顺序节点来实现分布式锁:
            在父节点下创建临时顺序节点
            获取父节点的所有节点,判断当前节点是不是父节点所有节点中最小的
            最小代表获取了节点,否则添加监控前一个节点是否存在的watcher
        优点:具备高可用、可重入、阻塞锁特性,可解决失效死锁问题
        缺点:因为需要频繁的创建和删除节点,性能上不如Redis方式
        推荐:Apache的开源库Curator,它是一个ZooKeeper客户端,Curator提供的InterProcessMutex是分布式锁的实现,acquire方法用于获取锁,release方法用于释放锁。

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值