分布式系统中的数据库事务 | 青训营笔记

2023-03-06 18:47:08 浏览数 (2)

分布式系统中的数据库事务 | 青训营笔记

这是我参与「第五届青训营」伴学笔记创作活动的第 8 天

前言

本文简述了在分布式系统中使用的分布式数据库事务方案。

什么是分布式

分布式系统是计算机程序的集合,这些程序利用跨多个独立计算节点的计算资源来实现共同的目标。可以分为分布式计算,分布式存储,分布式数据库等。

在分布式系统中,由于不同节点可能维护各自的数据库,但这些数据库有需要保持同步,这就可能引发同步问题。

为了解决这些问题,我们引入分布式事务的解决方案。

分布式事务

在分布式事务中,有多种处理方案可以在不同程度上解决我们的问题:

二阶段提交

二阶段提交(Two-phase Commit)是为了使基于分布式系统架构下的所有节点在进行事务提交时保持一致性而设计的一种演算法。

在二阶段提交算法中,我们需要引入三个假设:

  1. 引入协调者(Coordinator)和参与者(Participants),互相进行网络通信
  2. 所有节点都采用预写式日志,且日志被写入后即被保持在可靠的存储设备上
  3. 所有节点不会永久性损坏,即使损坏后依然可以恢复

在以上三个假设中,二阶段提交算法以如下方式工作:

  1. 协调者作为一个中心节点,负责处理参与者之间可能存在的冲突,参与者负责提交事务并告知协调者。
  2. 当希望提交事务时,会先进入 Prepare 阶段,协调者向参与者发送询问信息,参与者执行事务,但不提交,返回自己当前的状态是否正常。
  3. 当所有参与者返回正常的确认信号后,进入 Commit 阶段,协调者即可通知参与者进行事务的 commit,并收到 Ack 信号确认 commit 完成。

此时,可能出现以下异常情况:

  • 协调者未宕机,但参与者宕机,Prepare 阶段的参与者向协调者返回错误信号;此时协调者将通知所有参与者对已进行的 commit 进行 rollback 操作以保证数据一致。
  • 协调者宕机,但参与者未宕机,此时只需更换新的协调者,然后重新进行二阶段提交即可。
  • 协调者和参与者均宕机,此时由于无法确认状态,需要数据库管理员接入,防止数据库进入不一致的状态。

二阶段提交算法一定程度上解决了分布式事务提交的数据不一致问题,但也存在缺陷:

  1. 性能问题。二阶段提交需要多次节点间的网络通信,耗时过大,同时资源需要进行锁定,徒增资源等待时间。
  2. 协调者单点故障问题。如果事务协调者节点宕机,需要另起新的协调者,否则参与者处于中间状态无法完成事务。
  3. 网络分区带来的数据不一致问题。一部分参与者收到了 commit 消息,另一部分参与者没收到 commit 消息,导致节点之间数据的不一致。

三阶段提交

三阶段提交在二阶段提交的基础上进行了优化,以解决二阶段提交单点故障和阻塞的问题。

三阶段提交将 Prepare 阶段进一步拆分,得到 CanCommit,PreCommit,DoCommit 三个阶段:

  1. 首先,在 CanCommit 阶段,协调者会询问各个参与者是否能够正确执行事务,参与者会根据自身状况返回一个预估值(此时并为真正执行事务)。
  2. 进入 PreCommit 阶段,协调者根据 CanCommit 阶段的结果采取操作。如果所有参与者均返回确认信息,则向所有参与者发送事务执行通知,参与者收到通知后执行事务,但不提交,然后将事务执行情况返回给协调者;如果一个或多个参与者返回等待信息,亦或者协调者等待参与者返回确认信息超时,则会直接中断事务。
  3. 进入 DoCommit 阶段,如果 CanCommit 阶段的事务未发生中断,则协调者会根据事务执行返回的结果来决定提交或回滚事务。如果所有的参与者都能正常执行事务,则协调者会向所有参与者发送事务 commit 通知,参与者在收到通知后会进行 commit 操作,然后向协调者返回提交结果;如果一个或多个参与者执行事务失败,或参与者等待协调者返回信息超时,则协调者会要求所有参与者 rollback 事务,并反馈 rollback 结果。

在本阶段如果因为协调者或网络问题,导致参与者迟迟不能收到来自协调者的 commit 或 rollback 请求,那么参与者将不会如两阶段提交中那样陷入阻塞,而是等待超时后继续 commit,相对于两阶段提交虽然降低了同步阻塞,但仍然无法完全避免数据的不一致。

MVCC

多版本并发控制(MCC 或 MVCC)是数据库管理系统常用的一种并发控制方法,用于提供对数据库的并发访问,并以编程语言实现事务内存。 —— Wikipedia

MVCC 是一种并发控制的方法,维持一个数据的多个版本使读写操作没有冲突。所以既不会阻塞写,也不会阻塞读。MVCC 为每个修改保存一个版本,和事物的时间戳相关联。可以提高并发性能,解决脏读的问题。

引用

该文章部分内容来自于以下课程或网页:

  • 「分布式理论 – 现代架构基石」第五届字节跳动青训营 – 后端专场
  • cap – 分布式事务:两阶段提交与三阶段提交 – 个人文章 – SegmentFault 思否
  • Multiversion concurrency control – Wikipedia

0 人点赞