分布式一致性算法 2PC与3PC

2022年9月17日12:14:37

引出

分布式一致性

我们的数据不可能只保存一份一旦数据出错就完了。那么我们可以把数据备份,比如将数据保存三份。
在分布式系统中,为了保证数据的高可用,通常,我们会将数据保留多个副本(replica),这些副本会放置在不同的物理的机器上。

但是不同机器上的副本如何保证一致性,也就是说有一个机器数据更新了,而另一个机器上数据没更新,或者说另一个数据更新不及时,则会导致一个问题就是查询到数据不一致

为了对用户提供正确的增\删\改\差等语义,我们需要保证这些放置在不同物理机器上的副本是一致的。这个就叫分布式(事务)的一致性。

为什么也叫分布式事务一致性呢?

当我们单个数据库时候我们知道有事务这个概念:在单个数据库,事务机制保证ACID,即某一系列操作全部执行或者全部不执行。

分布式事务是指会涉及到操作多个数据库的事务。其实就是将对同一库事务的概念扩大到了对多个库的事务。各个节点之间相互独立,通过网络进行沟通。
但是多节点情况下,不同节点之间无法知道其他事务执行情况。所以从理论上讲,两台机器理论上无法达到一致的状态。

如果想让分布式部署的多台机器中的数据保持一致性,那么就要保证在所有节点的数据写操作,所有机器的操作,要不全部都执行,要么全部都不执行

解决方案

https://www.hollischuang.com/archives/681

为了解决这种分布式一致性问题,前人在性能和数据一致性的反反复复权衡过程中总结了许多典型的协议和算法。其中比较著名的有二阶提交协议、三阶提交协议和Paxos算法。

分布式一致性算法 2PC与3PC

但是,一台机器在执行本地事务的时候无法知道其他机器中的本地事务的执行结果。所以他也就不知道本次事务到底应该commit还是 roolback。所以,常规的解决办法就是引入一个“协调者”的组件来统一调度所有分布式节点的执行。

事务的提交与回滚

开启一个事物 start transaction
begin;
update tb_account set balance=balance-1000
where accid=‘1111’;
update tb_account set balance=balance+1000
where accid=‘2222’;
commit; – 提交 才能改变(写盘)
rollback; – 撤销

几种分布式算法

  • 分布式均衡算法:一致性hash,解决将数据均匀分布到不同机器,他考虑到了增加或者删除机器的情况,也有pg。但是没有在ceph中使用,一般在添加缓存服务器中使用。Consistent Hashing是为了解决单副本情况下的数据分布问题,比如说分布式缓存,并没有涉及多副本/EC场景,它类似于Ceph中object->PGs这段的工作;
  • crush算法:解决将pg分布到OSD
  • 分布式一致性(事务)算法:paxos, raft: 解决所有节点具有一致性,也就是所有节点数据统一,解决选举leader问题

2PC

https://blog.csdn.net/lengxiao1993/article/details/88290514

概念

两阶段提交又称2PC,2PC是一个非常经典的强一致、中心化的原子提交协议。

这里所说的中心化是指协议中有两类节点:一个是中心化协调者节点(coordinator)和N个参与者节点(partcipant)。

两个阶段是指:第一阶段:准备阶段(投票阶段)和第二阶段:提交阶段(执行阶段)。
第一阶段:协作者广播VOTE_REQUEST,等待commit或者abort
第二阶段:协作者根据收回的ack,广播一个全局commit或者abort

过程

第一阶段

  1. 协调者 向所有的 参与者 发送事务预处理请求,称之为Prepare,并开始等待各 参与者 的响应。
  2. 各个 参与者 节点执行本地事务操作,但在执行完成后并不会commit数据库本地事务,而是先向 协调者 报告说:我准备好提交了Yes或者我没准备好弄no
    第一阶段执行完后,会有两种可能。1、所有都返回Yes. 2、有一个或者多个返回No。

