为什么要分布式
分布式是为了解决传统单点系统 性能低、可用性低、扩展性低的问题
基于分布式的目标,可以把分布式系统进行分类:
- 为了提高性能,应对高并发,海量数据处理,此类系统代表:无状态的微服务、分布式数据等
- 为了提高可用性,避免单点故障,同时保证数据的一致性,此类系统代表:注册中心、集群协调器等
这里只讨论后者,为了提高可用性,某些关键应用需要集群部署,同时还要保证所有节点数据的一致性。
2PC(Two-phase Commit)
在分布式系统中,每个节点虽然可以知晓自己的操作时成功或者失败,却无法知道其他节点的操作的成功或失败。当一个事务跨越多个节点时,为了保持事务的ACID特性,需要引入一个作为协调者的组件来统一掌控所有节点(称作参与者)的操作结果并最终指示这些节点是否要把操作结果进行真正的提交(比如将更新后的数据写入磁盘等等)。因此,二阶段提交的算法思路可以概括为: 参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作
2PC前提
- 该分布式系统中,存在一个节点作为协调者(Coordinator),其他节点作为参与者(Participants)。且节点之间可以进行网络通信。
- 所有节点都采用预写式日志 (redo undo log),且日志被写入后即被保持在可靠的存储设备上,即使节点损坏不会导致日志数据的消失。
- 所有节点不会永久性损坏,即使损坏后仍然可以恢复。
算法实现
第一阶段(提交请求阶段)
- 协调者向所有参与者节点是否可以执行提交操作,并等待各节点的响应。
- 各参与者执行协调者发起的事务,并写入
undo
和redo
Log。 - 各参与者响应协调者发起的询问。若事务操作执行成功,则返回‘同意’,若执行失败,则返回一个‘终止’信息。
第二阶段 (提交执行阶段)
成功(各参与者均返回同意)
- 协调者向所有参与者发起 “正式提交” 请求。
- 参与者正式完成操作,并释放事务所占的资源(主要是锁)。
- 参与者向协调者发送“完成事务”通知。
- 协调者收到各参与者的“完成”通知之后,完成事务。
失败 (任意节点返回终止,或超时未返回)
- 协调者向所有参与者发起“回滚”请求。
- 参与者利用之前记录的
undo
日志,进行回滚。 - 参与则会通知协调者,回滚成功。
- 协调者收到回滚成功消息之后,取消事务。
算法示意
算法劣势
- 提交性能由参与者中最慢的节点决定,往往较慢。
- 无法提交阶段若有节点失联,无法处理。
一旦做出决定就无法撤销。
- 参与者不论能否提交,在响应协调者之后,必须持有资源,等待协调者通知。
- 协调者一旦决定提交,则所有参与者必须提交,若有节点暂时失联,也需要等待节点恢复之后进行提交。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。