分布式

作者: 小码弟 | 来源:发表于2018-12-18 16:14 被阅读0次

一、分布式锁
当数据库使用集群时,节点分布在不同地点,单机的锁无法满足分布式环境下事务的执行结果一致性。由此引入分布式锁

  1. 数据库的唯一索引
    获得锁时向表中插入一条记录,释放时删除这条记录。唯一索引可以保证这条记录只被插入一次,那么就可以通过判断这条记录是否存在进而决定锁有没有被占用。
    存在问题:

    • 锁没有失效时间,解锁失败其他进程无法再获得该锁
    • 只能是非阻塞锁,插入失败直接报错,不能重试
    • 不可重入,已经获得锁的进程也必须重新获得锁
  2. Redis的SETNX指令
    使用SETNX(set if not exist)指令插入一对键值,如果key已经存在,返回false;如果不存在,则插入这对键值。思想和唯一索引一致,不过借助Redis键的过期时间,可以避免锁释放失败的问题,因为经过一段时间键失效后,锁必然回归可用状态。

  3. Redis的RedLock算法
    保证单点失效时仍然可用。分为3步:

    1. 尝试从N个相互独立的Redis实例上获取锁
    2. 计算获取锁消耗的时间,如果小于键失效时间,并且从(N/2+1)个实例上成功获得锁,那么就认为成功获得的锁。
    3. 如果锁获取失败,就到每个实例上释放锁。
  4. ZooKeeper的有序节点
    ZooKeeper是一个分布式应用程序协调服务,是Hadoop和HBase的组件。提供分布式同步,组服务。它基于Fast Paxos ,基本流程:

    1. 在一个配置纪元内,产生若干个candidate
    2. 这些candidate向其他节点发送投票请求
    3. 每个节点按先到先得的原则对到来的投票请求发送响应,每个节点只能响应一个请求
    4. 获得半数以上的candidate提升为leader,向所有其他节点发送心跳包,告知自己的leader地位
    5. 如果两个及两个candidate获得相同票数,此次投票无效,进入下一个配置 纪元。

注意,每个节点都有一个配置纪元的计数器,随时间递减,每轮投票开始时初值随机生成。这样一来,一轮投票中同时成为candidate的概率比较低。
正常工作的leader轮询发送的心跳包会重置附属节点的配置纪元,不让他们成为candidate。一旦leader宕机,那么一段时间后,必定有一个附属节点的配置纪元归零,开始竞选leader。

二、 分布式事务

  1. 事务的操作位于不同的节点,需要保证事务的ACID特性

  2. 实现:2PC(2 Phrase Commit) 两阶段提交,引入协调者来协调参与者的行为

    2.1 准备阶段:协调者询问参与者事务是否执行成功,参与者发回事务执行结果。注意,事务参与者只是执行了事务,并没有提交事务。

    2.2 提交阶段:如果协调者收到所有参与节点的事务执行结果,那么协调者通知所有参与者提交事务。

  3. 存在问题:

    • 同步阻塞:在第二阶段,参与者等待协调者通知的时候处于阻塞状态
    • 单点失效: 如果协调者宕机,整个系统瘫痪
    • 数据不一致:如果协调者发给部分参与者的通知丢失,会导致数据不一致,

相关文章

网友评论

      本文标题:分布式

      本文链接:https://www.haomeiwen.com/subject/kmjlkqtx.html