分布式一致性协议
- 二阶段提交协议(2pc)
- 三阶段提交协议(3pc)
- paxos
- zab
在分布式系统中,每个机器都可以确定自己进行的事务操作是否成功,但是无法直接了解其他机器的操作结果。因此,当一个分布式事务操作需要保持ACID 特性时,就需要一个“协调者”节点调度其他“参与者”节点来进行分布式事务操作。
二阶段提交(2pc)
提交事务请求 -> 执行事务提交;缺点:同步阻塞(参与者之间阻塞)、单点问题,脑裂(导致数据不一致问题);主要用于关系型数据库中,解决了分布式事务的原子性问题;
1. 提交事务请求
- 协调者向参与者发送事务,并询问是否可以执行事务提交操作,等待参与者响应;
- 参与者执行事务,将操作写入本地事务日志,向协调者发送反馈;
2. 执行事务提交
参与者反馈,全部ACK
- 协调者向参与者发送Commit;
- 参与者执行事务提交,释放事务资源,反馈ACK,;
- 协调者收到反馈完成事务
参与者反馈,存在NO;协调者等待超时
- 协调者向参与者发送RollBack;
- 参与者利用undo,进行事务回滚;
- 参与者事务回滚之后,向协调者发送ACK 反馈;
- 协调者接收到ACK,完成事务中断;
三阶段提交(3pc)
cancommit -> precommit -> docommit;优缺点:降低了参与者同步阻塞范围,但是又引入了数据不一致性问题(若出现网络分区)、单点问题依然存在;
1. CanCommit
- 协调者向参与者发送cancommit 请求(包含事务内容),等待参与者反馈;
- 参与者接收到cancommit 请求之后,反馈ACK或者NO;
2. PreCommit
参与者反馈,全部ACK
- 协调者向参与者发送precommit 请求,等待反馈;
- 参与者执行事务,将操作写入本地事务日志,向协调者发送反馈;
参与者反馈,存在NO;协调者等待超时
- 协调者向参与者发送abort 请求;
- 参与者无论是接收到abort 请求还是等待超时都会中断事务;
3. DoCommit
参与者反馈,全部ACK
- 协调者向参与者发送docommit 请求,等待反馈;
- 参与者执行事务提交,释放事务资源,反馈ACK,;
- 协调者接收反馈,完成事务提交;
参与者反馈,存在NO;协调者等待超时
- 协调者向参与者发送abort 请求;
- 参与者进行事务回滚;
- 参与者反馈ACK;
- 协调者接收到ACK,完成事务中断;
paxos 算法
- paxos 基于消息传递并具有高度容错性;
- paxos 算法的核心是,分布式系统如何就某个状态(提案)达成一致;
- paxos 算法假设不存在“拜占庭将军问题”;
- paxos 算法中的角色:proposer、acceptor、learner;
- proposer:发送提案;
- acceptor:裁决提案;只能批准一个提案;过半批准原则;
- learner:学习提案;
1. prepare 阶段(生成提案)
- proposer 提出编号为Mn 的提案,向acceptor 集合发送prepare 请求;
- acceptor 反馈;
- 保证不再接收编号小于Mn 的提案;
- 返回已经批准的,编号最大的提案的Value;
- 若Mn 小于已经批准的最大编号,则忽略Mn;(优化)
- proposer 收到过半响应,则发送accept 请求(Mn,Vn)给acceptor 集合;Vn 是接收回的最大编号提案的Value;若无Value 可选(acceptor 都未接收提案),Vn 可为任意值;
2. accept 阶段(批准提案)
acceptor 接收到accept 请求之后,只要Mn 不小于已接受提案最大的编号,则批准提案;
learner 获取提案(学习策略)
- 一旦提案被批准(过半),则发送给所有learner;
- 提案批准,则发送给一个learner,该learner再发送给其他learner;
- 提案批准,则发送给一个learner集合,该learner集合再发送给其他learner;
优化
问题:proposer1 与 proposer2 两者陷入死循环;
解决:选出主proposer,只要主proposer 和 过半acceptor 能保持正常,那么但凡主proposer 能提出一个编号更高的提案,这个提案最终将会批准;
应用
chubby:分布式锁、GFS 中 master 选举