第二阶段
3. 如果所有参与者都返回yes,那么协调者向所有参与者发送commit命令,参与者都本地commit,在完成提交之后释放整个事务执行期间占用的事务资源。
4. 如果其中有参与者返回no或者超时没有返回,则协调者向所有参与者发送rollback请求,也就是撤销,将本地事务回滚,不commit。

优缺点

优点:2PC的优点是很显然的,原理简单,实现方便。他解决1PC的一个问题就是:如果协调者发送给参与者说进行事务提交操作,但是其中只有部分参与者可以执行,有参与者不能执行,这样就出现不一致的问题。而2PC确保所有节点都可以执行commit的时候才执行,确保数据的一致性。

目前,绝大多数关系型数据库都是采用两阶段提交协议来完成分布式事务处理的。

缺点:1.性能:所有的参与者资源和协调者资源都是被锁住的,只有当所有节点准备完毕,事务 协调者 才会通知进行全局提交
2. 单节点故障,协调者故障就没办法工作
3. 发生在第二阶段 并且 有部分参与者已经执行完commit操作,但是有节点故障,并不能完成commit。虽然这个时候可以再通过手段让他和协调者通信,再想办法把数据搞成一致的,但是,这段时间内他的数据状态已经是不一致的了! 2PC 无法解决这个问题。

3PC

https://www.jianshu.com/p/0829d8abccdf
https://www.cnblogs.com/qdhxhz/p/11167025.html
三阶段提交协议(3PC)主要是为了解决2PC提交协议的阻塞问题
2pc存在的问题是当协作者崩溃时,参与者不能做出最后的选择。因此参与者可能在协作者恢复之前保持阻塞。
三阶段提交(Three-phase commit),是二阶段提交(2PC)的改进版本。

过程

3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有CanCommit、PreCommit、DoCommit三个阶段。

  1. CanCommit阶段其实和2PC的准备阶段很像。协调者向参与者发送commit请求,参与者如果可以提交就返回Yes响应,否则返回No响应。这时参与者并不执行事务,而只是说我是否准备好了。
  2. PreCommit操作。根据响应情况,有以下两种可能。假如协调者从所有的参与者获得的反馈都是Yes响应,那么就会执行事务的预执行。执行事务,但是不commit。
  3. docommit.发送提交请求 协调接收到参与者发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有参与者发送doCommit请求。

在doCommit阶段,如果参与者无法及时接收到来自协调者的doCommit或者rebort请求时,会在等待超时之后,会继续进行事务的提交。(一旦参与者收到了PreCommit,意味他知道大家其实都同意修改了)所以,一句话概括就是,当进入第三阶段时,由于网络超时等原因,虽然参与者没有收到commit或者abort响应,但是他有理由相信:成功提交的几率很大。 )

优缺点

  • 优点:相对于2PC,3PC主要解决解决了2pc存在单点故障,导致节点持久阻塞的问题,降低了整个事务的阻塞时间和范围,3PC一旦参与者无法及时收到来自协调者的信息之后,他会默认执行commit,而2PC会一直持有事务资源并处于阻塞状态。缺点:但是这种实现就可能导致一致性的问题。
  • 优点2:多设置了一个缓冲阶段保证了在最后提交阶段之前各参与节点的状态是一致的。

总结

2PC和3PC都无法彻底解决分布式一致性问题。paxos发明者说过:世上只有一种一致性算法,那就是Paxos,所有其他一致性算法都是Paxos算法的不完整版。后面有机会讲Paxos。

参考文献

https://www.hollischuang.com/archives/681
https://blog.csdn.net/qq_21033663/article/details/78522557?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_baidulandingword~default-0.no_search_link&spm=1001.2101.3001.4242.1
https://www.jianshu.com/p/0829d8abccdf

  • 作者:Charles Ren
  • 原文链接:https://chongbin.blog.csdn.net/article/details/121249419
    更新时间:2022年9月17日12:14:37 ,共 3459 字。