文档下载建议反馈入口

  • 概述
  • 基础概念
  • 使用限制
  • 部署配置
  • 扩缩容
  • 高可用机制
  • 相关操作
  • 错误码

双副本集群高可用

概述

KaiwuDB 双副本集群提供两种高可用部署形态,适配不同服务器资源条件(以三台服务器为例): 部署形态一:资源不均衡场景(2 数据节点 + 1 仲裁节点) 当集群内服务器配置差异较大,单台节点资源显著弱于其他节点时,推荐采用仲裁节点架构。仲裁节点不承载时序业务数据,仅参与 Raft 共识投票,保障集群选主与故障判定。 部署形态二:资源均衡场景(2 数据副本 + 仲裁副本,无独立仲裁节点) 当各服务器硬件配置均衡,希望在双副本降低存储冗余的同时最大化利用整机资源,可采用内嵌仲裁副本,不单独部署独立仲裁节点;仲裁副本与数据副本均衡打散分布于各节点,进一步提升硬件资源利用率。

以上两种部署形态,可根据实际业务情况进行切换。

说明

  • 双副本策略仅对时序数据生效,关系数据和元数据仍采用三副本。
  • RPO 可通过集群参数 ts.arbiter.rpo_max_duration 配置,默认不限制。

基础概念

概念描述
数据副本(Data Replica)存储实际时序业务数据的副本,正常参与 Raft 共识和选举,可当选 Leader 和 Leaseholder。双副本方案中每个数据分片有 2 个数据副本,分布在数据节点上。
仲裁副本(Arbitration Replica)不存储时序业务数据的副本,参与 Raft 共识和选举,可当选 Leader 但优先级较低,不可成为 Leaseholder。正常情况下 Leader 由数据副本担任,仅在数据节点故障时仲裁副本才可能当选 Leader。
仲裁节点(Arbiter Node)承载仲裁副本的节点,通常为集群中配置较低或异构的机器。仲裁节点仍需存储关系数据和元数据,并参与集群心跳。
数据节点(Data Node)承载数据副本的节点,负责时序数据的实际存储与读写服务。

使用限制

双副本集群存在以下限制:

  • 集群中至少有 2 个数据节点和 1 个仲裁节点【部署形态一】。
  • 每个数据分片的副本构成固定为 2 个数据副本 + 1 个仲裁副本,不允许通过 CONFIGURE ZONE USING num_replicas 修改副本数量。
  • 双副本策略只能通过 ALTER RANGE ts CONFIGURE ZONE USING arbiter = true 或 ALTER DATABASE ... CONFIGURE ZONE USING arbiter = true 启用,不支持表级别设置,不支持对已有表从三副本切换为双副本。
  • 启用双副本后,不支持切换回三副本模式。

部署配置

前提条件

  • 已准备至少三台服务器。
  • 各服务器之间网络互通,且时钟偏差小于 500 ms。

步骤

  1. 在个服务器上启动服务

部署形态一

以三台服务器为例,部署 2 数据节点 + 1 仲裁节点

(1)在数据节点服务器上分别执行以下命令,启动数据节点:

# 数据节点 A
./kwbase start \
  --insecure \
  --store=/data \
  --listen-addr=<node_a_address>:26257 \
  --advertise-addr=<node_a_address>:26257 \
  --brpc-addr=:27257 \
  --http-addr=<node_a_address>:8080 \
  --join=<node_a_address>,<node_b_address>,<node_c_address> \
  --background

# 数据节点 B
./kwbase start \
  --insecure \
  --store=/data \
  --listen-addr=<node_b_address>:26257 \
  --advertise-addr=<node_b_address>:26257 \
  --brpc-addr=:27257 \
  --http-addr=<node_b_address>:8080 \
  --join=<node_a_address>,<node_b_address>,<node_c_address> \
  --background

(2)在仲裁节点服务器上执行以下命令,启动仲裁节点。注意必须加上 --arbiter 参数:

# 仲裁节点 C
./kwbase start \
  --insecure \
  --store=/data \
  --arbiter \
  --listen-addr=<node_c_address>:26257 \
  --advertise-addr=<node_c_address>:26257 \
  --brpc-addr=:27257 \
  --http-addr=<node_c_address>:8080 \
  --join=<node_a_address>,<node_b_address>,<node_c_address> \
  --background

部署形态二

以三台服务器为例,在各台服务器上执行启动命令

# 节点 A
./kwbase start \
  --insecure \
  --store=/data1 \
  --listen-addr=<node_a_address>:26257 \
  --advertise-addr=<node_a_address>:26257 \
  --brpc-addr=:27257 \
  --http-addr=<node_a_address>:8080 \
  --join=<node_a_address>,<node_b_address>,<node_c_address> \
  --background

