ClickHouse 容灾技术方案(两方案对比+落地细节)

3 阅读10分钟

本文针对 ClickHouse 容灾需求,设计两种可直接落地的技术方案,均采用 HAProxy 实现故障自动切换,分别适配不同服务器资源、业务优先级场景,明确各方案的架构设计、落地实施步骤、故障切换流程及注意事项,确保容灾能力可落地、可验证。

核心前提:两种方案均保障 RTO(恢复时间目标)≤ 3秒RPO(恢复点目标)= 0(无数据丢失),业务全程无感知;HAProxy 均采用双机热备部署,避免负载均衡组件单点故障。

方案一:双节点实时同步 + HAProxy 故障切换

一、方案概述

架构:2台服务器部署 ClickHouse(单主+实时热备),不依赖 ClickHouse Keeper(无需分布式协调),通过 MaterializedMySQL 引擎实现主备节点数据实时同步,HAProxy 部署在两台服务器,实现流量路由、健康检查及故障自动切换,适配服务器资源有限(仅2台)、中小业务场景。

核心优势:架构极简、无 Keeper 脑裂风险、部署成本低;核心劣势:容灾能力仅支持单节点故障,无多副本冗余,服务器集群级故障(如机房断电)无法应对。

二、落地实施细节(生产可用,直接复制执行)

1. 环境准备

服务器角色IP地址硬件配置(生产低配)部署组件
主节点(CH-Master)192.168.1.101CPU 8核、内存16GB、SSD 500GB+、CentOS 7+ClickHouse Server + HAProxy
备节点(CH-Slave)192.168.1.102与主节点一致(配置需对等)ClickHouse Server + HAProxy

前置操作(两台服务器均执行):关闭防火墙、SELinux,优化内核参数

# 关闭防火墙/SELinux
systemctl stop firewalld && systemctl disable firewalld
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

# 优化内核参数(ClickHouse 官方要求)
cat >> /etc/sysctl.conf << EOF
fs.file-max=65535
net.core.somaxconn=65535
vm.max_map_count=262144
EOF
sysctl -p

2. 部署 ClickHouse(两台服务器均执行)

# 安装官方源
curl -s https://packagecloud.io/install/repositories/altinity/clickhouse/script.rpm.sh | bash
# 安装服务
yum install -y clickhouse-server clickhouse-client
# 开机自启
systemctl enable clickhouse-server
systemctl start clickhouse-server
# 验证启动(无报错即正常)
systemctl status clickhouse-server

3. 配置主备实时同步(核心步骤)

步骤3.1 主节点(192.168.1.101)配置

编辑 ClickHouse 配置文件,开启 MySQL 兼容协议(用于备节点同步)

# 创建配置文件
vi /etc/clickhouse-server/config.d/mysql.xml

写入以下内容:

<yandex>
    <!-- 开启MySQL兼容协议,端口9004(自定义,不冲突即可) -->
    <mysql_port>9004</mysql_port>
</yandex>

重启主节点 ClickHouse:

systemctl restart clickhouse-server
步骤3.2 备节点(192.168.1.102)配置

执行 SQL,创建同步数据库(自动全量+增量同步主节点数据)

# 登录 ClickHouse 客户端
clickhouse-client

# 创建同步库(同步主节点的default库,可替换为实际业务库)
CREATE DATABASE default_sync
ENGINE = MaterializedMySQL(
    '192.168.1.101:9004',  -- 主节点IP+MySQL协议端口
    'default',             -- 主节点需要同步的库名
    'default',             -- 主节点ClickHouse用户名(默认default)
    ''                    -- 主节点密码(默认空,生产需设置密码)
);

# 验证同步(主节点写入数据后,备节点可查询到)
-- 主节点执行:INSERT INTO default.test_table VALUES (1, 'test', now());
-- 备节点执行:SELECT * FROM default_sync.test_table;

4. 部署 HAProxy(两台服务器均执行,配置完全一致)

步骤4.1 安装 HAProxy
yum install -y haproxy
systemctl enable haproxy
步骤4.2 配置 HAProxy(核心,实现故障切换)
vi /etc/haproxy/haproxy.cfg

替换以下完整配置(适配双节点同步场景):

# 全局配置
global
    log         127.0.0.1 local2 info
    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

# 默认配置
defaults
    log                     global
    retries                 3
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m

# ClickHouse TCP端口监听(用于应用程序连接,端口8001自定义)
listen clickhouse-tcp
    bind *:8001
    mode tcp
    option tcplog
    # 健康检查:每秒检查ClickHouse 9000端口(TCP客户端端口),2次失败标记为不可用
    option tcp-check
    tcp-check connect port 9000
    default-server inter 1s fall 2 rise 2

    # 主节点:权重100,优先转发所有流量
    server ch-master 192.168.1.101:9000 check weight 100
    # 备节点:权重1,主节点故障后自动接管流量
    server ch-slave 192.168.1.202:9000 check weight 1
步骤4.3 启动 HAProxy 并验证
systemctl start haproxy
# 查看HAProxy状态(无报错即正常)
systemctl status haproxy
# 查看后端节点状态(确认主备节点均为UP)
echo "show servers state" | socat stdio /var/lib/haproxy/stats

