分布式

作者: 小码弟 | 来源:发表于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