# 节点 B
./kwbase start \
  --insecure \
  --store=/data \
  --listen-addr=<node_b_address>:26257 \
  --advertise-addr=<node_b_address>:26257 \
  --brpc-addr=:27257 \
  --http-addr=<node_b_address>:8080 \
  --join=<node_a_address>,<node_b_address>,<node_c_address> \
  --background

# 节点 C
./kwbase start \
  --insecure \
  --store=/data \
  --listen-addr=<node_b_address>:26257 \
  --advertise-addr=<node_c_address>:26257 \
  --brpc-addr=:27257 \
  --http-addr=<node_c_address>:8080 \
  --join=<node_a_address>,<node_b_address>,<node_c_address> \
  --background
  1. 在任意节点上执行集群初始化命令:
./kwbase init --insecure --host=<node_a_address>:26257
  1. 连接到集群后,执行以下语句启用双副本策略:

    -- 对全部时序数据生效,执行时集群中不能存在任何时序表
    ALTER RANGE ts CONFIGURE ZONE USING arbiter = true;
    
    -- 对全部时序数据生效,执行时目标数据库中不能存在时序表,且保证数据不丢失
    ALTER RANGE ts CONFIGURE ZONE USING arbiter = true, arbiter_with_log = true;
    
    -- 仅对指定数据库生效,执行时目标数据库中不能存在时序表
    ALTER DATABASE <db_name> CONFIGURE ZONE USING arbiter = true;
    
    -- 对指定数据库生效,执行时目标数据库中不能存在时序表,且保证数据不丢失
    ALTER DATABASE <db_name> CONFIGURE ZONE USING arbiter = true, arbiter_with_log = true;
    

    系统随后会将时序数据分片自动分配为 2 个数据副本 + 1 个仲裁副本,根据部署形态进行仲裁副本和数据副本的迁移。如果是存在仲裁节点的部署形态一,仲裁副本会迁移至仲裁节点,数据副本迁移至数据节点,并将 Leaseholder 迁移至数据节点。

    说明

    • 初始化完成后副本补足和 Leaseholder 迁移需要一定时间,期间首次建表的响应时间会略长于标准三副本集群。
    • 设置 arbiter_with_log 时的前提条件是 arbiter = true,否则会报错 could not validate zone config:must set arbiter to true before set arbiter_with_log。并且不支持从 true 修改为 false。
    • 开启 arbiter_with_log 后,仲裁节点上会存储 raft log ,会比不开启时占用相对多的磁盘空间。
    • 启用后不支持切换回三副本模式。

扩缩容

双副本集群支持通过扩缩容处理节点故障、调整集群规模,或是调整部署形态。每个数据分片的副本构成标准始终为 2 个数据副本 + 1 个仲裁副本,允许暂时缺少一个数据副本或仲裁副本,但不允许数据副本数量超过 2 个,也不允许仲裁副本数量超过 1 个。

注意:缩容之前,必须保证缩容之后集群规模 >=3,且数据副本不少于2,否则缩容失败。

加入新节点

当节点故障无法恢复,或需要主动扩容时,可加入新节点:

加入新数据节点

./kwbase start \
  --insecure \
  --store=/data_new \
  --listen-addr=<new_node_address>:26257 \
  --advertise-addr=<new_node_address>:26257 \
  --brpc-addr=:27257 \
  --http-addr=<new_node_address>:8080 \
  --join=<existing_node_address>:26257 \
  --background

加入新仲裁节点

./kwbase start \
  --insecure \
  --store=/data_new \
  --arbiter \
  --listen-addr=<new_node_address>:26257 \
  --advertise-addr=<new_node_address>:26257 \
  --brpc-addr=:27257 \
  --http-addr=<new_node_address>:8080 \
  --join=<existing_node_address>:26257 \
  --background

新节点加入后,系统可能触发副本自动均衡,将部分副本迁移至新节点。

退役节点

加入新节点后,可执行退役操作移除故障节点:

./kwbase node decommission <node_id> --insecure --host=<address>:26257

退役操作会将故障节点上的副本迁移至新节点,等待命令执行完成后,所有副本已在新节点上补全。

注意

  • 退役数据节点时,集群规模要求至少为 4,且至少有 3 个数据节点(包含待退役节点),否则退役将失败。

也可以不立即执行退役,等待故障节点被系统判定为死亡后,系统会自动在其他节点上补足副本。

两种部署形态切换

无仲裁节点双副本集群切换至有仲裁节点双副本集群

  1. 部署无仲裁节点双副本集群,操作参考初始化安装部署

  2. 加入仲裁节点,操作参考加入新仲裁节点

  3. 退役数据节点,操作参考退役节点

