Bootstrap

PG高可用学习@2

一、Patroni 支持在同步复制下备库故障时自动降级为异步复制?

synchronous_commit
synchronous_mode
synchronous_standby_names

备库优先级别
在这里插入图片描述

模拟故障
在这里插入图片描述
同步备库从1-0切换到2-0
在这里插入图片描述

synchronous_commit 设置为 on 时,PostgreSQL 主库会等待至少一个同步备库确认接收到事务日志后才会向客户端返回事务提交成功的信息。如果备库挂掉,主库就会一直等待,导致卡住。Patroni 是一个用于管理 PostgreSQL 高可用集群的工具,它支持将同步复制降级为异步复制,以解决主库卡住的问题。

根据 Patroni 官方文档,Patroni 使用 PostgreSQL 的流复制。默认情况下,Patroni 配置 PostgreSQL 为异步复制。选择复制模式取决于您的业务考虑。需要调查异步复制和同步复制,以及其他高可用性解决方案,以确定哪种解决方案最适合您的需求。在异步复制模式下,集群被允许丢失一些已提交的事务,以确保可用性。当主服务器失败或因其他任何原因变得不可用时,Patroni 将自动提升一个足够健康的备用服务器为主服务器。任何尚未复制到备用服务器的事务都保留在主服务器上的“分叉时间线”中,并且实际上是可恢复的。

要启用 PostgreSQL 的同步复制,可以在 Patroni 的 YAML 配置文件中的 parameters 部分添加以下行:

synchronous_commit: "on"
synchronous_standby_names: "*"

启用同步复制后,使用至少三个 Postgres 数据节点以确保写入可用性,如果一个主机失败。使用 PostgreSQL 同步复制并不保证在所有情况下都不会丢失事务。当主服务器和当前作为同步副本的服务器同时失败时,可能会提升一个不包含所有事务的第三个节点。

Patroni 的 synchronous_mode 可以在运行时通过 patronictl edit-config 命令或通过 Patroni REST 接口开启或关闭。有关动态配置的说明,请参见 Patroni 官方文档。开启 synchronous_mode 并不保证在所有情况下都能实现多节点提交的持久性。当没有合适的备用服务器可用时,主服务器仍然会接受写入,但不保证它们的复制。当主服务器以这种模式失败时,不会提升任何备用服务器。当主机重新上线时,它将自动被提升,除非系统管理员执行了手动故障转移。这种行为使得同步模式适用于具有两个节点的集群集。

synchronous_mode 打开且备用服务器崩溃时,提交将阻塞,直到下一次迭代的 Patroni 运行并切换主服务器到独立模式(在最坏情况下,写入延迟为 ttl 秒,平均情况下为 loop_wait/2 秒)。手动关闭或重新启动备用服务器不会导致提交服务中断。备用服务器将在 PostgreSQL 关闭之前向主服务器发出信号,以释放其同步备用职责,然后 PostgreSQL 关闭。

如果需要保证每个写入都持久地存储在至少两个节点上,请启用 synchronous_mode_strict 以及 synchronous_mode。此参数会阻止 Patroni 在没有同步备用候选时关闭主服务器上的同步复制。缺点是,主服务器在没有同步副本候不可写入(除非 Postgres 事务显式关闭 synchronous_mode),这会阻塞所有客户端写入请求,直到至少有一个同步副本可用。

您可以通过设置 nosync 标签为 true 来确保备用服务器永远不会成为同步备用。这对于通过网络连接缓慢且可能导致性能下降的备用服务器,建议设置此标签。将标签 nostream 设置为 true 也将产生相同的效果。

参考依据

1. PostgreSQL 官方文档

PostgreSQL 官方文档详细解释了 synchronous_commit 参数的作用和不同取值的含义。当 synchronous_commit 设置为 on 时,主库会严格等待同步备库的确认,这可能导致在备库故障时主库卡住。而将其设置为 off 可以让主库在提交事务时不等待备库确认,实现异步复制。

2. Patroni 官方文档

Patroni 官方文档提供了关于如何通过修改配置文件来调整 PostgreSQL 参数的详细说明。我们可以通过修改 patroni.yml 文件中的 postgresql.parameters 部分来动态调整 synchronous_commit 参数,以适应不同的集群状态。

