zoukankan      html  css  js  c++  java
  • 分布式系统中有关一致性的理解

    首先什么是一致性?

    一致性就是分布式系统中相互独立多个节点就某个值达成一致。

     

    具体可分为强一致性和弱一致性。

    强一致性:在任意时刻,所有节点中的数据是一样的。同一时间点,你在节点A中获取到key1的值与在节点B中获取到key1的值应该都是一样的。

    弱一致性:不保证任意时刻所有节点数据一样,有很多不同实现。最广泛实现的是最终一致性。所谓最终一致性,就是不保证在任意时刻任意节点上的同一份数据都是相同的,但是随着时间的迁移,不同节点上的同一份数据总是在向趋同的方向变化。也可以简单的理解为在一段时间后,节点间的数据会最终达到一致状态。

     

    分布式一致性的应用场景:

    多节点提供读写服务,保证高可用性,可伸缩性(ZooKeeper,DNS,redis集群)

     

    分布式系统面临的问题:

    * 消息传递异步无序(asynchronous): 现实网络不是一个可靠的信道,存在消息延时、丢失,节点间消息传递做不到同步有序(synchronous)

    * 节点宕机(fail-stop): 节点持续宕机,不会恢复

    * 节点宕机恢复(fail-recover): 节点宕机一段时间后恢复,在分布式系统中最常见

    * 网络分化(network partition): 网络链路出现问题,将N个节点隔离成多个部分

    * 拜占庭将军问题(byzantine failure)[2]: 节点或宕机或逻辑失败,甚至不按套路出牌抛出干扰决议的信息

     

    而需要满足一致性的分布式系统设计一般前提是无拜占庭将军问题(内网可信)

    此处要提到分布式系统的基础理论,FLP定理,即当只在节点宕机的模型中,不能同时满足可用性和强一致性。它的另一个角度提法是CAP理论,即强一致性、可用性和分区容错性,只能保证其中2个。

     

    保证一致性的协议有很多,包括2PC,3PC,Paxos,raft和PacificA。

     

    2PC:2阶段锁提交协议,保证多个数据分片上操作的原子性。(分布式事务)

    节点分为协调者(coordinator)和参与者(participat),执行分为2个阶段

    阶段一:coordinator发起一个提议,分别问询各participant是否接受。Participate执行事务操作,将undo和redo信息写入事务日志,向coordinator回复yes或no

    阶段二:coordinator根据participant的反馈,提交或中止事务,如果participant全部yes则提交,只要有一个participant回复no就中止。Participate根据coordinator的commit/Rollback信息正式提交或终止事务,并释放占用资源,返回ack。

     

    优点:原理简单、实现方便

    缺点:同步阻塞、单点问题、数据不一致(协调者在未发送完commit请求前崩溃或网络原因部分participate没收到commit,则部分participate无法进行事务提交)、太过保守(如果参与者在与协调者通信期间出现故障,协调者只能靠超时机制来判断是否需要中断事务)

     

    3PC:3阶段锁提交协议,保证多个数据分片上操作的原子性。(分布式事务)

    相对2PC,分为询问,预提交,提交3个阶段(解决阻塞,但还是可能数据不一致)

    过程:coordinator接收完participant的反馈(vote)之后,进入阶段2,给各个participant发送准备提交(prepare to commit)指令。participant接到准备提交指令后可以锁资源,但要求相关操作必须可回滚。coordinator接收完确认(ACK)后进入阶段3、进行commit/abort,3PC的阶段3与2PC的阶段2无异。协调者备份(coordinator watchdog)、状态记录(logging)同样应用在3PC。

    Paxos算法(解决单点问题)

    Paxos算法是当前最重要的一致性算法,所有一致性算法都是paxos或是paxos的简化版。

    Paxos算法解决多份相同数据就某个值达成一致。正确性证明的理论基础:任意2个法定集合(超过半数节点组成的集合)的交集不为空。

    角色:

    从提案到表决流程涉及到三个角色:

    * Proposer:提案者,可能有多个,它门负责提出提案。

    * Acceptor:接受人,一定要有多个,它们对指定提案进行表决,同意则接受提案,不同意则拒绝。

    * Learner:学习人,收集每位Acceptor接受的提案,并根据少数服从多数的原则,形成最终提案。

    实际上,分布式系统中一个组件可以对应一种或多种角色。

    算法描述:

    * 第一阶段(Prepare阶段)

    Proposer:

    * 选取提案编号n,并向大多数Acceptor发送携带编号n的prepare请求。

    Acceptor:

    * 如果收到的提案编号n比自己已经收到的编号都要大,则向Proposer承诺不再接收编号小于n的提案,如果之前接受过提案,则同时将接受的提案中编号最大的提案及其编号发给Proposer。

    * 如果收到的提案编号n小于自己已经收到提案编号的最大值,则拒绝。

    * 第二阶段(Accept阶段)

    Proposer:

    * 首先,对接收到响应,逐条处理:

    * 如果接收到拒绝,则暂不处理。

    * 如果接收到同意,同时还接收到Acceptor已经接受的提案,则记下该提案及编号。

    * 处理完响应后,统计拒绝和同意个数:

    * 如果大多数拒绝,则准备下次提案。

    * 如果大多数同意,从这些Acceptor已经接受的提案中选取提案编号最大的提案作为自己的提案,没有则使用自己的提案,逐个向Acceptor发送Accept消息。

    Acceptor:

    * 如果收到的提案编号n小于自己已经收到最大提案编号,则拒绝。

    * 如果收到的提案编号n等于自己已经收到最大提案编号,则接受该提案。

    * 如果收到的提案编号n大于自己已经收到最大提案编号,则拒绝。

    * 形成共识(与Prepare&Accept阶段并行)

    Acceptor:

    * 每当接受一个提案,则将该提案及编号发给Learner。

    Learner:

    * 记录每一个Acceptor当前接受的提案,一个Acceptor先后发来多个提案,则保留编号最大的提案。

    * 统计每个提案被接受的Acceptor个数,如果超过半数,则形成共识。

     

    Raft和PacificA是基于paxos的简化实现,更容易理解更容易实现。等看了再总结下

    http://www.cnblogs.com/liulaoshi/p/7821339.html 

    参考文章:

    https://segmentfault.com/a/1190000004474543

    https://www.zhihu.com/question/19787937

    http://www.cnblogs.com/bangerlee/p/5268485.html

    http://www.voidcn.com/article/p-xvyhhccc-dm.html

     

     

     

     

  • 相关阅读:
    Linux命令_2
    Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.
    壁纸目录
    ubuntu 解决“无法获得锁 /var/lib/dpkg/lock -open (11:资源暂时不可用)”的方法
    Oracle VM VirtulBox 安装Ubuntu16.04
    Linux 中文输入法安装
    Android LayoutInflater 相关知识
    Linux命令_1
    青蛙跳杯子
    横向打印二叉树
  • 原文地址:https://www.cnblogs.com/liulaoshi/p/7821339.html
Copyright © 2011-2022 走看看