阿里云RDS金融数据库(三节点版) - 理论篇

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 标签 PostgreSQL , MySQL , 三节点版 , 金融数据库 , Raft , 分布式共享存储版 背景 《阿里云RDS金融数据库(三节点版) - 背景篇》说明了为什么需要推出金融级数据库的三节点版本,以及三节点引入的一个世界难题 - 拜占庭将军问题。

标签

PostgreSQL , MySQL , 三节点版 , 金融数据库 , Raft , 分布式共享存储版


背景

《阿里云RDS金融数据库(三节点版) - 背景篇》说明了为什么需要推出金融级数据库的三节点版本,以及三节点引入的一个世界难题 - 拜占庭将军问题。

Lamport 在论文 《The Part-Time Parliament》中提出了一种算法Paxos,并使用了大量的数学公式论证了通过Paxos算法解决拜占庭问题的可行性。紧接着在《Paxos Made Simple》论文中,则完全放弃了所有数学符号的证明,使用纯英文的逻辑推导。原因是 Lamport 认为 Paxos 很 simple,但也许只是针对他的头脑而言。事实是大家理解起来都还是很困难,所以 Raft 就是建立在希望得到一个更易于理解的 Paxos 算法的替代品。把可理解性作为算法的主要目标之一,从论文题目就可看出来《In Search of an Understandable Consensus Algorithm》。

拜占庭将军的问题和三节点选举主节点的问题类似,Raft是目前一种非常流行可靠(在有限前提下)的选举算法,也是RDS 金融数据库(三节点版)的理论基础,RDS对其算法与数据库进行融合,弥补了一些算法的缺陷,实现了高可用、高可靠兼具的金融数据库(三节点版)。  

Raft 协议的易理解性描述

在一个由 Raft 协议组织的集群中有三类角色:

1、Leader(领袖)

2、Follower(群众)

3、Candidate(候选人)

就像一个民主社会,领袖由民众投票选出。刚开始没有“领袖”,所有集群中的参与者都是“群众”,那么首先开启一轮大选,在大选期间所有群众都能参与竞选,这时所有群众的角色就变成了“候选人”,民主投票选出领袖后就开始了这届领袖的任期,然后选举结束,所有除领袖的候选人又变回群众角色服从领袖领导。这里提到一个概念「任期」,用术语 Term 表达(Term ID是自增的,每一轮成功的选举都会产生一个新的Term ID,注意所有角色发现了新Term ID时自动服从他,解决了脑裂的问题)。关于 Raft 协议的核心概念和术语就这么多而且和现实民主制度非常匹配,所以很容易理解。三类角色的变迁图如下,结合后面的选举过程来看很容易理解。

pic

三种角色的转变说明如下:

1、Follower(群众)

所有节点一开始都是Follower。

Follower在150ms ~ 300ms的随机超时时间(Election Timeout)内,如果没有收到任何Leader发过来的心跳消息,将会转变为Candidate,给自己投票,同时请求其他人给自己投票,同时重置150ms ~ 300ms的随机超时时间。

2、Candidate(候选人)

Candidate在150ms ~ 300ms的随机超时时间内,没有发生角色变化(即没有转换为new Leader的Follower,也没有获得足够的票数转换为Leader),那么将重新发起选举(给自己投票,同时请求其他人给自己投票,同时重置150ms ~ 300ms的随机超时时间。)

在选举过程中,Candidate获得了多数票数,则转换为new Leader。

Candiate发现了当前任期(自选任期)或更新任期的Leader时(即收到Leader发来的心跳),转变为该Leader的Follower。

3、Leader(领袖)

Leader发现了更新任期的Leader时,转变为新任期Leader的Follower。

客户端视角事务的三种状态

不管是三节点还是单节点,都可能会出现这几种状态。

1、提交、回滚成功。客户端正常收到数据库的事务结束的信号,明确事务成功按要求结束。

2、UNKNOWN。客户端发出了提交、回滚请求,但是未收到反馈。

3、提交失败。客户端收到事务结束失败的信号,明确事务失败。

无论是单节点还是多节点,都会有这三种事务状态的可能存在。

Leader 选举过程