3. 高可用和容错设计原则

在高可用集群设计中,当同步备库出现故障时,将同步复制降级为异步复制是一种常见的容错策略。这样可以确保主库在备库故障时仍然能够继续处理事务,避免因等待备库确认而导致系统卡住,从而提高系统的可用性。

replication_modes

第10章 复制模式

二、patroni 是如何检测备库故障的?

Patroni 是一款用于管理 PostgreSQL 高可用集群的工具,它主要通过心跳机制、监控数据库进程状态、查询系统视图以及利用 PostgreSQL 内置的复制状态信息等方式来检测备库故障,以下为你详细介绍:

1. 心跳机制

  • 原理:Patroni 基于 etcd、Consul 或 ZooKeeper 等分布式键值存储系统实现心跳机制。主库和备库会定期向这些存储系统写入自己的状态信息(心跳信息),包括节点的健康状况、角色(主库或备库)、当前时间戳等。
  • 故障检测:Patroni 会持续监控这些心跳信息。如果某个备库在规定的时间内没有更新其心跳信息,Patroni 就会认为该备库可能出现故障。例如,设置的心跳间隔为 2 秒,超时时间为 10 秒,若备库超过 10 秒未更新心跳,Patroni 就会触发故障处理流程

2. 监控数据库进程状态

  • 进程检查:Patroni 会定期检查备库上的 PostgreSQL 进程是否正常运行。它可以通过操作系统命令(如 ps 命令)来查看 PostgreSQL 进程是否存在。
  • 故障判定:如果在多次检查中都无法找到 PostgreSQL 进程,Patroni 会判定该备库出现故障。例如,每隔 5 秒检查一次,连续 3 次都未发现进程,就认为备库故障。

3. 查询系统视图

  • 状态查询:Patroni 会在备库上执行 SQL 查询,通过查询 PostgreSQL 的系统视图来获取备库的状态信息。常用的系统视图包括 pg_stat_replication(主库上查看复制状态)和 pg_stat_wal_receiver(备库上查看 WAL 接收状态)。
  • 故障识别:如果查询结果显示备库的复制状态异常,如 pg_stat_wal_receiver 中的 state 字段不是正常的 streaming 状态,或者 pg_stat_replication 中显示备库长时间没有接收或应用 WAL 日志,Patroni 会判断备库可能存在故障。

4. 复制延迟监测

  • 延迟计算:Patroni 会监控备库与主库之间的复制延迟。通过比较主库和备库的 WAL 位置(如 pg_current_wal_lsn() 函数获取的日志序列号),计算出备库落后主库的日志量。
  • 故障判断:如果复制延迟超过了预设的阈值,Patroni 会认为备库可能出现问题。例如,设定延迟阈值为 100MB,当备库落后主库的日志量超过 100MB 且持续一段时间(如 5 分钟),就判定备库故障。

5. 网络连接测试

  • 连接尝试:Patroni 会定期尝试与备库建立网络连接,包括数据库连接和其他必要的通信连接。
  • 故障确认:如果多次连接尝试都失败,Patroni 会认为备库可能由于网络问题或自身故障而无法正常响应,从而判定备库故障。例如,每隔 3 秒尝试连接一次,连续 5 次失败就触发故障处理。

三、动态配置设置

动态配置存储在DCS(分布式配置存储)中并应用于所有集群节点。

为了更改动态配置,您可以使用:ref:patronictl_edit_config 工具或 Patroni:ref:REST API <rest_api>

  • loop_wait:循环休眠的秒数。默认值:10,最小可能值:1

  • ttl:获取领导者锁的 TTL(以秒为单位)。可以将其视为启动自动故障转移过程之前的时间长度。默认值:30,最小可能值:20

  • retry_timeout:DCS 和 PostgreSQL 操作重试的超时时间(以秒为单位)。短于此时间的 DCS 或网络问题不会导致 Patroni 降级领导者。默认值:10,最小可能值:3

当改变 loop_wait、retry_timeout 或 ttl 的值时,必须遵循以下规则:

loop_wait + 2 * retry_timeout <= ttl

在这里插入图片描述

Dynamic Configuration Settings

;