第10章 复制模式
Patroni 使用 PostgreSQL 流复制。有关流式复制的更多信息,请参阅Postgres 文档。默认情况下,Patroni 将 PostgreSQL 配置为异步复制。选择复制模式取决于您的业务考虑。调查异步和同步复制以及其他 HA 解决方案,以确定哪种解决方案最适合您。
10.1异步模式持久性
在异步模式下,集群允许丢失一些已提交的事务以确保可用性。当主服务器由于任何其他原因出现故障或变得不可用时,Patroni 会自动将一个足够健康的备用服务器提升为主服务器。任何尚未复制到该备用数据库的事务都保留在主数据库上的“分叉时间线”中,并且实际上无法恢复[1]。
可以丢失的交易量通过maximum_lag_on_failover参数进行控制。由于未实时采样主事务日志位置,因此实际上,故障转移时丢失的数据量是最坏的情况,受限于事务日志的maximum_lag_on_failover字节加上最近ttl秒内写入的数据量(一般情况下是loop_wait/2秒)。但是典型的复制延迟要不到一秒钟。
默认情况下,在进行领导者选举时,Patroni 不会考虑副本的当前时间线,这在某些情况下可能是不受欢迎的行为。您可以通过将check_timeline参数的值更改为true来防止与以前的主节点没有相同时间轴的节点成为新的领导者。
10.2 PostgreSQL 同步复制
您可以在Patroni中使用Postgres的同步复制。同步复制通过在成功返回连接客户端之前确认已写入辅助节点来确保整个群集的一致性。同步复制的成本:降低写入吞吐量。 此吞吐量将完全基于网络性能。
在托管数据中心环境(如 AWS、Rackspace 或您无法控制的任何网络)中,同步复制显著提高了写入性能的可变性。如果主库无法访问从库,主库实际上变为只读。
要启用简单的同步复制测试,请将以下几行添加到YAML 配置文件的parameters部分:
synchronous_commit: "on"
synchronous_standby_names: "*"
使用 PostgreSQL 同步复制时,至少使用三个 Postgres 数据节点,以确保一台主机故障时的写入可用性。
使用 PostgreSQL 同步复制并不能保证在所有情况下都零丢失事务。当当前充当同步副本的主节点和辅助节点同时发生故障时,将提升可能不包含所有事务的第三个节点。
10.3同步模式
对于不允许丢失已提交事务的用例,您可以打开 Patroni 的synchronous_mode. 当synchronous_mode打开时 Patroni 不会提升备用数据库,除非确定备用数据库包含所有可能已将成功提交状态返回给客户端[2] 的事务。这意味着即使某些服务器可用,系统也可能无法进行写入。即使导致事务丢失,系统管理员仍然可以使用手动故障转移命令来提升备用数据库。
开启synchronous_mode并不能保证在所有情况下多节点提交的持久性。当没有合适的备用服务器可用时,主服务器仍将接受写入,但不能保证其复制。当主服务器在此模式下发生故障时,将不会升级备用服务器。当曾经的主机恢复时,它将自动升级,除非系统管理员执行了手动故障转移。 此行为使同步模式可用于2个节点群集。
当synchronous_mode开启并且从机崩溃时,提交将被阻塞,直到Patroni的下一次迭代运行并将主模式切换为独立模式(最坏情况的写入延迟为ttl秒,平均情况为loop_wait/2秒)。手动关闭或重新启动备用数据库不会导致提交服务中断。 在启动PostgreSQL关闭之前,备用服务器将指示主要数据库从同步备用数据库任务中释放出来。
如果绝对有必要确保每个写入都可以持久存储在至少两个节点上,则除了启用synchronous_mode之外,还启用synynchronous_mode_strict。当没有可用的同步备用候选者时,此参数可防止Patroni关闭主服务器上的同步复制。不利的一面是,主数据库不可用于写操作(除非Postgres事务显式转换为synchronous_mode),从而阻止所有客户端写请求,直到出现至少一个同步副本为止。
您可以通过将nosync设置为true来确保备用数据库永远不会成为同步备用数据库。 建议为慢速网络连接之后的备用服务器设置此选项,防止在成为同步备用服务器时会导致性能下降。
同步模式可以通过 Patroni REST 界面打开和关闭。有关说明,请参阅动态配置。
注意:由于PostgreSQL中实现同步复制的方式,即使使用synchronous_mode_strict,仍有可能丢失事务。如果在等待确认复制时取消了PostgreSQL后端(由于客户端超时或后端失败而取消了数据包),则其他后端会看到事务更改。此类更改尚未复制,在从库升级时可能会丢失。
10.4同步复制因素
Patroni使用参数synchronous_node_count来管理同步备用数据库的数量。默认情况下设置为1。当synchronous_mode设置为关闭时它不起作用。启用后,Patroni会根据参数synchronous_node_count管理精确数量的同步备用数据库,并在成员加入和离开时调整DCS和sync_standby_names中的状态。
10.5同步模式实现
当处于同步模式时,Patroni 在 DCS 中维护同步状态,其中包含最新的主数据库和当前同步备用数据库。使用严格的排序约束更新此状态以确保以下不变量:
•只要节点可以接受写入事务,就必须将其标记为最新的领导者。Patroni 崩溃或 PostgreSQL 未关闭可能会导致违反此变量。
•在PostgreSQL中,只要节点发布为同步备用数据库,就必须将其设置为同步备用数据库。
•非领导者或当前同步备用的节点不允许自动升级。
•Patroni 将仅根据synchronous_node_count参数将一个或多个同步备用节点分配给synchronous_standby_names。
在每个 HA 循环迭代中,Patroni 重新评估同步备用节点的选择。如果同步备用节点的当前列表已连接并且尚未请求删除其同步状态,则它保持被选中。否则,将选择复制中最靠前的可用于同步的集群成员。
[1]
数据仍然存在,但是要恢复数据,需要数据恢复专家进行手动恢复。当允许Patroni使用use_pg_rewind参数进行rewind时,分叉的时间线将被自动删除,并且将失败的主节点重新加入集群。
[2]
客户端可以使用 PostgreSQL 的synchronous_commit设置更改每个事务的行为。synchronous_commit值为off和 local的事务可能会在故障转移时丢失,但不会被复制延迟阻塞。