这是我参与「第五届青训营 」伴学笔记创作活动的第 6 天
对课程中学到的重要知识点做了笔记,方便后续的回顾
1. 分布式事务
比较难的方向,很多系统都避免产生分布式事务
什么是分布式事务:
- 对应着本地的数据库的事务,当系统扩展到了微服务级别,就延伸到了分布式事务
- 存储端的复杂性
- 本地事务的情况下,所有数据都会落到同一个DB中,在分布式的情况下,就会出现数据可能要落到多个DB,或者还会落到Redis,落到MQ等中
- 事务链路的延展性
- 本地实现的事务,通常会被封装到一个服务中,但是到了微服务的实现,由于调用链路的边长,会导致事务可能跨越了多个微服务,呈现线状或网状
- 例子
- 比如在电商项目中,用户进行下单,需要对数据库做减少库存操作,但是由于网络问题,微服务端没有返回减少库存成功,于是本地事务失败了,回滚了用户的操作,导致两端的数据库内容不一致了 为了解决以上的问题,提供了下面两种解决思路
1.1 两阶段提交
二阶段提交(Two-phase Commit):为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种演算法。
三个假设:
- 引入协调者(Coordinator)和参与者(Participants),互相进行网络通信,一个协调者,两个参与者
- 所有节点都采用预写式日志,且日志被写入后即被保持在可靠的存储设备上
- 所有节点不会永久性损坏,即使损坏后仍然可以恢复
可能出现的情况:
- 情况1) Coordinator不宕机,Participant宕机,需要进行回滚操作
- 情况2) Coordinator宕机,Participant不宕机。可以起新的协调者,待查询状态后,重复二阶段提交
- 情况3) Coordinator宕机,Participant宕机。
回滚:在Prepare阶段,如果某个事务参与者反馈失败消息,说明该节点的本地事务执行不成功,必须回滚。
情况3∶无法确认状态,需要数据库管理员的介入,防止数据库进入一个不一致的状态。
两阶段提交需注意的问题
- 性能问题
- 两阶段提交需要多次节点间的网络通信,耗时过大,资源需要进行锁定,徒增资源等待时间。
- 协调者单点故障问题
- 如果事务协调者节点宕机,需要另起新的协调者,否则参与者处于中间状态无法完成事务。
- 网络分区带来的数据不一致
- 一部分参与者收到了Commit消息,另一部分参与者没收到Commit消息,会导致了节点之间数据不一致。
思考
- 日志被保存在「可靠」的存储设备上。如何保证这一点?
- 参与者Commit了,但Ack信息协调者没收到。怎么办?
1.2 三阶段提交
1.3 MVCC
2. 共识协议
2.1 Quorum NWR模型
2.2 raft协议
2.3 Paxos协议
主要讲解了和raft的区别
- 所有的节点都可以成为leader,所有节点都可以成为follower
- Paxos允许并发修改日志,raft只能是有序的
- 没有一个节点有完整的最新的数据,恢复流程复杂,需要同步历史记录
3. 分布式实践
3.1 MapReduce
3.2 分布式KV
课后个人总结
- 对分布式理论有了一些了解,自己又查找了一些分布式事务的相关资料
- 分布式事务,MVCC,raft协议都是经常用到的内容,etcd就是用的raft算法实现的,之后还需要加强了解