这是我参与「第四届青训营」笔记创作活动的的第7天
为什么需要分布式协议?
在古代战争时期,各个将军在外征战,各处天南地北,打仗时只能靠传信兵交流。为了统一战线,一同进退,就需要一位大帅坐镇中枢,通过传信兵发放军令。撤退时,一起撤退保存兵力,进攻时,共同进攻,打败敌人。但是这里也有个问题,如果传令兵在中途被人截杀怎么办?被人收买怎么办?或者遇到突发状况没有及时传到怎么办?
分布式协议就是为了解决分布式系统中各个节点数据一致性问题,一些经典的协议有2PC,3PC,Paxos和Raft等。
2PC
分布式系统中的各个节点都能明确知道自己的事务是成功还是失败,但无法直接获取到其它节点的事务结果,为了保证事务的ACID特性,于是引入了“协调者”来调度各个节点,被调度的结点叫“参与者”,协调者负责调度这些参与者的行为,并最终决定这些参与者是否要提交事务。
2PC主要是分为两个阶段:
阶段一:提交事务请求(投票阶段)
-
事务询问:协调者向所有参与者发送事务内容,询问是否可以执行事务提交操作,并开始等参与者响应。
-
执行事务:各个参与者执行事务操作,并且把Undo和Redo信息记录到事务日志中。(Redo用来保证事务的原子性和持久性,Undo能保证事务的一致性,两者都是系统恢复的基础前提)
-
各参与者向协调者反馈事务询问的响应:如果参与者成功执行了事务操作,那么就反馈yes,表示事务可以执行;如果参与者没有成功执行事务,就返回no。
阶段二:事务提交
如果所有参与者返回的都是yes,那么就会进行事务提交
- 发送提交请求:协调者向所有参与者发送commit请求
- 事务提交:参与者受到commit请求后,开始提交事务,并释放整个事务期间占用的资源
- 反馈事务提交结果:参与者提交事务之后,会向协调者返回ack信息
- 完成事务:协议调者受到所有参与者的ack信息,完成事务。
如果有个参与者返回了no,或者有参与者超时没有响应,那么就进行事务中断。
-
发送回滚请求:协调者向所有参与者发送rollback请求
-
事务回滚:参与者受到rollback请求后,利用undo信息执行事务回滚,并释放资源
-
反馈事务回滚结果:参与者完成回滚之后,向协调者发送ack信息
-
中断事务:协调者收到所有事务的ack信息,完成事务中断。
-
发送回滚请求:协调者向所有参与者发送rollback请求
-
事务回滚:参与者受到rollback请求后,利用undo信息执行事务回滚,并释放资源
-
反馈事务回滚结果:参与者完成回滚之后,向协调者发送ack信息
-
中断事务:协调者收到所有事务的ack信息,完成事务中断。