两阶段提交协议,简称2PC(2 Prepare Commit),是比较常用的解决分布式事务问题的方式,要么所有参与进程都提交事务,要么都取消事务,即实现ACID中的原子性(A)的常用手段
分布式事务:事务提供一种操作本地数据库的不可分割的一系列操作“要么什么都不做,要么做全套(All or Nothing)”的机制,而分布式事务就是为了操作不同数据库的不可分割的一些列操作“要么什么都不做,要么做全套(All or Nothing)”的机制


阶段一:
阶段二:
假如任何一个参与者向协调者反馈了No响应,或者在等待超时之后,协调者尚无法接收到所有参与者的反馈响应,那么就会中断事务

第一阶段:
第二阶段:
优点:原理简单
缺点:
三阶段提交协议出现背景:一致性协议中设计出了二阶段提交协议(2PC),但是2PC设计中还存在缺陷,于是就有了三阶段提交协议,这便是3PC的诞生背景。
3PC,全称“three phase commit”,是2PC的改进版,将2PC的“提交事务请求“过程一分为二,共形成了由CanCommit、PreCommit和doCommit三个阶段组成的事务处理协议

三阶段提交升级点(基于二阶段):
简单讲:就是除了引入超时机制之外,3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有CanCommit、PreCommit、DoCommit三个阶段
类似于2PC的准备(第一)阶段。协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。
协调者根据参与者的反映情况来决定是否可以执行事务的PreCommit操作。根据响应情况,有以下两种可能:
该阶段进行真正的事务提交,也可以分为执行提交和中断事务两种情况。

如果出现任意一种情况,最终都会导致参与者无法收到doCommit请求或者abort请求,针对这种情况,参与者都会在等待超时之后,继续进行事务提交
问题:3PC协议并没有完全解决数据一致问题
NWR是一种在分布式存储系统中用于控制一致性级别的一种策略。在亚马逊的云存储系统中,就应用NWR来控制一致性
NWR值的不同组合会产生不同的一致性效果,当W+R>N的时候,整个系统对于客户端来讲能保证强一致性。
以常见的N=3、W=2、R=2为例:
在分布式系统中,数据的单点是不允许存在的。即线上正常存在的备份数量N设置1的情况是非常危险的,因为一旦这个备份发生错误,就可能发生数据的永久性错误。假如我们把N设置成为2,那么,只要有一个存储节点发生损坏,就会有单点的存在。所以N必须大于2。N越高,系统的维护和整体成本就越高。工业界通常把N设置为3。

在上图中,如果R+W>N,则读取操作和写入操作成功的数据一定会有交集(如图中的Node2),这样就可以保证一定能够读取到最新版本的更新数据,数据的强一致性得到了保证。在满足数据一致性协议的前提下,R或者W设置的越大,则系统延迟越大,因为这取决于最慢的那份备份数据的响应时间。

