当前位置:   article > 正文

分布式锁的3种实现方式_mvcc 分布式锁

mvcc 分布式锁

分布式锁的3种实现方式

锁的的基本概念:
开发中锁的概念并不陌⽣,通过锁可以实现在多个线程或多个进程间在争抢资源时,能够合理的分配置资源的所有权。在单体应⽤中我们可以通过 synchronized 或ReentrantLock 来实现锁。
但在分布式系统中,仅仅是加synchronized 是不够的,需要借助第三组件来实现。⽐如⼀些简单的做法是使⽤ 关系型数据⾏级锁来实现不同进程之间的互斥,但⼤型分布式系统的性能瓶颈往往集中在数据库操作上。为了提⾼性能得采⽤如Redis、Zookeeper之内的组件实现分布式锁。

  • 共享锁:也称作只读锁,当⼀⽅获得共享锁之后,其它⽅也可以获得共享锁。但其只允许读取。在共享锁全部释放之前,其它⽅不能获得写锁。

  • 排它锁:也称作读写锁,获得排它锁后,可以进⾏数据的读写。在其释放之前,其它⽅不能获得任何锁。

  • 表锁:操作对象是数据表。Mysql大多数锁策略都支持,是系统开销最低但并发性最低的一个锁策略。事务t对整个表加读锁,则其他事务可读不可写,若加写锁,则其他事务增删改都不行。

  • 行级锁:操作对象是数据表中的一行。是MVCC技术用的比较多的。行级锁对系统开销较大,但处理高并发较好。

1、给数据库表字段加版本号

并发量不大可以用,这个策略源于 mysql 的 mvcc 机制,使用这个策略其实本身没有什么问题,唯一的问题就是对数据表侵入较大,我们要为每个表设计一个版本号字段,然后每次操作时都要判断 版本号,增加了数据库负担,在高并发的要求下,对数据库连接的开销也是无法忍受的,而且数据库本身也有瓶颈。

2、基于redis

  • 1、给线程生成唯一id,作为key的value值
  • 2、setnx(lockkey, 1) 如果返回 0,则说明占位失败;如果返回 1,则说明占位成功
  • 3、expire() 命令对 lockkey 设置超时时间,为的是避免死锁问题。
  • 4、执行完业务代码后,可以通过 delete 命令删除 key。

redis:
在这里插入图片描述
redisson(对redis操作又进一步封装):
在这里插入图片描述

在这里插入图片描述

3、基于zookeeper

锁的获取流程:
在这里插入图片描述

  • 1、基于资源ID创建临时序号读锁节点 /lock/888.R00000001 Read
  • 2、获取 /lock 下所有⼦节点,判断其最⼩的节点是否为读锁,如果是则获锁成功
  • 3、最⼩节点不是读锁,则阻塞等待。添加lock/ ⼦节点变更监听。
  • 4、当节点变更监听触发,执⾏第2步

⽺群效应:在等待锁获得期间,所有等待节点都在监听 Lock节点,⼀但lock 节点变更,所有等待节点都会被触发,然后在同时反查Lock ⼦节点。如果等待用例过⼤会使⽤Zookeeper承受⾮常⼤的流量压⼒。
在这里插入图片描述
为了改善这种情况,可以采⽤监听链表的⽅式,每个等待对列只监听前⼀个节点,如果前⼀个节点释放锁的时候,才会被触发通知。这样就形成了⼀个监听链表。
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/776249
推荐阅读
相关标签
  

闽ICP备14008679号