在极简的思维下,一个最小的 Raft 民主集群需要三个参与者(如下图:A、B、C),这样才可能投出多数票。初始状态 ABC 都是 Follower,Follower在150ms ~ 300ms的随机超时时间内,如果没有收到任何Leader发过来的心跳消息,将会转变为Candidate,给自己投票,同时请求其他人给自己投票,同时重置150ms ~ 300ms的随机超时时间。

发起选举这时有三种可能情形发生。下图中前二种都能选出 Leader,第三种则表明本轮投票无效(Split Votes),每方都投给了自己,结果没有任何一方获得多数票。之后每个参与方随机休息一阵(Election Timeout)重新发起投票直到一方获得多数票。这里的关键就是 随机 timeout,最先从 timeout 中恢复发起投票的一方向还在 timeout 中的另外两方请求投票,这时它们就只能投给对方了,很快达成一致。

pic

选出 Leader 后,Leader 通过定期(heart timeout,heart timeout必须小于150ms)向所有 Follower 发送心跳信息维持其统治,每次Follower收到Leader心跳后,重置随机Election Timeout。

若 Follower 一段时间(Election Timeout)未收到 Leader 的心跳则认为 Leader 可能已经挂了,Follower将发起选主(election)过程。

Leader 节点对一致性的影响

Raft 协议强依赖 Leader 节点的可用性来确保集群数据的一致性。数据的流向只能从 Leader 节点向 Follower 节点转移。当 Client 向集群 Leader 节点提交数据后,Leader 节点接收到的数据处于未提交状态(Uncommitted),接着 Leader 节点会并发向所有 Follower 节点复制数据并等待接收响应,确保至少集群中超过半数节点(quorum based)已接收到数据后再向 Client 确认数据已接收。一旦向 Client 发出数据接收 Ack 响应后,表明此时数据状态进入已提交(Committed),Leader 节点再向 Follower 节点发通知告知该数据状态已提交。

步骤4.1成功,客户端就认为事务提交成功,换句话说事务已经持久化了。

因此4.2如果没有发送成功,并且此时如果Leader异常,并发生了重新选举,有没有风险?New Leader的这笔事务到底是commit还是uncommit?

对于数据库来说,只要事务的WAL日志到位了,那么就该事务就持久化了,由于Follower已经有了WAL,因此数据库是不会让这笔事务丢失的,这也是ACID的D持久化,即用户看到COMMIT了,那就一定COMMIT了(开启异步提交遇到异常DOWN库或DOWN机除外)。

pic

在这个过程中,主节点可能在任意阶段挂掉,看下 Raft 协议如何针对不同阶段保障数据一致性的。

1. 数据到达 Leader 节点前

这个阶段 Leader 挂掉不影响一致性,不多说。

pic

2. 数据到达 Leader 节点,但未复制到 Follower 节点

这个阶段 Leader 挂掉,数据属于未提交(uncommit)状态,Client 不会收到 Ack 会认为超时事务失败。Follower 节点上没有该数据,重新选主后 Client 重试 (重新发起整个事务请求) 重新提交可成功。原来的 Leader 节点恢复后作为 Follower 加入集群重新从当前任期的新 Leader 处同步数据,强制保持和 NEW Leader 数据一致。

(为了达到一致,这里涉及到OLD Leader rewind的操作。)

pic

3. 数据到达 Leader 节点,成功复制到 Follower 所有节点,但还未向 Leader 响应接收

这个阶段 Leader 挂掉,同时数据在 Follower 节点处于未提交状态(Uncommitted)但保持一致,重新选出 Leader 后可完成数据提交,此时 Client 不知到底提交成功没有,也就是说客户端视角事务状态为UNKNOWN。

但是对于NEW Leader,和OLD Leader的数据是一致的。

pic

如何解决UNKNOWN的事务,后面的系列文章会讲到。

4. 数据到达 Leader 节点,成功复制到 Follower 部分节点,但还未向 Leader 响应接收

这个阶段 Leader 挂掉,数据在 Follower 节点处于未提交状态(Uncommitted)且不一致,Raft 协议要求投票只能投给拥有最新数据的节点。所以拥有最新数据的节点会被选为 Leader 再强制同步数据到其他 Follower,数据不会丢失并最终一致。

