警告
TimescaleDB v2.13 是最后一个包含对 PostgreSQL 13、14 和 15 版本多节点支持的版本。
TimescaleDB 的多节点安装可以通过为集群中的每个节点设置一个或多个备用节点,或者通过在数据块级别进行原生数据复制来实现高可用性。
使用备用节点依赖于流式复制,其设置方式与配置单节点高可用性类似,尽管配置需要独立应用于每个节点。
要在数据块级别复制数据,您可以使用多节点 TimescaleDB 的内置功能,避免复制整个数据节点。访问节点仍然依赖于流式复制备用节点,但数据节点不需要额外的配置。相反,现有数据节点池共同负责托管数据块副本并处理节点故障。
每种方法都有其优缺点。为集群中的每个节点设置备用节点可确保备用节点在实例级别上保持一致,这是一种经过验证的高可用性提供方法。然而,它也需要更多的镜像集群设置和维护工作。
原生复制通常需要更少的资源、节点和配置,并利用内置功能,例如添加和删除数据节点,以及在每个分布式超表上使用不同的复制因子。但是,数据节点上仅复制数据块。
本节的其余部分讨论原生复制。要为每个节点设置备用节点,请按照单节点高可用性的说明进行操作。
原生复制是一组功能和 API,允许您构建高可用的多节点 TimescaleDB 安装。原生复制的核心是能够将数据块的副本写入多个数据节点,以便在数据节点发生故障时拥有备用数据块副本。如果一个数据节点发生故障,其数据块应至少在另一个数据节点上可用。如果一个数据节点永久丢失,可以将新的数据节点添加到集群中,并且可以从其他数据节点重新复制丢失的数据块副本,以达到所需的数据块副本数量。
警告
TimescaleDB 中的原生复制仍在开发中,目前缺乏完整的高可用性解决方案所需的功能。本节中描述的一些功能仍处于实验阶段。对于生产环境,我们建议为多节点集群中的每个节点设置备用节点。
与单节点 PostgreSQL 的高可用性配置使用 Patroni 等系统自动处理故障转移类似,原生复制需要一个外部实体来协调故障转移、数据块重新复制和数据节点管理。TimescaleDB 默认不提供这种协调功能,因此需要单独实现。以下部分描述了如何启用原生复制以及在节点故障情况下实现高可用性所涉及的步骤。
启用原生复制的第一步是为访问节点配置一个备用节点。此过程与设置单节点备用节点相同。
下一步是在分布式超表上启用原生复制。原生复制由 `replication_factor` 控制,它决定了数据块复制到多少个数据节点。此设置是为每个超表单独配置的,这意味着同一个数据库可以有一些分布式超表是复制的,而另一些则不是。
默认情况下,复制因子设置为 `1`,因此没有原生复制。您可以在创建超表时增加此数字。例如,要将数据复制到总共三个数据节点上
SELECT create_distributed_hypertable('conditions', 'time', 'location',replication_factor => 3);
或者,您可以使用 set_replication_factor
调用来更改现有分布式超表上的复制因子。但请注意,只有新的数据块会根据更新后的复制因子进行复制。现有数据块需要通过将其复制到新的数据节点来重新复制(参见下面的节点故障部分)。
启用原生复制后,只要您向表中写入数据,就会发生复制。在每次 `INSERT` 和 `COPY` 调用中,数据的每一行都会写入多个数据节点。这意味着您无需执行任何额外步骤即可复制新摄入的数据。当您查询复制数据时,查询规划器在查询计划中仅包含每个数据块的一个副本。
当数据节点发生故障时,尝试写入故障节点的插入操作将导致错误。这是为了在数据节点再次可用时保持数据一致性。您可以使用 alter_data_node
调用通过运行此查询将故障数据节点标记为不可用
SELECT alter_data_node('data_node_2', available => false);
将 `available` 设置为 `false` 意味着该数据节点不再用于读写查询。
为了实现读操作的故障转移,alter_data_node
调用会查找所有以不可用数据节点作为主要查询目标的数据块,并故障转移到另一个数据节点上的数据块副本。然而,如果某些数据块没有可故障转移到的副本,则会发出警告。对于在任何其他数据节点上没有数据块副本的数据块,读操作将继续失败。
为了实现写操作的故障转移,任何打算写入故障节点的活动都会通过更改访问节点上的元数据,将所涉及的数据块标记为特定故障节点的陈旧状态。这仅适用于原生复制的数据块。这允许您在故障节点被标记为不可用时,继续写入其他数据节点上的数据块副本。对于在任何其他数据节点上没有数据块副本的数据块,写操作将继续失败。另请注意,故障节点上未写入的数据块不受影响。
当您将数据块标记为陈旧时,该数据块将变为复制不足状态。当故障数据节点再次可用时,可以使用 copy_chunk
API 重新平衡此类数据块。
如果等待数据节点恢复不可行,无论是由于耗时过长还是节点永久失效,您可以选择删除它。要删除数据节点,其所有数据块必须在其他数据节点上至少有一个副本。例如
SELECT delete_data_node('data_node_2', force => true);WARNING: distributed hypertable "conditions" is under-replicated
如果您删除数据节点意味着集群无法再达到所需的复制因子,请在删除时使用 `force` 选项。这通常是正常情况,除非数据节点没有数据块,或者分布式超表的数据块副本数量多于配置的复制因子。
重要提示
如果强制删除数据节点会导致多节点集群永久丢失数据,则无法强制删除该数据节点。
当您成功移除故障数据节点,或将故障数据节点标记为不可用后,某些数据块可能缺少副本,但查询和插入操作会再次正常工作。然而,在所有数据块完全复制之前,集群仍处于脆弱状态。
当您恢复了故障数据节点或将其再次标记为可用时,您可以使用此查询查看需要复制的数据块
SELECT chunk_schema, chunk_name, replica_nodes, non_replica_nodesFROM timescaledb_experimental.chunk_replication_statusWHERE hypertable_name = 'conditions' AND num_replicas < desired_num_replicas;
此查询的输出如下所示
chunk_schema | chunk_name | replica_nodes | non_replica_nodes-----------------------+-----------------------+---------------+---------------------------_timescaledb_internal | _dist_hyper_1_1_chunk | {data_node_3} | {data_node_1,data_node_2}_timescaledb_internal | _dist_hyper_1_3_chunk | {data_node_1} | {data_node_2,data_node_3}_timescaledb_internal | _dist_hyper_1_4_chunk | {data_node_3} | {data_node_1,data_node_2}(3 rows)
根据数据块复制状态视图中的信息,可以将复制不足的数据块复制到新节点,以确保数据块具有足够的副本数量。例如
CALL timescaledb_experimental.copy_chunk('_timescaledb_internal._dist_hyper_1_1_chunk', 'data_node_3', 'data_node_2');
重要提示
当您恢复数据块复制时,操作会使用多个事务。这意味着它无法自动回滚。如果您在操作完成之前取消操作,则会记录复制的操作 ID。您可以使用此操作 ID 清理取消操作留下的任何状态。例如
CALL timescaledb_experimental.cleanup_copy_chunk_operation('ts_copy_1_31');
关键词