因为成功写和成功读集合可能不存在交集,这样读操作无法读取到最新的更新数值,也就无法保证数据的强一致性
Gossip协议也叫Epidemic协议(流行病协议)。原本用于分布式数据库中节点同步数据使用,后被广泛用于数据库复制、信息扩散、集群成员身份确认、故障探测等。
从gossip单词就可以看到,其中文意思是八卦、流言等意思,我们可以想象下绯闻的传播(或者流行病的传播);gossip协议的工作原理就类似于这个。gossip协议利用一种随机的方式将信息传播到整个网络中,并在一定时间内使得系统内的所有节点数据一致。Gossip其实是一种去中心化思路的分布式协议,解决状态在集群中的传播和状态一致性的保证两个问题。
Gossip协议的消息传播方式有两种:反熵传播和谣言传播
是以固定的概率传播所有的数据。所有参与节点只有两种状态:Suspective(病原)、Infective(感染。过程是种子节点会把所有的数据都跟其他节点共享,以便消除节点之间数据的任何不一致,它可以保证最终、完全的一直。缺点是消息数量非常庞大,且无限制;通常只用于新加入节点的数据初始化。
是以固定的概率仅传播新到达的数据。所有参与节点有三种状态:Suspective(病原)、Infective(感染)、Removed(愈除)。过程是消息只包含最新update,谣言消息在某个时间点之后会被标记为removed,并且不再被传播。缺点是系统有一定的概率会不一致,通常用于节点间数据增量同步。
Gossip协议最终目的是将数据分发到网络中的每一个节点。根据不同的具体应用场景,网络中两个节点之间存在三种通信方式:推送模式、拉取模式、推/拉模式
1.Push
节点A将数据(key, value, version)及对应的版本号推送给B节点,B节点更新A中币自己新的数据

2.Pull
A仅将数据 key,version 推送给B,B将本地比A新的数据 (key, value, version)推送给A,A更新本地

3.Push/Pull
与Pull类似,只是多了一步,A再将本地比B新的数据推送给B,B则更新本地
综上所述,我们可以得出Gossip是一种去中心化的分布式协议,数据通过节点像病毒一样逐个传播。因为是指数级传播,整体传播速度非常快。
Gossip协议由于以上的优缺点,所以适合于AP场景的数据一致性处理,场景应用有P2P网络通信、Redis Cluster、Consul
Paxos协议其实说的就是Paxos算法,Paxos算法是基于消息传递且具有高度容错特性的一致性算法,是目前公认的解决分布式一致性问题最有效的算法之一。
在常见的分布式系统中,总会发生注入机器宕机或网络异常(包括消息的延迟、丢失、重复、乱序、还有网络分区)等情况。Paxos算法需要解决的问题就是如何在一个可能发生上述异常的分布式系统中,快速且正确地在集群内部对某个数据的值达成一致,并且保证不论发生以上任何异常,都不会破坏整个系统的一致性。
注:这里某个数据的值并不只是狭义上的某个数,它可以是一条日志,也可以是一条命令(command)。根据应用场景不同,某个数据的值有不同的含义。
Paxos的版本有:Basic Paxos,Multi Paxos,Fast-Paxos,具体落地有Raft和zk的ZAB协议


basic paxos流程一共分为4个步骤:

在下图中,多数派中的一个Acceptor发生故障,因此多数派大小变为2。在这种情况下,Basic Paxos协议仍然成功。

Proposer在提出提案之后但在达成协议之前失败。具体来说,传递到Acceptor的时候失败了,这个时候需要选出新的Proposer(提案人),那么Basic Paxos协议仍然成功。

最复杂的情况是多个Proposer都进行提案,导致Paxos的活锁问题

针对活锁问题解决起来非常简单:只需要在每个Proposer在去提案的时候随机加上一个等待时间即可
针对basic Paxos是存在一定的问题,首先就是流程复杂,实现及其困难,其次效率低(达成一致性需要2轮RPC调用),针对basic Paxos流程进行拆分为选举和复制的过程。


Multi-Paxos在实施的时候会将Proposer,Acceptor和Learner的角色合并统称为“服务器”。因此,最后只有“客户端”和“服务器”

Paxos是论证了一致性协议的可行性,但是论证的过程晦涩难懂,缺少必要的实现细节,而且工程实现难度比较高,广为人知实现只有zk的实现zab协议。
Paxos协议的出现为分布式强一致性提供了很好的理论基础,但是Paxos协议理解起来较为困难,实现比较复杂
此时出现了一个易理解的分布式一致性复制协议Raft。Java,C++,Go等都有其对应的实现,之后出现的Raft相对要简洁很多。引入主节点,通过竞选确定主节点。节点类型:Follower、Candidate和Leader。
Leader会周期性的发送心跳包给Follower。每个Follower都设置了一个随机的竞选超时时间,一般为150ms~300ms,如果在这个时间内没有收到Leader的心跳包,就会编程Candidate,进入竞选阶段,通过精选阶段的投票多的人成为Leader。

这个是Raft完整版http://thesecretlivesofdata.com/raft/动画演示
github也提供一个https://raft.github.io/动画演示地址 . 原理都是一样的.
单节点是不存在数据不一致问题的,一个节点就很容易就该值达成一致性
如果是多个节点如何达成一致性.Raft是用于实施分布式数据一致性协议的。
我们使用了3个不同的圆圈表示三种不同的状态

接下来开始完成整个竞选阶段流程:
1)下图表示一个分布式系统的最初阶段,此时只有Follower,没有Leader。Follower A等待一个随机的竞选超时时间之后,没收到Leader发来的心跳包,因此进入竞选阶段。

2)此时A发送投票请求给其它所有节点

3)其他节点会对请求进行恢复,如果超过一半的节点回复了,那么该Candidate就会变成Leader

4)之后Leader会周期性地发送心跳包给Follower,Follower接收到心跳包,会重新开始计时


Leader节点B宕机之后,会在剩下的节点中继续去选举新的Leader
1.如果有多个Follower成为Candidate,并且所获得票数相同,那么就需要重新开始投票,例如下图中Candidate B和Candidate D都获得两票,因此需要重新开始投票

2.当重新开始投票时,由于每个节点设置的随机竞选超时时间不同,因此能下一次再次出现多个Candidate并获得同样票数的概率很低

1.来自客户端的修改都会被传入Leader。注意该修改还未被提交,只是写入日志中

2.Leader会把修改复制到所有Follower

3.Leader会等待大多数的Follower也进行了修改,然后才将修改提交

4.此时,Leader会通知所有的Follower让它们也提交修改,此时所有节点的值达成一致

5.多次日志复制情况

面对网络分区,Raft甚至可以保持一致
1.最初始正常情况下状态,B节点会对其他4个节点发送心跳

2.当出现网络分区情况,但是出现网络分区的请求后,只能对A发送心跳,同时其他三个节点会再次选出一个Leader节点。

以term大的为准
网络分区情况日志复制工作也可以完成数据一致性


Lease机制,即租约机制,是一种在分布式系统常用的协议,是维护分布式系统数据一致性的一种常用工具。
Lease机制有以下几个特点:
以租车为例:

分布式系统中,如何确认一个节点是否工作正常?如果有5副本1-5,。其中1号为主副本

在分布式中最直观的处理方法是在每个副本与主副本维护一个心跳,期望通过心跳是否存在而判断对方是否依旧存活。
心跳方法其实根本无法解决分布式下节点是否正常的这个问题。考虑如下场景:


主要解决思路有四种:


在01:05期间如果出现网络抖动导致其他节点申请Lease会申请失败,因为中心节点在01:10之前都会承认有主节点,不允许其他节点再申请Lease




Lease时间长短一般取经验值1-10秒即可。太短网络压力太大,太长则收回承诺时间过长影响可用性