全局一致性
AntDB 的集群架构包括,一个 GTM(Global Transaction Manager)、多个Coordinator(CN)、多个 Datanode(DN)。其中 GTM 负责给其他的 DN 和CN 分发集群全局唯一的事务号和集群当前判断可见性的 SnapShot。CN 为计算节点,负责接收客户端连接,并且做词法、语法和语义分析,还会判断语句或者执行计划需要发送到哪些 DN。DN 为存储节点,负责存储最终的数据信息。
AntDB 采用与 PGXC 一样的 2PC 两阶段协议来保证分布式数据库一致性。假设用户A 向用户 B 转账,用户A 需要转账 50 元给用户B。用户 A 的数据分片在 DN1 上,用户 B 的数据分片在 DN2 上。CN1 连接到 DN1 和 DN2,分别对用户A 数据减去 50,用户 B 数据加上 50,最终 CN1 需要commit 提交的时候, 需要分别到 DN1 和 DN2 上做两阶段提交。
2PC协议和Paxos协议
在数据库领域,提到分布式系统,就会提到分布式事务。Paxos 协议与分布式事务并不是同一层面的东西。分布式事务的作用是保证跨节点事务的原子性,涉及事务的节点要么都提交(执行成功),要么都不提交(回滚)。分布式事务的一致性通常通过 2PC(Two-Phase Commit)来保证,这里面涉及一个协调者(CN)和若干个参与者(DN)。第一阶段,协调者询问参与者事务是 否可以执行,参与者回复同意(本地执行成功),回复取消(本地执行失败)。第二阶段,协调者根据第一阶段的投票结果进行决策,当且仅当所有的参与者同意提交事务时才会提交,否则回滚。2PC 的最大问题是,协调者是单点(需要有一个备用节点),另外协议是阻塞协议,任何一个参与者故障,都需要等待(可以通过加入超时机制)。
Paxos 协议用于解决多个副本之间的一致性问题。比如日志同步,保证各个节点的日志一致性,或者选主(主故障情况下),保证投票达成一致,选主具有唯一性。简而言之,2PC 用于保证多个数据分片上事务的原子性,Paxos 协议用于保证同一个数据分片在多个副本的一致性,所以两者是互补的关系, 而不是替代关系。对于 2PC 协调者单点问题,可以利用 Paxos 协议解决,即当协调者出问题时,选一个新的协调者继续提供服务。工程实践中,Google Spanner、Google Chubby 就是利用 Paxos 来实现多副本日志同步。当前 AntDB 还尚未引入 Paxos 协议,下一步考虑使用 Paxos 协议来实现分布式模式下“一主多备”的高可用。
2PC 流程在 AntDB 内部流程如图 3-6 所示。
(1)CN1 从 GTM 请求并获得,集群全局,SnapShot。
(2)CN1 从 GTM 请求并获得,集群全局唯一 TransactionID ,事务号 100。
(3)CN1 到 DN1 上对用户 A 减去 50,同时到 DN2 上对用户 B 加上 50。
(4)CN1 分别操作用户 A 和用户 B 的数据成功后,需要提交该事务。两阶段的第一阶段,分别到 DN1 和 DN2 预提交。即 prepare transaction T100。
(5)DN1 和 DN2 都能预提交成功并且成功返回 ACK。
(6)CN1 本地结束事务号 100。
(7)CN1 分别到 DN1 和 DN2 上进行两阶段的第二阶段,真正地提交
T100。
(8)DN1 和 DN2 提交成功并且成功返回 ACK。
如果第(5)步,任何一个节点返回预提交失败,第(6)、(7)步分别需要本地 rollback 和两阶段第二阶段 rollback prepared T100。这样就能实现两个或多个节点,同时成功或同时失败。
AntDB 5.0 优化了 GTM 事务号和 SnapShot 分发流程,减少了 CN 和 GTM的实时交互,并实现了一种 CN 在本地获取 SnapShot 的方法。AntDB CN/DN申请和结束事务号流程如图 3-7 所示。
(1)Client CN1 某一个连接进程需要获取事务号,发送请求给本地进程SnapRcv。SnapRcv 与 GTM SnapSender 有 TCP 长连接。SnapRcv 发送申请事务号请求给 GTM SnapSender 获取事务号。
(2)GTM SnapSender 收到申请事务号请求,在本地获取集群全局唯一事务号,返回给 SnapRcv,同时放入待分发事务号列表中,触发 GTM SnapSender 去处理待分发和待结束事务号列表。
(3)Client CN1 SnapRcv 收到返回的事务号后,通知 Backend 服务进程,
Backend 继续处理。
(4)GTM 处理事务号分发列表,把 CN1 申请的事务号发送给所有的SnapRcv Client。所有的 SnapRcv 收到 GTM SnapSender 分发的事务号,放入SnapRcv 活跃事务号列表中。
(5)Backend 结束事 务 号,SnapRcv 发送结 束事务号 请求到 GTM SnapSender。
(6)GTM SnapSender 收到 SnapRcv 请求,把要结束的事务号放入待结束事务号列表,立即返回给 Client,同时触发 GTM SnapSender 处理分发和结束事务号列表。
(7)CN1 SnapRcv 收到结束事务号返回,结束该 Backend 进程等待。
Backend 继续处理。
(8)GTM SnapSender 发送结束事务号消息到所有的 SnapRcv。SnapRcv
收到消息后,从活跃事务号列表中剔除要结束的事务号。
SnapRcv 发送包括申请和结束事务号消息,为Backend 进程服务。SnapRcv 接收申请事务号和结束事务号相对应,返回给等待的 Backend 进程。SnapRcv 接收 GTM SnapSender 分发和结束的事务号列表,来更新到本地共享内存中。SnapRcv 维护集群活跃事务号列表,提供给本地 Backend 获取 Snapshot。