使用 Patroni 实现 PostgreSQL 的高可用

四月 8, 2024

摘要:Patroni 是一个模板,使用 Python 实现的 PostgreSQL 高可用解决方案。为了获得最大的可访问性,Patroni 支持各种分布式配置存储,如 ZooKeeper、etcd、Consul 或 Kubernetes。

目录

高可用

PostgreSQL 已被广泛采用为现代的高性能事务型数据库。一个高可用的 PostgreSQL 集群可以承受由网络中断、资源饱和、硬件故障、操作系统崩溃或意外重启引起的故障。此类集群通常是企业应用环境的关键组件,其中四个 9 的可用性是最低要求。

有多种方法可以实现 PostgreSQL 的高可用。本解决方案文档介绍了 Patroni,一个开源扩展,用于增强和管理 PostgreSQL 中的高可用部署。

高可用方案

有多种原生的方法可以实现 PostgreSQL 的高可用:

  • 共享磁盘故障转移,
  • 文件系统复制,
  • 基于触发器的复制,
  • 基于语句的复制,
  • 逻辑复制,
  • 预写式日志(WAL)传送,以及
  • 流复制

流复制

流复制是预写式日志传送的一部分,其中对 WAL 的更改会立即提供给备用副本。使用此方法,一个备用实例会始终与主节点的更改保持同步,并且可以在故障转移时承担主节点的角色。

为什么原生的流复制还不够

尽管 PostgreSQL 中原生的流复制支持故障转移到主节点,但它缺乏真正高可用解决方案所预期的一些关键功能。这些包括:

  • 在故障转移期间,缺少基于共识的“领导”节点选择能力
  • 没有像样的监控集群状态的功能
  • 无法自动将故障的主节点带回集群
  • 手动或计划的切换不容易管理

为了解决这些缺点,PostgreSQL 有许多第三方开源扩展。数据库管理员面临的挑战是,为当前场景选择正确的实用方案。

PostgreSQL 通过提供 Patroni 扩展来实现 PostgreSQL 的高可用,从而解决了这一挑战。

Patroni

Patroni 是一个使用 Python 实现的模板,用于创建自己的自定义高可用解决方案,以及 - 为了获得最大的可访问性 - 支持分布式配置存储,如 ZooKeeper、etcd、Consul 或 Kubernetes。

Patroni 的工作原理

使用 Patroni,您可以自定义和自动化 PostgreSQL 高可用集群。它基于现代的共识算法,通过决定在集群中执行哪些操作来确保数据库的高可用,并保护您免受数据丢失。

Patroni 会监控主节点和副本节点的活跃度,并可以更改所有集群成员的配置。它可以处理同步性要求和计划内切换,以及计划外故障转移。Patroni 会自动执行这些复杂的任务。此外,它可以保证始终满足某些条件,以完全排除对您的数据造成不可逆转的损害。

Patroni 的架构是这样的,每个 PostgreSQL 实例都有一个指定的 Patroni 实例来监视和控制它。

Patroni 的主要优点:

  • 持续监控和自动故障转移
  • 使用单个命令进行手动/计划切换
  • 内置自动化功能,用于将故障节点再次带回到集群。
  • 用于整个集群配置和进一步工具化的 REST API。
  • 为透明的应用故障转移提供基础能力
  • 每个操作和配置的分布式共识。
  • 与 Linux 看门狗集成,以避免脑裂现象。

架构布局

下图显示了一个有单个领导节点的 PostgreSQL 三节点集群的架构。

Architecture of the three-node, single primary PostgreSQL cluster

组件

此架构中的组件包括:

  • PostgreSQL 节点
  • Patroni - 用于配置 PostgreSQL 高可用集群的模板。
  • ETCD - 存储 PostgreSQL 集群状态的分布式配置存储。
  • HAProxy - 集群的负载均衡器,是客户端应用访问的单一入口点。
  • pgBackRest - PostgreSQL 的备份和恢复解决方案
  • Postgres 监控和管理(PMM) - 用于监控集群运行状况的解决方案

组件如何协同工作

集群中的每个 PostgreSQL 实例通过流复制与其他成员保持一致。每个实例都托管了 Patroni,这是一个监控集群运行状况的集群管理器。Patroni 依靠可操作的 ETCD 集群来存储集群配置,和有关集群运行状况的敏感数据。

Patroni 会定期向 ETCD 发送集群状态的心跳请求。ETCD 将此信息写入磁盘,并将响应发送回 Patroni。如果当前主节点未能在指定的超时时间内更新其作为领导者的状态,Patroni 将在 ETCD 中更新状态更改,ETCD 会使用此信息来选择新的主节点,并保持集群正常运行。

与集群的连接不会直接连接到数据库节点,而是通过连接代理(如 HAProxy)进行路由。此代理通过查询 Patroni REST API 来确定活动节点。