5. 故障切换验证(必做)

  1. 正常状态:HAProxy 将所有流量转发到主节点(192.168.1.101),备节点实时同步数据,应用连接 HAProxy 地址(192.168.1.101:8001 或 192.168.1.102:8001)。
  2. 故障模拟:关闭主节点 ClickHouse 服务 systemctl stop clickhouse-server
  3. 切换验证:1秒内 HAProxy 检测到主节点失效,自动将流量切换到备节点,应用无感知,可正常读写。
  4. 恢复验证:重启主节点 ClickHouse systemctl start clickhouse-server,HAProxy 自动检测到主节点恢复,流量切回主节点,备节点继续同步。

6. 注意事项

  • 备节点默认只读,无需额外配置,同步引擎自动限制写入,仅主节点可读写。
  • 生产环境需给 ClickHouse 设置密码,同步时修改 MaterializedMySQL 引擎的用户名/密码配置。
  • 双节点仅支持单节点故障容灾,若两台服务器同时故障(如机房断电),需额外配置异地备份。

方案二:1分片3副本集群 + HAProxy 故障切换

一、方案概述

架构:3台服务器部署 ClickHouse 集群(1分片+3副本),每台服务器混部 ClickHouse Server + ClickHouse Keeper(无需额外部署 Keeper 节点),通过 ReplicatedMergeTree 引擎实现副本数据同步,Keeper 集群(3节点奇数)负责协调副本、避免脑裂,HAProxy 部署在3台服务器,实现流量负载均衡、健康检查及故障自动切换,适配核心业务、对容灾能力要求高的场景。

核心优势:多副本冗余(3份数据),支持单节点/双节点故障,无单点风险,容灾能力强;核心劣势:部署成本高于方案一,需3台服务器,运维复杂度略高。

二、落地实施细节(生产可用,直接复制执行)

1. 环境准备

服务器角色IP地址硬件配置(生产低配)部署组件
节点1(CH+Keeper)192.168.1.101CPU 8核、内存16GB、SSD 500GB+、CentOS 7+ClickHouse Server + ClickHouse Keeper + HAProxy
节点2(CH+Keeper)192.168.1.102与节点1一致ClickHouse Server + ClickHouse Keeper + HAProxy
节点3(CH+Keeper)192.168.1.103与节点1一致ClickHouse Server + ClickHouse Keeper + HAProxy

前置操作(三台服务器均执行):同方案一的前置操作(关闭防火墙、SELinux、优化内核参数)。

2. 部署 ClickHouse(三台服务器均执行)

与方案一的 ClickHouse 部署步骤完全一致(安装官方源 → 安装服务 → 开机自启),此处不再重复,执行方案一“部署 ClickHouse”的命令即可。

3. 配置集群(核心步骤:Keeper + 副本 + 集群配置)

步骤3.1 配置 ClickHouse Keeper(三台服务器,逐台配置)

创建 Keeper 配置文件,实现3节点 Keeper 集群(奇数节点,避免脑裂)

vi /etc/clickhouse-server/config.d/keeper.xml

节点1(192.168.1.101)配置:

<yandex>
    <keeper_server>
        <tcp_port>2181</tcp_port>  -- Keeper默认端口
        <server_id>1</server_id>    -- 节点唯一ID(1/2/3)
        <log_storage_path>/var/lib/clickhouse/keeper/log</log_storage_path>
        <snapshot_storage_path>/var/lib/clickhouse/keeper/snapshot</snapshot_storage_path>
        <raft_configuration>
            <server><id>1</id><hostname>192.168.1.101</hostname><port>2181</port></server>
            <server><id>2</id><hostname>192.168.1.102</hostname><port>2181</port></server>
            <server><id>3</id><hostname>192.168.1.103</hostname><port>2181</port></server>
        </raft_configuration>
    </keeper_server>
</yandex>

节点2(192.168.1.102)配置:仅修改 <server_id>2</server_id>,其余与节点1一致。

节点3(192.168.1.103)配置:仅修改 <server_id>3</server_id>,其余与节点1一致。

步骤3.2 配置宏定义(三台服务器,逐台配置)

宏定义用于标识分片和副本,所有节点分片ID一致(1分片),副本ID唯一。

vi /etc/clickhouse-server/config.d/macros.xml

节点1配置:

<yandex>
    <macros>
        <shard>01</shard>  -- 分片ID(所有节点一致,1分片)
        <replica>01</replica>-- 副本ID(01/02/03,唯一)
    </macros>
</yandex>

节点2配置:<replica>02</replica>,其余一致。

节点3配置:<replica>03</replica>,其余一致。

步骤3.3 配置集群(三台服务器,配置完全一致)

定义集群信息,关联3个副本,实现数据同步和负载均衡。

vi /etc/clickhouse-server/config.d/remote_servers.xml
<yandex>
    <remote_servers>
        <cluster_1shard_3replica>  -- 集群名称(自定义)
            <shard>
                <internal_replication>true</internal_replication>
                -- 3个副本,对应三台服务器
                <replica><host>192.168.1.101</host><port>9000</port></replica>
                <replica><host>192.168.1.102</host><port>9000</port></replica>
                <replica><host>192.168.1.103</host><port>9000</port></replica>
            </shard>
        </cluster_1shard_3replica>
    </remote_servers>