与第三种情况类似,此时 Client 不知到底提交成功没有,也就是说客户端视角事务状态为UNKNOWN。

但是对于NEW Leader,和OLD Leader的数据是一致的。

pic

5. 数据到达 Leader 节点,成功复制到 Follower 所有或多数节点,数据在 Leader 处于已提交状态,但在 Follower 处于未提交状态。(实际上就是图中标注的4.2步骤没有被执行)

这个阶段 Leader 挂掉,重新选出新 Leader 后的处理流程和阶段 3 一样。

这个情况下,Follower实际上已经包含了最新的数据库WAL日志,NEW Leader只要APPLY WAL即可达到事务committed的最终状态,不会丢失数据,也不会改变客户端视角对事务提交成功状态的认知。

pic

6. 网络分区导致的脑裂情况,出现双 Leader

网络分区将原先的 Leader 节点和 Follower 节点分隔开,Follower 收不到 Leader 的心跳将发起选举产生新的 Leader。这时就产生了双 Leader,原先的 Leader 独自在一个区,向它提交数据不可能复制到多数节点所以“永远提交不成功”

(虽然提交不成功,从数据库WAL日志角度来看,依旧可能出现 旧Leader 和 新Leader 存在差异的情况。例如 旧Leader 接收到某些请求,产生了WAL,只是提交事务的信息由于无法到达多数派,旧Leader是不会向客户端返回commit ack的,因此向OLD Leader发起事务提交请求的客户端会超时失败。)。

客户端向新的 Leader 提交数据可以提交成功。

网络恢复后 旧Leader 发现集群中有更新任期(Term)的新 Leader,旧Leader 自动降级为 Follower 并从 新Leader 处同步数据(对于数据库,可能OLD Leader首先要rewind,然后才能从NEW Leader同步)达成集群数据一致。

pic

一些逻辑定理:

1、永远不可能存在两个Term ID相同的Leader,因为同一个Term ID每个角色只有一票,所以绝对只有一个Leader得到多数票。

2、如果同时存在两个Leader,Term ID低的那个,事务提交一定会超时,因为它的Follower一定是不足的,副本数不足,永远不会返回Client ack。

综上穷举分析了最小集群(3 节点)面临的所有情况,可以看出 Raft 协议都能很好的应对一致性问题,并且很容易理解。

但是要结合数据库和Raft,实现金融级零数据丢失和一致性的数据库多副本产品,会更加复杂,例如rewind,以及UNKNOWN事务的处理(即使是单节点,依旧需要处理unknown事务)。

总结

算法以正确性、高效性、简洁性作为主要设计目标。

虽然这些都是很有价值的目标,但这些目标都不会达成直到开发者写出一个可用的实现。

所以我们相信可理解性同样重要。

Raft 算法是 2013 年发表的,大家在参考[5]上面可以看到有多少个不同语言开源的实现库了,这就是算法可理解性的重要性。

阿里云RDS金融数据库(三节点版)以Raft协议为基础,将重做日志的复制、选主与Raft进行结合,打造了一个可以同时满足可用性、可靠性,并保持高性能的金融级的数据库。

参考

[1]. LESLIE LAMPORT, ROBERT SHOSTAK, MARSHALL PEASE. The Byzantine General Problem. 1982

[2]. Leslie Lamport. The Part-Time Parliament. 1998

[3]. Leslie Lamport. Paxos Made Simple. 2001

[4]. Diego Ongaro and John Ousterhout. Raft Paper. 2013

[5]. Raft Website. The Raft Consensus Algorithm

[6]. Raft Demo. Raft Animate Demo

[7]. Raft 为什么是更易理解的分布式一致性算法

系列文章

《阿里云RDS金融数据库(三节点版) - 背景篇》

《阿里云RDS金融数据库(三节点版) - 理论篇》

《阿里云RDS金融数据库(三节点版) - 性能篇》

《阿里云RDS金融数据库(三节点版) - 案例篇》

阿里云RDS金融数据库(三节点版)

阿里云RDS金融数据库 - MySQL三节点版

