本文根据 OceanBaseDev Meetup#1 上海站分享整理,本次活动针对分布式数据库的分布式事务以及落地实践展开具体分享。本文作者:羡林,蚂蚁集团高级技术专家,2012年毕业于北京邮电大学计算机专业。2013年加入 OceanBase 团队,参与了OceanBase 1.0 及 2.0 版本的设计与开发,目前主要负责 OceanBase 高可用及一致性相关的工作。分享视频以及 PPT 查看地址见文末。
本文将首先介绍实现高可用数据库所面临的挑战,然后从几个方面介绍解决高可用问题所需的分布式一致性技术的相关内容,希望对你有所帮助。
在关系数据库系统之中,事务需要满足 ACID 特性。其中,"D"表示"持久性"(Durability),即一旦事务完成,则事务对数据库的影响就不会丢失。
DBMS 复杂性的一个重要原因就是需要满足持久性:数据库中的任何修改直到该修改被存储到非易失性的辅助存储器中,才能认为这个修改是最终有效的。
数据是企业的核心命脉,满足持久性是数据库系统正确服务的先决条件。在此基础上,随着信息时代的发展,客户对数据库系统提出了更高的要求,即服务不能停,要求最基础的数据库系统提供高的可用性。
以支付宝为例,支付宝的客户24小时均会使用支付宝提供的服务,这对整个系统提出了非常高的挑战。
客观现实及传统数据库的解决方案
如果系统不出现任何故障,那么同时实现数据的可靠存储和服务的持续可用也许是简单的。
但在真实场景中,故障是不可避免的。有多种可能的故障原因:
- 硬件故障: 磁盘、网络,甚至 CPU 和 Memory 均可能出现故障。以硬件厂商的统计数据为例,硬盘的年故障率达到1.25%, 服务器的年故障率会更高;
- 软件故障:操作系统、文件系统以及数据库系统本身,均有可能出现软件故障;
- 人为误操作:运维人员和 DBA 在运维、升级系统时,存在误操作的可能,每个操作均如履薄冰;
- 故障范围:随着系统规模越来越大,故障可能出现的范围从单机、机架,到整个机房甚至一个城市;
传统数据库一般通过共享存储或主备同步的方案来应对可能出现的故障。
在共享存储的方案中,往往依赖于高端硬件来提高可用性,这一方面需要更高的成本,另一方面在共享存储出现故障时,整个系统仍需要停服务,甚至有丢数据的风险。除此之外,共享存储不支持跨机房部署,无机房级的容灾能力。
在主备同步的方案中,无法平衡服务的可靠性和可用性。主备同步本质上只有两种选择:异步同步和强同步。异步同步无法保证在主库故障时数据的可靠性,而强同步无法保证在主库、备库或网络三者任一出现故障时系统的可用性。
分布式一致性协议
如上所述,共享存储和主备同步的方案在故障场景下均无法很好的平衡数据的可靠性和系统的可用性。针对此问题,计算机科学家、图灵奖获得者 Leslie Lamport 早在20多年前就提出了对应的解决方案,也就是著名的 Paxos 协议。
我们先来看下 Wiki 里对分布式一致性协议的说明:
- Consensus is the process of agreeing on one result among a group of participants.
- This problem becomes difficult when the participants or their communications may experience failures.
通过 Paxos 协议,使用三副本/五副本,可以很好的平衡数据的可靠性和系统的可用性;在少数派副本出现故障时,Paxos 协议可以确保系统数据不丢,且服务持续可用。
在 Paxos 协议里,有两种不同的角色:
- Proposer: 提案发起者;
- Acceptor: 提案接受者,对 Proposer 的消息进行应答;
一个或多个 Proposer 可以发起提案,系统需要对所有提案中的某一个提案达成一致,协议保证最多对一个确定的提案达成一致。
一个基本的 Paxos 流程分 prepare、accept 两步,如下图所示:
Paxos协议的详细内容参考论文《Paxos Made Simple》。另外,Raft 协议作为 Paxos 协议的一个变种,其论文《In Search of an Understandable Consensus Algorithm (Extended Version)》也值得细读。
OceanBase 一致性工程实践
OceanBase 是最早将 Paxos 协议用于关系型数据库的系统之一。通过数据多副本,OceanBase 用软件手段在普通 PC 服务器上实现了金融级的数据高可靠和系统的高可用,实现了 RPO = 0 以及 RTO < 30s。通过提供多种部署模式的选择,可以分别实现机器级、机房级以及城市级的容灾能力。
如下,是 OceanBase 的一个简化的部署结构图。图中每个 ZONE 是一个容灾域,每个 OBServer 是一个数据库服务节点,每个 OBServer 中包含多个Paxos Group 提供服务。
这一小节分别介绍 OceanBase 使用的 Multi-Paxos 协议,为了节省成本开发的日志副本功能,以及为了保证数据正确性所做的一系列工作。
Multi-Paxos
在数据库系统中,实现事务的持久性依赖的是 redo log。使用 Paxos 协议,每一条 redo log 即对应一个 Paxos Instance。
如果使用基本的 Paxos 协议决定一条 redo log 的内容,至少会有两轮 RPC 延迟。基于此,使用 Multi-Paxos 协议对 redo log 的同步做优化,在系统稳定的情况下,一条 redo log 的同步,仅需要一轮 RPC 延迟。
Multi-Paxos 协议需要有一个稳定的 Leader。OceanBase 通过一个选举协议在多个副本中选择一个 Leader,所有的读写请求均通过 Leader 进行。写请求会要求日志同步到多数派副本后应答客户端持久化成功,而读请求仅需要访问 Leader 即可保证读取到最新的数据。
Leader 作为 Multi-Paxos 协议的 Proposer。假定 Proposer 比较稳定,可以一次性对所有的 Paxos Instance 做 prepare,所有 Paxos Instance 共用一个 maxPreparedProposalNO。
一轮具体的 Multi-Paxos 流程如下:
- 选举协议从所有副本中选择出一个 Leader 节点,作为 Proposer;
- Proposer 选择一个 ProposalID 对所有日志进行 Prepare; Follower 节点(也是协议中的 Acceptor)收到后进行检查:
- 如果未收到过更大 ProposalID 的请求,则接受此 Prepare 消息,并回复 LocalMaxLogID;
- 否则直接忽略此请求;
- Reconfirm: Proposer 收到多数派 Acceptor 对 Prepare 的响应,选取响应中 LocalMaxLogID 最大值,记做 ReconfirmMaxLogID,假设本地最大确认 LogID 为 K,对于 [K+1, ReconfirmMaxLogID] 范围内所有日志,通过 Prepare/Accept 两阶段重新执行 Paxos 协议流程;
- Leader Active: Reconfirm 完成后,切换到此状态提供数据的读写服务;
Multi-Paxos 实现了日志的乱序同步,对网络抖动的容忍性更好。
日志副本
传统数据库的主备同步同一份数据保存了两份,而 Paxos 协议作为一个多数派协议,需要至少三副本。我们为了提供高可用能力付出了额外的成本,那这部分成本是否可以减小甚至消除呢?
首先,我们分析一个副本所需的资源类型:CPU、内存、磁盘空间。
作为一个备副本而言,CPU 和内存主要用于 redo log 的回放,而磁盘空间主要用于存储用户数据和 redo log。和用户数据相比,redo log 所占用的磁盘空间是非常少的,常常只需要十分之一甚至更少,并且可以重复使用。
基于上述分析,OceanBase 提供了日志副本功能,这样的副本不回放 redo log,节省了 CPU 和内存的开销,同时不存储用户数据,仅需要很少的磁盘空间用于 Paxos 投票。
在具体部署上,数据库服务器可以交叉部署正常副本和日志副本,也可以采购低配低成本服务器,仅用于存储日志副本。
数据正确性保证
Paxos 协议是分布式数据库系统的基石,而通过 Paxos 协议实现的多副本数据一致性又是一切数据正确性的前提。
OceanBase 从两方面来确保数据的正确性。
1.异常测试
在测试阶段模拟各类异常是确保正确性的基础。具体工作如下:
- 设计了专门测试 Paxos 协议流程的测试框架,mock 写盘和网络,模拟乱序、丢包、延时等多种场景,测试协议正确性;
- 数十个容灾测试用例,测试数据节点遇到各类异常时的行为;
- 代码随机错误注入,模拟内存分配失败、随机的网络丢包;
- 多个集成测试环境,7*24 不间断的做各类容灾测试;
2.完备的 checksum 校验
除异常测试外,在系统运行过程中,设计了多个维度的 checksum 校验,用于实时发现可能的数据正确性问题;
- 日志体/完整日志(日志头+日志体)/单次写入块的三个层次的 checksum 校验,用于发现内存写坏、磁盘静默错误等问题;
- RPC packet checksum 实时校验,用于发现可能的网络包的数据问题;
- 单个日志流的累积 checksum 校验,任何一条日志都会校验从所在日志流第一条日志开始到本日志结束的所有日志内容的 checksum 校验和,用于确保多个副本数据的严格一致;
总结
分布式一致性协议是实现原生分布式数据库的关键技术之一。本文首先介绍了实现高可用数据库所面临的挑战,然后从几个方面介绍了解决高可用问题所需的分布式一致性技术的相关内容。原生分布式是数据库的未来,在走向未来的过程中,一定有更多有意思的挑战,还有非常多的技术难题和挑战等着我们,欢迎感兴趣的小伙伴加入我们!
回顾资料
- 视频回顾:https://www.bilibili.com/video/BV1wt4y1q7Eg
- PPT 查看地址:https://tech.antfin.com/community/activities/1283/review/1013
- 《Paxos Made Simple》:https://lamport.azurewebsites.net/pubs/paxos-simple.pdf
- 《In Search of an Understandable Consensus Algorithm (Extended Version)》 :https://raft.github.io/raft.pdf