有仲裁节点双副本集群切换至无仲裁节点双副本集群

  1. 部署有仲裁节点双副本集群,操作参考初始化安装部署

  2. 加入数据节点,操作参考加入新数据节点

  3. 退役仲裁节点,操作参考退役节点

高可用机制

双副本方案通过 Raft 投票机制实现高可用,可容忍任意一个节点故障。

单节点故障

数据节点故障

当一个数据节点不可用时,剩余的 1 个数据副本与仲裁副本组成 2/3 多数,达成 Raft 共识,由剩余数据节点继续对外提供读写服务。节点恢复后,自动重新加入集群并与 Leader 完成数据同步,读写服务不受影响。

仲裁节点故障

当仲裁节点不可用时,2 个数据副本自身即可达成 2/2 多数,集群读写服务不受影响。节点恢复后,自动重新加入集群,恢复投票能力。

多节点故障

当任意两个节点同时故障时(包括两个数据节点同时故障,或一个数据节点与仲裁节点同时故障),集群无法达成多数共识,写入操作将失败。待任意一个节点恢复后,集群恢复服务,读写恢复正常。

当所有节点故障时,写入操作将失败。待节点全部恢复后,集群自动完成选举并恢复读写服务。

数据一致性保证

双副本方案采用弱一致性保证:数据写入 Leader 副本后即视为成功,Follower 数据副本可能存在短暂落后。可通过集群参数 ts.arbiter.rpo_max_duration 配置数据同步周期,控制最大数据丢失量。详细信息参见配置 RPO。

数据完整性

开启 Raft log后,数据节点离线后,将使用仲裁副本上包含数据的 Raft log 补齐 follow 数据副本,保证数据不丢失。在数据补齐期间,无 leaseholder 可用,无法进行读写。 仲裁副本上存储足够的供数据副本 follow 数据补齐的 Raft log,因此需要更多的磁盘空间、IO资源。

相关操作

配置 RPO

ts.arbiter.rpo_max_duration 用于控制双副本模式下数据节点间数据同步的时间周期,即最大允许丢失的数据时间范围。仅在启用双副本模式时生效。

SET CLUSTER SETTING ts.arbiter.rpo_max_duration = '60s';
取值说明
-1(默认值)不进行 RPO 控制,数据节点之间无需进行周期性数据同步。
大于 1s 的时间值系统按设定周期在数据节点之间同步数据,强制同步期间阻塞写入。如果有数据节点不可用,写入将被阻塞,直至数据节点恢复或新数据节点加入且故障节点退役后,写入才会继续执行。

注意

开启 RPO 控制后,如果有数据节点故障,写入将持续阻塞。仲裁节点故障不影响数据写入。

查看节点状态

执行以下命令查看集群节点状态,输出中 node_mode 列显示各节点角色:

./kwbase node status --insecure --host=<address>:26257

输出示例:

id |      address      |   sql_address     |  build  |         started_at          |         updated_at          |   locality    | is_available | is_live | node_mode
-----+-------------------+-------------------+---------+-----------------------------+-----------------------------+---------------+--------------+---------+-----------
1 | node_a:26257      | node_a:26257      | V3.2.0  | 2026-03-02 09:24:56.827856  | 2026-03-02 09:25:01.343206  | region=NODE1  | true         | true    | normal
2 | node_b:26257      | node_b:26257      | V3.2.0  | 2026-03-02 09:24:58.012345  | 2026-03-02 09:25:02.234567  | region=NODE2  | true         | true    | normal
3 | node_c:26257      | node_c:26257      | V3.2.0  | 2026-03-02 09:25:00.543210  | 2026-03-02 09:25:03.654321  | region=NODE3  | true         | true    | arbiter

node_mode 字段取值说明:

取值说明
normal标准数据节点,存储时序业务数据。
arbiter仲裁节点,参与 Raft 投票,不存储时序业务数据。

查看监控指标

在KaiwuDB内置数据监控平台的 debug/chart 页面可查看以下双副本相关监控指标:

指标说明单位
raft.arbiter.leader.duration仲裁副本作为 Leader 的时长。记录每个仲裁副本从当选 Leader 开始到变回 Follower 的时间。正常情况下该值应接近 0,数值持续偏高说明数据节点可能存在故障。DURATION
arbiter.rpo.sync.paused开启 RPO 控制后,每次执行数据同步的副本数量。COUNT

错误码

错误码SQL语句错误信息
0A000ALTER RANGE ts CONFIGURE ZONE USING arbiter_with_log = false;unsupported FALSE value for arbiter_with_log.
23514前提:未设置 arbiter = true
ALTER RANGE ts CONFIGURE ZONE USING arbiter_with_log = true;
could not validate zone config: must set arbiter to true before set arbiter_with_log.