阿里云RDS金融数据库 - PostgreSQL三节点版(敬请期待)

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
28天前
|
关系型数据库 分布式数据库 数据库
成都晨云信息技术完成阿里云PolarDB数据库产品生态集成认证
近日,成都晨云信息技术有限责任公司(以下简称晨云信息)与阿里云PolarDB PostgreSQL版数据库产品展开产品集成认证。测试结果表明,晨云信息旗下晨云-站群管理系统(V1.0)与阿里云以下产品:开源云原生数据库PolarDB PostgreSQL版(V11),完全满足产品兼容认证要求,兼容性良好,系统运行稳定。
|
1月前
|
缓存 安全 Java
阿里云数据库 SelectDB 内核 Apache Doris 2.0.6 版本正式发布
阿里云数据库 SelectDB 内核 Apache Doris 2.0.6 版本正式发布
|
1月前
|
SQL 安全 数据管理
在阿里云数据管理DMS(Data Management Service)中,您可以按照以下步骤来创建和管理数据库
【2月更文挑战第33天】在阿里云数据管理DMS(Data Management Service)中,您可以按照以下步骤来创建和管理数据库
37 7
|
1月前
|
SQL 关系型数据库 MySQL
阿里云MySQL数据库价格、购买、创建账号密码和连接数据库教程
阿里云数据库使用指南:购买MySQL、SQL Server等RDS实例,选择配置和地区,完成支付。创建数据库和账号,设置权限。通过DMS登录数据库,使用账号密码访问。同地域VPC内的ECS需将IP加入白名单以实现内网连接。参考链接提供详细步骤。
369 3
|
22天前
|
弹性计算 关系型数据库 MySQL
阿里云数据库服务器价格表,数据库创建、连接和使用教程
阿里云数据库使用流程包括购买和管理。选择所需数据库类型如MySQL,完成实名认证后购买,配置CPU、内存和存储。确保数据库地域与ECS相同以允许内网连接。创建数据库和账号,设置权限。通过DMS登录数据库,使用账号密码连接。同一VPC内的ECS需添加至白名单以进行内网通信。参考官方文档进行详细操作。
125 3
|
1月前
|
弹性计算 关系型数据库 MySQL
阿里云MySQL云数据库优惠价格、购买和使用教程分享!
阿里云数据库使用流程包括购买和管理。首先,选购支持MySQL、SQL Server、PostgreSQL等的RDS实例,如选择2核2GB的MySQL,设定地域和可用区。购买后,等待实例创建。接着,创建数据库和账号,设置DB名称、字符集及账号权限。最后,通过DMS登录数据库,填写账号和密码。若ECS在同一地域和VPC内,可内网连接,记得将ECS IP加入白名单。
438 2
|
1月前
|
存储 SQL 数据管理
阿里云数据库 SelectDB 内核 Apache Doris 如何基于自增列满足高效字典编码等典型场景需求|Deep Dive 系列
自增列的实现,使得 Apache Doris 可以在处理大规模时展示出更高的稳定性和可靠性。通过自增列,用户能够高效进行字典编码,显著提升了字符串精确去重以及查询的性能。使用自增列作为主键来存储明细数据,可以完美的解决明细数据更新的问题。同时,基于自增列,用户可以实现高效的分页机制,轻松应对深分页场景,有效过滤掉大量非必需数据,从而减轻数据库的负载压力,为用户带来了更加流畅和高效的数据处理体验。
|
1月前
|
SQL 关系型数据库 MySQL
阿里云mysql数据库价格购买和使用教程
阿里云数据库使用指南:购买MySQL、SQL Server等RDS实例,通过选择配置、地域和可用区完成购买。创建数据库和账号,分配权限。使用DMS登录数据库,进行管理操作。确保ECS与RDS在同一地域的VPC内,配置白名单实现内网连接。详细步骤见官方文档。
631 1
|
21天前
|
存储 关系型数据库 MySQL
轻松入门MySQL:数据库设计之范式规范,优化企业管理系统效率(21)
轻松入门MySQL:数据库设计之范式规范,优化企业管理系统效率(21)
|
23天前
|
存储 关系型数据库 MySQL
数据库字符编码MySQL中使用UTF-8还是UTFB4
数据库字符编码MySQL中使用UTF-8还是UTFB4
20 0