详细解读开源 PolarDB 三节点高可用的功能特性和关键技术
在 3 月 2 日的阿里云开源 PolarDB 企业级架构发布会上,阿里云数据库技术专家孟勃荣带来了主题为《PolarDB 三节点高可用》的精彩演讲。三节点高可用功能主要为 PolarDB 提供金融级强一致性、高可靠性的跨机房复制能力,基于分布式共识算法同步数据库物理日志,自动 failover,任意节点故障后数据零丢失。本议题主要介绍 PolarDB 三节点高可用的功能特性和关键技术。
直播回顾视频:https://developer.aliyun.com/topic/PolarDB_release
PDF 下载: https://developer.aliyun.com/topic/download?id=8346
以下根据发布会演讲视频内容整理:
PolarDB for PostgreSQL 三节点高可用功能主要是将物理复制与一致性协议相结合,为 PolarDB 提供金融级强一致性以及高可靠的跨机房复制能力。
PG 原生的流复制支持异步/同步/Quorum 三种同步方式。
同步复制的主要目标是保证数据不丢失,但它同时也会带来三个问题:
① 无法满足可用性的要求,备库出现故障或网络链路抖动的时候,会影响主库的可用性,这对生产环境是不可接受的。其次它不能完全保证数据不丢失,同步复制保证数据不丢失的方案是当备机没有完全持久化 RW 日志前,主库的事务不能提交。在某种极端情况下,比如主库已经写入了 WAL 日志,等待备库同步 WAL 日志的过程中主库发生了重启,那么在重启的过程中,日志回放的过程是不等待备库持久化的。所以回放完成后,有可能备库没有持久化,而日志在主库上回放完之后已经对外可见了。
② 不具备故障自动切换的能力。自动切换、可用性探测等能力都依赖于外部的组件。
③ 旧的主库在故障恢复之后,可能无法直接加入到集群。比如当事务在主库上的 WAL 日志已经持久化,而备库还未收到日志或者还未持久化。此时如果主库出现了故障,备库切换成主库后,旧的主库重新运行后,因为在重启之前有多余的 WAL 日志,所以无法直接从主库上拉取日志,必须依赖于其他工具对其一致性进行处理后才能加入到集群里。
异步复制相比于同步复制,性能比较好,可用性也更高,因为备机的故障或网络链路的抖动不会影响主库,但它最大的问题是丢数据。比如原来在主库上能看到的数据,发生切换之后在备库上不存在。其次,它也不具备自动故障切换和自动探测的能力,切换后的主库无法自动加入到集群里。
Quorum 复制使用了多数派的方案之后,可能也能保证不丢数据,但它并没有涉及到当主机发生故障时如何选取新的主机;其次,每个节点的日志不一致时,如何确保日志的一致性;第三,集群发生变更的时候,如何保证集群状态最终的一致性。针对以上问题,Quorum 复制没有提供完整的解决方案。所以本质上来说, PG 的 Quorum 复制并不是一个完整的、不丢数据的高可用方案。
我们的方案是将阿里内部的一致性协议 X-Paxos 引入进来协调物理复制。X-Paxos 在阿里内部和阿里云的多个产品上已经稳定运行了很长时间,因此它的稳定性得以保障。它的的一致性协议的算法和其他的协议是类似的。
整个高可用方案是一个单点写入、多点可读的集群系统。 Leader 节点作为单点写入节点对外提供读写服务,产生了 WAL 日志后向其他节点同步。Follower 主要是接受来自于 Leader 节点的 WAL 日志,并进行回放,对外提供只读服务。
那么它的主要能力是包括以下三个方面:
保证集群内数据的强一致性,即 RPO=0。当多数派节点的 WAL 日志写入成功后,才认为此日志在集群层面已经提交成功。发生故障时,其他 Follower 节点会自动与 Leader 节点对齐日志。
自动 failover 。在高可用集群中,只要半数以上的节点存活,就能保证集群正常对外提供服务。因此当少数 failover 故障或少数节点网络不通的时候,并不会影响集群的服务能力。
当 Leader 节点故障或与多数派节点网络不通的时候,会自动触发集群重新选主流程,由新主对外提供读写服务。另外 Follower 节点也会自动从新的 Leader 节点上同步 WAL 日志,并且自动与新的 Leader 日志对齐。此时如果 Follower 上的日志比新 Leader 上多,则会自动从新 Leader 上对齐 WAL 日志。
在线集群变更可以支持在线增删节点、手动切换、角色变换,比如从 Leader 切到 follower 角色。此外还能支持所有节点设置选举权重,选举权重高的节点会优先被选为主。同时,集群变更操作不影响业务的正常运行,此能力的实现由一致性协议来保证。最终集群内配置达成一致,不会因为集群配置过程中的异常情况导致状态不一致的问题。
三节点高可用功能中增加了一个新的角色: Learner 节点。它没有多数派的决策权,但能够提供只读服务。Learner 节点的日志同步状态与 Leader 无关,也不会影响 Leader ,它的主要作用有两点:
① 作为加节点的中间状态。比如新加的 Leader 节点延迟比较大,如果直接将其加入到多数派里,会影响多数派的提交。因此,先以 learner 的角色加入到集群来同步数据,当它的数据基本追上 Leader 之后,再升为 follower 节点。
② 作为异地灾备节点。它不会影响主库的可用性,发生 Leader 切换之后,它能自动从新的账号同步日志,不需要外部的介入。
在集群部署方面,能够支持跨机房和跨域的部署,包括同机房三副本、同城三机房三副本,以及两地三机房五副本、三地三机房五副本等。另外跨域也可以利用 Learner 节点进行灾备,不会影响 Leader 节点的可用性。此外,它兼容了 PG 原生的流复制和逻辑复制,能够保证下游的消费不受影响,保证下游不会出现未提交的数据。
从前文的介绍中可以看到,在 PolarDB 的高可用方案中,至少要存储三份数据,存储成本会有所增加。针对这个问题,我们提供了两个方面的解决方案:
首先,提高资源的利用率。 Follower 节点可以作为只读节点来提供读服务,从而增加整个集群的读扩展能力;此外,支持跨节点的并行查询能力,可以充分利用各个基节点的资源。
其次,引入了日志节点,减少资源的占用。日志节点本身不存储数据,它只存储实时的 WAL 日志,仅作为日志持久化的多数派节点之一。此日志节点本身也具备完整的日志复制能力,可以兼容原生的流复制和逻辑复制,可以将其作为下游日志消费的源,从而减少 Leader 节点的日志传输压力。可以根据下游日志消费的需求,来定制日志节点的网络规格或者其他资源。
一致性协议复制的基本原理主要包含三个方面:
① 通过原生的异步流复制来传输或同步 WAL 日志。② 由一致性协议来推动集群的提交位点。③ 针对自动 failover 的问题,根据一致性协议层面自身状态的变化,来驱动数据库层面的状态变化。比如心跳超时之后,可能会自动降级。
具体实现上,以 Consensus Log 为载体来推进提交位点。针对每一段 WAL 日志生成相应的 Consensus Log Entry ,里面记录了 WAL 日志的结束 LSN。 而后引入一个持久化依赖,保证每个 Log Entry 持久化的时候,本节点上相应位点的 WAL 日志已经持久化成功。
引入上述两个机制后,如果一致性协议层面认为 Consensus Log 已经提交成功,则意味着 Consensus Log 已经在多数派上持久化成功,相应位点的 WAL 日志肯定也已经持久化成功。
以上图为例, Leader 上已经持久化了三段 WAL 日志,在 Follower 1 节点上,虽然 log entry 的 WAL 日志已经持久化成功,但它对应的 Consensus Log 还未持久化成功,所以一致性协议就认为此 Consensus Log 也没有持久化成功。Follower 2 上 Log Entry 和 Consensus Log 没有持久化,它的 WAL 日志只持续化了一段,它的 WAL 日志段也没有持久化成功。因此,根据一致性协议,当前 LogIndex 2 的日志在多数派节点上已经写入成功,当前 Consensus Log 的 CommitIndex 就是 2 ,对应的那 Commit LSN 就是 300。
上图为 tpmC 测试过程中 RTO 的情况。tpmC 达到 30 万左右的时候,进行 kill 主库的操作。可以看到,不到 30 秒,新的主库已经恢复了写的能力,并且恢复到切换之前的水平。
(完)
资料分享:PolarDB 的源码仓库地址:https://github.com/ApsaraDB/PolarDB-for-PostgreSQL
评论