</yandex>
步骤3.4 重启 ClickHouse,验证 Keeper 集群
# 三台服务器均执行重启
systemctl restart clickhouse-server

# 验证 Keeper 集群状态(任意节点执行)
clickhouse-client -q "SELECT * FROM system.keeper_server;"
# 正常状态:有1个leader节点,2个follower节点,无error
步骤3.5 创建集群表(任意节点执行)

创建 ReplicatedMergeTree 本地复制表(存储数据)和 Distributed 分布式表(应用入口)

# 登录 ClickHouse 客户端
clickhouse-client

# 1. 创建本地复制表(所有节点自动同步,无需逐台创建)
CREATE TABLE test_table_local
(
    id Int64,
    name String,
    create_time DateTime
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{shard}/test_table', '{replica}')
ORDER BY id;

# 2. 创建分布式表(应用唯一入口,自动负载均衡)
CREATE TABLE test_table_distributed AS test_table_local
ENGINE = Distributed(cluster_1shard_3replica, default, test_table_local, rand());

# 验证同步:任意节点写入数据,其他节点可查询到
INSERT INTO test_table_distributed VALUES (1, 'test', now());
SELECT * FROM test_table_local;  -- 三台节点均能查询到数据

4. 部署 HAProxy(三台服务器均执行,配置完全一致)

步骤4.1 安装 HAProxy

与方案一的 HAProxy 安装步骤一致,执行 yum install -y haproxy && systemctl enable haproxy

步骤4.2 配置 HAProxy(适配3副本集群)
vi /etc/haproxy/haproxy.cfg

替换以下配置(核心差异:后端节点为3个副本,权重均等,实现负载均衡):

# 全局配置、默认配置与方案一一致,仅修改 listen 段
listen clickhouse-tcp
    bind *:8001
    mode tcp
    option tcplog
    option tcp-check
    tcp-check connect port 9000
    default-server inter 1s fall 2 rise 2

    # 3个副本节点,权重均等,HAProxy自动负载均衡
    server ch-node1 192.168.1.101:9000 check weight 100
    server ch-node2 192.168.1.102:9000 check weight 100
    server ch-node3 192.168.1.103:9000 check weight 100
步骤4.3 启动 HAProxy 并验证

与方案一一致,执行启动命令并查看节点状态,确保3个 CH 节点均为 UP 状态。

5. 故障切换验证(必做)

  1. 正常状态:HAProxy 对3个副本节点进行负载均衡,应用连接 HAProxy 地址(任意节点的 8001 端口),读写请求自动分发。
  2. 单节点故障:关闭节点1 ClickHouse systemctl stop clickhouse-server,HAProxy 1秒内剔除故障节点,流量自动分发到节点2、3,业务无感知。
  3. 双节点故障:关闭节点2,仅剩余节点3,HAProxy 自动将所有流量转发到节点3,服务正常运行,数据不丢失。
  4. 恢复验证:重启故障节点,ClickHouse 自动同步缺失数据,HAProxy 检测到节点恢复后,重新纳入负载均衡。

6. 注意事项

  • Keeper 节点必须为奇数(3/5),本方案3节点刚好满足最小高可用,避免脑裂。
  • 所有节点的配置文件(macros.xml、keeper.xml、remote_servers.xml)需严格一致(除节点ID、副本ID外),否则会导致同步失败。
  • 应用必须连接分布式表(test_table_distributed),不可直接连接本地表,确保负载均衡和故障切换生效。
  • 生产环境需配置写入仲裁(insert_quorum=2),确保至少2个副本写入成功才算写入完成,进一步保障数据安全。

三、两个方案对比总结

对比维度方案一(双节点实时同步+HAProxy)方案二(1分片3副本集群+HAProxy)
服务器数量2台(成本低)3台(成本中等)
核心组件ClickHouse + HAProxy(无 Keeper)ClickHouse + ClickHouse Keeper + HAProxy(混部)
数据冗余2份(主备各1份)3份(3副本各1份)
容灾能力支持单节点故障,集群级故障无法应对支持单/双节点故障,无单点风险,容灾能力强
故障切换主备切换,HAProxy 自动剔除故障节点多副本负载均衡,HAProxy 自动分发流量、剔除故障节点
运维复杂度低(无 Keeper,配置简单)中等(需配置 Keeper 集群、副本同步)
适用场景中小业务、服务器资源有限、非核心数据,对容灾要求一般核心业务、对数据安全和容灾能力要求高,需支持多节点故障
数据同步引擎MaterializedMySQL(主备同步)ReplicatedMergeTree(副本同步)

选型建议

  • 若仅能提供2台服务器,且业务非核心、可接受集群级故障风险 → 选方案一。
  • 若能提供3台服务器,且业务核心、对容灾能力要求高 → 选方案二(生产首选,符合高可用标准)。
  • 两种方案均支持 HAProxy 双机热备,无负载均衡单点故障,可根据自身资源和业务需求灵活选择。