ClickHouse集群部署与分布式表引擎实战指南
ClickHouse集群部署与分布式表引擎实战指南
说明:本文将从零开始,带你一步步完成 ClickHouse 集群的部署和配置,重点讲解如何利用分布式表(Distributed)引擎实现跨节点的数据分片和查询。文中包含配置文件示例、SQL 代码示例,以及图解帮助你快速理解集群拓扑和引擎原理。
目录
- 前言
- 2.1 集群节点类型
- 2.2 集群拓扑示意图
- 3.1 系统要求与依赖
- 3.2 网络与防火墙配置
- 4.1 单节点安装步骤
- 4.2 配置文件结构说明
- 4.3 常用参数详解
- 5.1 ZooKeeper 集群部署(可选但推荐)
- 5.2 ClickHouse 配置联动 ZooKeeper
- 5.3 拓扑文件 (
cluster.xml
) 配置示例
- 6.1 分布式表(Distributed)引擎基础
- 6.2 本地引擎(MergeTree)与分布式引擎配合
- 6.3 拉取数据与查询路由
- 6.4 具体示例:创建本地表和分布式表
- 7.1 数据插入到本地分片
- 7.2 通过分布式表进行全局查询
- 7.3 并行查询优化与监控指标
- 8.1 ZooKeeper 保持节点状态与 Failover
- 8.2 Proxy 层常见方案(例如 HAProxy/Nginx)
- 8.3 查询路由示意图
- 总结与参考文档
1. 前言
ClickHouse 是一款由 Yandex 开源的高性能列式分布式 OLAP 数据库,擅长海量数据的实时分析与查询。单机部署就能获得非常快的查询速度,而集群化部署则可以水平扩展,支持更大规模的数据存储与并行计算。
本文重点关注:
- 如何从零搭建一个简单的 ClickHouse 集群
- 如何使用分布式表(Distributed)引擎将数据分片到多个节点
- 如何针对高并发查询进行性能优化与监控
通过阅读本文,你将了解 ClickHouse 的集群配置逻辑、分布式表的使用方法,以及集群高可用的最佳实践。
2. ClickHouse 集群架构概览
2.1 集群节点类型
一个典型的 ClickHouse 集群通常包含以下几种角色:
ZooKeeper 节点(可选,推荐)
- 作用:负责存储集群元数据(如分片信息、复制队列等),协调各 ClickHouse 节点之间的分布式一致性。
- 推荐配置:3 节点或以上的 ZooKeeper 集群,保证高可用。
ClickHouse 数据节点(Data Node)
- 作用:存储并处理数据,多数使用
MergeTree
系列引擎。 - 特点:数据根据分片判定规则分布到不同数据节点,节点之间通过 ZooKeeper 协调写操作和复制。
- 作用:存储并处理数据,多数使用
ClickHouse 查询(或 Proxy)节点(可选)
- 作用:接收客户端查询请求,将 SQL 语句路由到下游数据节点,汇总结果后返回客户端。
- 优点:可以屏蔽客户端对集群内部拓扑的感知,实现负载均衡与高可用。
本文示例采用最简化拓扑:
- 一个 ZooKeeper 集群(3 个节点)
- 两个 Data Node,分别作为分片的两个副本
- 一个 Proxy Node 作为统一入口
2.2 集群拓扑示意图
┌───────────────────┐
│ Client (CLI/UI) │
└────────┬──────────┘
│ (1) SQL 请求
▼
┌─────────────────────┐
│ Proxy Node (CH-P) │
│ clickhouse-server │
└──────────┬──────────┘
│ (2) 根据 cluster.xml 路由
┌─────────────────┴─────────────────┐
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ ClickHouse │ │ ClickHouse │
│ Data Node 1 │ │ Data Node 2 │
│ (Shard 1) │ │ (Shard 2) │
│ merge_tree1 │ │ merge_tree1 │
└─────┬────────┘ └─────┬────────┘
│ │
│ │
│ ┌─────────────────────────┐ │
└───▶│ ZooKeeper Cluster ◀────┘
│ zk1, zk2, zk3 (3 节点) │
└─────────────────────────┘
- 步骤 (1):Client 将 SQL 请求发送给 Proxy Node。
- 步骤 (2):Proxy Node 根据
/etc/clickhouse-server/config.d/cluster.xml
中定义的集群拓扑,将请求分发到对应的 Data Node(Shard)。 - Data Node:各自保存本地分片数据,并在 ZooKeeper 中完成分片间的复制协调。
- ZooKeeper:存储分片分配信息、复制队列等集群元数据,保证写入的一致性和容错。
3. 环境准备
3.1 系统要求与依赖
操作系统
- 建议使用 CentOS 7/8、Ubuntu 18.04/20.04 或者 Debian 9/10。
- 这里以 Ubuntu 20.04 LTS 为示例,其他 Linux 发行版类似。
机器配置(Data Node)
- CPU:4 核及以上
- 内存:16 GB 及以上
- 磁盘:SSD(至少 200 GB)
- 网络:千兆以太网,保证低延迟
ZooKeeper机器(各 3 节点)
- CPU:2 核
- 内存:4 GB
- 磁盘:机械盘即可,只存储少量元数据
- 配置为三台独立的机器,以保证 ZooKeeper 集群的高可用性
依赖软件
- OpenJDK 8/11(ZooKeeper 依赖)
- wget、curl、tar 等常用命令行工具
3.2 网络与防火墙配置
确保各节点之间可以互通,默认端口:
- ClickHouse:TCP 9000(native),HTTP 8123,TCP 9009(interserver)
- ZooKeeper:TCP 2181(客户端连接),TCP 2888/3888(集群内部通信)
- 如果启用了防火墙(
ufw
或firewalld
),需开放相应端口。示例(Ubuntu 下采用ufw
):
# 允许 ClickHouse native 协议、HTTP 协议与 interserver 通信
sudo ufw allow 9000/tcp
sudo ufw allow 8123/tcp
sudo ufw allow 9009/tcp
# 允许 ZooKeeper 端口
sudo ufw allow 2181/tcp
sudo ufw allow 2888/tcp
sudo ufw allow 3888/tcp
sudo ufw enable
4. 节点安装与基础配置
4.1 单节点安装步骤
以下示例以 Ubuntu 20.04 为例,演示如何安装 ClickHouse 二进制包。
# 1. 添加 ClickHouse 官方仓库 GPG Key
curl https://packages.clickhouse.com/CLICKHOUSE-KEY.GPG | sudo apt-key add -
# 2. 添加仓库地址
sudo sh -c 'echo "deb https://packages.clickhouse.com/deb stable main" > /etc/apt/sources.list.d/clickhouse.list'
# 3. 更新并安装 clickhouse-server 与 clickhouse-client
sudo apt update
sudo apt install -y clickhouse-server clickhouse-client
# 4. 启动并设置为开机自启
sudo systemctl enable clickhouse-server
sudo systemctl start clickhouse-server
# 5. 验证服务状态
sudo systemctl status clickhouse-server
安装完成后,ClickHouse 默认会在 /etc/clickhouse-server/
下生成以下关键目录:
config.xml
:ClickHouse 全局配置文件users.xml
:用户权限配置文件config.d/
:可放置自定义的扩展配置users.d/
:可放置自定义的用户配置macros.xml
:变量宏定义(常用于集群配置)
4.2 配置文件结构说明
/etc/clickhouse-server/config.xml
- 定义 HTTP 服务端口、Logging、Zookeeper、Interserver 通信等全局参数。
- 示例(简化):
<yandex>
<!-- 监听端口 -->
<tcp_port>9000</tcp_port>
<http_port>8123</http_port>
<interserver_http_port>9009</interserver_http_port>
<!-- 日志与临时目录 -->
<logger>
<level>information</level>
<log>/var/log/clickhouse-server/clickhouse-server.log</log>
<errorlog>/var/log/clickhouse-server/clickhouse-server.err.log</errorlog>
</logger>
<path>/var/lib/clickhouse/</path>
<tmp_path>/var/lib/clickhouse/tmp/</tmp_path>
<!-- ZooKeeper 配置(后文将补充) -->
</yandex>
/etc/clickhouse-server/users.xml
- 定义用户及其权限,默认包含一个
default
用户,密码为空,可访问所有数据库。 - 这里最好创建一个强密码的管理员用户,并限制
default
用户只读或禁用。
- 定义用户及其权限,默认包含一个
/etc/clickhouse-server/macros.xml
- 定义集群相关宏(如
{cluster}
,{shard}
,{replica}
等),在cluster.xml
中会引用这些宏。 - 示例:
- 定义集群相关宏(如
<yandex>
<macros>
<!-- 在服务器自己的 config.d/cluster.xml 中,如果需要使用宏可以在此定义 -->
<cluster>my_clickhouse_cluster</cluster>
<shard>shard1</shard>
<replica>replica1</replica>
</macros>
</yandex>
4.3 常用参数详解
<path>
与<tmp_path>
path
:ClickHouse 数据文件存储路径,主存储目录。tmp_path
:临时文件存储路径,如临时排序文件。
<max_concurrent_queries>
,<max_memory_usage>
等- 可以根据机器资源进行调整,避免单个查询占满全部内存或资源。
<listen_host>
- 如果只希望监听特定网卡,可以设置;默认为
0.0.0.0
全网段监听。
- 如果只希望监听特定网卡,可以设置;默认为
<zookeeper>
- 用于指定 ZooKeeper 集群地址(多个节点可使用逗号分隔),示例可在下一节详解。
5. 集群级别配置
5.1 ZooKeeper 集群部署(可选但推荐)
ClickHouse 的副本(Replicated MergeTree)和分布式表(Distributed)很大程度依赖于 ZooKeeper 来实现一致性与协调。若只是做测试,也可以省略 ZooKeeper,但不推荐在生产环境省略。
以下以三台服务器(IP 假设为 10.0.0.1
, 10.0.0.2
, 10.0.0.3
)为例,部署 ZooKeeper 3.7.x。
安装 Java(以 OpenJDK 11 为例)
sudo apt update sudo apt install -y openjdk-11-jre-headless
下载并解压 ZooKeeper
wget https://dlcdn.apache.org/zookeeper/zookeeper-3.7.1/apache-zookeeper-3.7.1-bin.tar.gz tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz sudo mv apache-zookeeper-3.7.1-bin /opt/zookeeper
配置
zoo.cfg
在
/opt/zookeeper/conf/zoo.cfg
中写入:tickTime=2000 initLimit=10 syncLimit=5 dataDir=/var/lib/zookeeper clientPort=2181 # 下面三行用于集群通信 server.1=10.0.0.1:2888:3888 server.2=10.0.0.2:2888:3888 server.3=10.0.0.3:2888:3888
dataDir
:保存 ZooKeeper 元数据的路径,需提前创建并赋予zookeeper
用户权限。server.X
:集群内部通信地址,X
为 ID(从 1 起)。
设置
myid
文件sudo mkdir -p /var/lib/zookeeper echo "1" | sudo tee /var/lib/zookeeper/myid # 对于 IP 10.0.0.1 上填入 1 # 第二台 IP 10.0.0.2: echo "2" > /var/lib/zookeeper/myid # 第三台 IP 10.0.0.3: echo "3" > /var/lib/zookeeper/myid
启动 ZooKeeper
cd /opt/zookeeper bin/zkServer.sh start
验证状态
bin/zkServer.sh status
如果显示
Mode: follower
或Mode: leader
即可,说明集群已初始化成功。
5.2 ClickHouse 配置联动 ZooKeeper
在每个 ClickHouse Data Node(假设在 10.0.0.11
和 10.0.0.12
)上,需要编辑 /etc/clickhouse-server/config.d/zookeeper.xml
,将 ZooKeeper 信息写入:
<yandex>
<zookeeper>
<!-- 可以指定多个节点,格式:host:port -->
<node>
<host>10.0.0.1</host>
<port>2181</port>
</node>
<node>
<host>10.0.0.2</host>
<port>2181</port>
</node>
<node>
<host>10.0.0.3</host>
<port>2181</port>
</node>
<!-- 可选:设置会话超时时间 -->
<session_timeout_ms>300000</session_timeout_ms>
</zookeeper>
</yandex>
重启 ClickHouse 服务使配置生效:
sudo systemctl restart clickhouse-server
5.3 拓扑文件(cluster.xml
)配置示例
在集群模式下,需要在每台 Data Node 上的 /etc/clickhouse-server/config.d/cluster.xml
中定义集群拓扑。例如,假设集群名称为 my_cluster
,有两个分片(shard1、shard2),每个分片有两个副本(replica1、replica2),实际 IP 如下:
Shard1:
- Replica1:
10.0.0.11
- Replica2:
10.0.0.12
- Replica1:
Shard2:
- Replica1:
10.0.0.13
- Replica2:
10.0.0.14
- Replica1:
在所有节点的 /etc/clickhouse-server/config.d/cluster.xml
中,写入:
<yandex>
<remote_servers>
<my_cluster>
<!-- Shard 1 定义 -->
<shard>
<replica>
<host>10.0.0.11</host>
<port>9000</port>
</replica>
<replica>
<host>10.0.0.12</host>
<port>9000</port>
</replica>
</shard>
<!-- Shard 2 定义 -->
<shard>
<replica>
<host>10.0.0.13</host>
<port>9000</port>
</replica>
<replica>
<host>10.0.0.14</host>
<port>9000</port>
</replica>
</shard>
</my_cluster>
</remote_servers>
<!-- 定义用于 SQL 中引用的宏 -->
<macros>
<cluster>my_cluster</cluster>
<!-- 注意每个节点还需要在自己的 macros.xml 中定义 shard 与 replica 的值 -->
</macros>
</yandex>
说明:
<remote_servers>
:用于定义集群中可访问的节点分组,名字my_cluster
可以自定义。- 每个
<shard>
下可以定义多个<replica>
,ClickHouse 在写入时会向每个 shard 内的 replica 同步数据。- 所有节点都需要能够互相读取到同一份
cluster.xml
,否则查询时会出现节点不可达或配置不一致错误。
6. 分布式表引擎原理与实战
6.1 分布式表(Distributed)引擎基础
在 ClickHouse 集群中,通常会结合以下两种引擎来实现分布式写入与查询:
本地引擎:
- 最常用的是
MergeTree
(及其变体,比如ReplicatedMergeTree
)。 - 数据存储在节点本地文件系统,支持二级索引、分区、分桶、TTL 等。
- 最常用的是
分布式引擎(Distributed):
- 用于将 SQL 查询路由到多个节点的本地表,并将结果合并后返回给客户端。
其核心配置包括:
cluster
:要路由到的集群名(即cluster.xml
中定义的<remote_servers>
)。database
:本地数据库名。table
:本地表名。sharding_key
(可选):用于将写入请求按哈希算法路由到不同 shard。
当你向分布式表插入数据时,ClickHouse 会根据 sharding_key
计算出应该插入到哪个 shard,再把这条数据落到对应 shard 的本地表中(若没有明确 sharding_key
,则轮询或全部写入)。
当你从分布式表查询时,ClickHouse 会拆分查询,将子查询同时发往各个 shard,然后将各个节点返回的结果做合并、排序、聚合等处理后返回给客户端。
6.2 本地引擎(MergeTree)与分布式引擎配合
下面以 events
表为例,演示如何先在每个节点上创建一个本地的 MergeTree
表,再创建对应的 Distributed
表。
6.2.1 本地表(采用 ReplicatedMergeTree)
在每个 Data Node(假设执行环境是 clickhouse-client 已登录到每个节点)上,先创建一个数据库(若未创建):
CREATE DATABASE IF NOT EXISTS analytics;
然后在每个节点上执行(注意:{cluster}
, {shard}
, {replica}
宏需要在各节点的 macros.xml
中预先定义):
CREATE TABLE analytics.events_local
(
event_date Date,
event_time DateTime,
user_id UInt64,
event_type String,
event_properties String
)
ENGINE = ReplicatedMergeTree('/clickhouse/tables/{cluster}/events_local', '{replica}')
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, user_id)
TTL event_date + INTERVAL 30 DAY -- 示例:30 天后自动清理
SETTINGS index_granularity = 8192;
/clickhouse/tables/{cluster}/events_local
:ZooKeeper 路径,用于存储副本队列等元数据。{replica}
:宏定义,每台服务器需要在macros.xml
中设置自己对应的replica1
、replica2
等。PARTITION BY toYYYYMM(event_date)
:按月份分区。ORDER BY (event_date, user_id)
:常见的排序键,可加速基于日期或用户的查询。
执行成功后,系统会在 ZooKeeper 中创建对应的目录结构,并在各副本之间进行数据同步。
6.2.2 分布式表(Distributed)创建
分布式表不存储数据,仅负责查询路由与合并。我们在同一个 analytics
数据库下执行:
CREATE TABLE analytics.events
(
event_date Date,
event_time DateTime,
user_id UInt64,
event_type String,
event_properties String
)
ENGINE = Distributed(
my_cluster, -- 与 cluster.xml 中 remote_servers 定义保持一致
analytics, -- 本地数据库
events_local, -- 本地表
rand() -- 随机函数,用于插入时随机负载到不同 shard
);
my_cluster
:集群名称,对应cluster.xml
中<my_cluster>
。analytics
:本地库名。events_local
:本地物理表名。rand()
:作为简单示例,将插入的行随机分发到两个 shard;也可以使用更复杂的分片键,比如user_id % 2
等。
6.3 拉取数据与查询路由
写入数据
向分布式表analytics.events
插入数据时:INSERT INTO analytics.events VALUES ('2025-06-03', now(), 1001, 'page_view', '{"url": "/home"}'), ('2025-06-03', now(), 1002, 'click', '{"button": "signup"}');
ClickHouse 会计算
rand()
或者sharding_key
决定这两条记录应该插往哪个 shard,然后把它对应的INSERT
请求转发给目标 shard 的某个副本上执行。查询数据
当你执行:SELECT event_type, count() FROM analytics.events WHERE event_date = '2025-06-03' GROUP BY event_type;
ClickHouse 会将此查询拆分成如下子任务:
- 在 Shard1 上执行相同的
SELECT
,得到部分聚合结果[(page_view, 500), (click, 200)]
(示例) - 在 Shard2 上执行相同的
SELECT
,得到部分聚合结果[(page_view, 600), (click, 150)]
(示例) Proxy Node(或客户端)接收到各个子结果后,进行二次合并:
page_view
: 500 + 600 = 1100click
: 200 + 150 = 350
- 最终返回给客户端:
[(page_view, 1100), (click, 350)]
。
- 在 Shard1 上执行相同的
图解:分布式查询流程
┌───────────────────────────────────────────────────────────────────┐ │ 分布式查询 (Distributed) │ │ │ │ Client/Proxy │ │ │ │ │ │ 1. 下发查询请求 │ │ ▼ │ │ +----------------------------+ │ │ | Distributed Table Routing | │ │ +----------------------------+ │ │ │ │ │ │ 2. 向各个 Shard 分发查询 │ │ ▼ │ │ ┌───────────────┐ ┌───────────────┐ │ │ │ Shard1 (2台) │ │ Shard2 (2台) │ │ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ │ │ │Replica1 │ │ │ │Replica1 │ │ │ │ │ └─────────┘ │ │ └─────────┘ │ │ │ │ ┌─────────┐ │ │ ┌─────────┐ │ │ │ │ │Replica2 │ │ │ │Replica2 │ │ │ │ │ └─────────┘ │ │ └─────────┘ │ │ │ └───────────────┘ └───────────────┘ │ │ ▲ ▲ │ │ │ 3. 各副本执行聚合并返回部分结果 │ │ │ │ │ │ │ └────── 4. 合并结果 ──────────┘ │ │ │ └───────────────────────────────────────────────────────────────────┘
6.4 具体示例:创建本地表和分布式表
本地表(示例)
CREATE TABLE analytics.logs_local ( ts DateTime, level String, message String ) ENGINE = ReplicatedMergeTree( '/clickhouse/tables/{cluster}/logs_local', '{replica}' ) PARTITION BY toYYYYMM(ts) ORDER BY ts SETTINGS index_granularity = 4096;
- 每个副本节点都要执行同样的建表语句。
分布式表(示例)
CREATE TABLE analytics.logs ( ts DateTime, level String, message String ) ENGINE = Distributed( my_cluster, -- cluster 名称 analytics, -- 本地库 logs_local, -- 本地表名 sipHash64(message) -- 推荐使用哈希函数,保证同一条日志恒定路由到同一 shard );
- 通过
sipHash64(message)
分片,能保证同一条日志按照message
字符串散列值决定落到哪个 shard。- 也可使用
rand()
做均匀随机分片,但不保证同一message
写到同一 shard。
7. 数据导入与查询示例
7.1 数据插入到本地分片
假设我们向分布式表 analytics.events
导入一批 CSV 文件,示例 CSV 文件 events_20250603.csv
内容如下:
2025-06-03,2025-06-03 10:00:00,1001,page_view,{"url":"/home"}
2025-06-03,2025-06-03 10:05:00,1002,click,{"button":"signup"}
2025-06-03,2025-06-03 10:10:00,1001,click,{"button":"purchase"}
2025-06-03,2025-06-03 10:15:00,1003,page_view,{"url":"/product"}
使用
clickhouse-client
导入 CSVclickhouse-client --query="INSERT INTO analytics.events FORMAT CSV" < events_20250603.csv
- ClickHouse 会解析 CSV,并将每行数据根据分片策略写入到对应的本地表上。
- 例如第一行的
user_id = 1001
,若rand()
模式下随机写入到 Shard1;若使用user_id % 2
可能落到 Shard1(1001 % 2 = 1)。
验证本地分片写入情况
登录 Shard1 的 Replica1 (
10.0.0.11
):clickhouse-client
查询本地表
events_local
的数据量:SELECT count() AS cnt, shardNumber() AS shard_id FROM analytics.events_local GROUP BY shard_id;
- 类似地,在 Shard2 (
10.0.0.13
) 上查看events_local
,对比两边的分布情况。
7.2 通过分布式表进行全局查询
简单聚合查询
SELECT event_type, count() AS total_cnt FROM analytics.events WHERE event_date = '2025-06-03' GROUP BY event_type ORDER BY total_cnt DESC;
- 该查询会并行发往各个 shard,然后在 Proxy/客户端做最终合并排序。
按用户统计访问量
SELECT user_id, count() AS visits FROM analytics.events WHERE event_date = '2025-06-03' AND event_type = 'page_view' GROUP BY user_id HAVING visits > 1 ORDER BY visits DESC LIMIT 10;
- 充分利用
ORDER BY (event_date, user_id)
索引加速。
- 充分利用
7.3 并行查询优化与监控指标
并行流(Parallel Replicas)
- 默认情况下,分布式表会读取每个 shard 上第一个可用的副本(顺序无保证)。
- 若想在同一 shard 内的多个副本并行扫描,可设置
distributed_replica_read_mode = 'parallel'
。 例如在客户端或者
users.xml
中配置:<profiles> <default> <distributed_replica_read_mode>parallel</distributed_replica_read_mode> </default> </profiles>
监控指标
在 ClickHouse 内部可以通过系统表
system.metrics
、system.events
监控:QueryThreads
: 当前并发查询线程数NetworkSendBytes, NetworkReceiveBytes
: 网络吞吐MergeTreeParts*
: 后台合并状态
例如:
SELECT metric, value FROM system.metrics WHERE match(metric, 'Query|Network');
8. 高可用与负载均衡
8.1 ZooKeeper 保持节点状态与 Failover
- 当某个 Data Node 宕机时,ZooKeeper 会检测到节点不可用,ClickHouse Client(或 Proxy)会自动路由到同 shard 下的其他可用副本进行查询与写入。
- 写操作:写到 ReplicatedMergeTree 时,若当前副本短暂不可用,则写会被暂缓到 ZooKeeper 的队列中,待该副本恢复后自动同步;若整个 shard 下所有副本都不可用,则写入失败。
8.2 Proxy 层常见方案
HAProxy
- 可以配置
balance roundrobin
或balance leastconn
,将客户端请求分发给多个 ClickHouse 节点。 示例
haproxy.cfg
:global log /dev/log local0 maxconn 4096 daemon defaults log global mode tcp option tcplog timeout connect 5s timeout client 50s timeout server 50s listen clickhouse bind *:9000 mode tcp option tcp-check default-server inter 3s fall 3 rise 2 server ch11 10.0.0.11:9000 check server ch12 10.0.0.12:9000 check server ch13 10.0.0.13:9000 check server ch14 10.0.0.14:9000 check
- 这样客户端连接到 HAProxy 的 9000 端口,就相当于连接到了一个虚拟的 ClickHouse 集群入口。
- 可以配置
Nginx Stream 模块
- 在
nginx.conf
中启用stream {}
区块,类似 HAProxy 做 TCP 负载均衡。
- 在
8.3 查询路由示意图
┌────────┐
│ Client │
└───┬────┘
│
▼
┌───────────────────┐
│ Load Balancer │ (HAProxy/Nginx 等)
│ 10.0.0.100:9000 │
└────────┬──────────┘
│ (1) 随机或最少连接路由
▼
┌───────────────┐ ┌───────────────┐
│ ClickHouse │ │ ClickHouse │
│ Proxy Node │ │ Data Node 1 │
│ (Optional) │ └───────────────┘
└───────┬───────┘ ▲
│ │
▼ (2) 按 cluster.xml 路由
┌───────────────┐ ┌───────────────┐
│ ClickHouse │ │ ClickHouse │
│ Data Node 2 │ │ Data Node 3 │
└───────────────┘ └───────────────┘
- 客户端连接到负载均衡器 IP,例如
10.0.0.100:9000
。 - 负载均衡器根据配置将请求转给 Proxy Node(若有)或直接给 Data Node。
- Proxy Node(若存在)再根据
cluster.xml
路由到对应的分片与副本。
9. 总结与参考文档
9.1 总结
本文详细介绍了如何在生产环境中构建一个基本的 ClickHouse 集群,内容包括:
- 环境准备与依赖安装:选择合适的操作系统,配置端口与防火墙。
- ZooKeeper 集群的部署与配置:保证 ClickHouse 副本间一致性的元数据存储。
- ClickHouse 节点安装与基础配置:理解
config.xml
、users.xml
、macros.xml
、cluster.xml
等配置文件的作用。 - 集群级别配置:编写
cluster.xml
定义分片与副本节点,利用macros.xml
简化配置。 - 分布式表引擎(Distributed)实战:先创建本地的
ReplicatedMergeTree
表,再在同库下创建分布式表,将数据分片并行化查询。 - 数据导入与查询示例:演示如何通过 CSV 导入测试数据,并使用分布式表进行跨分片聚合查询。
- 高可用与负载均衡:借助 ZooKeeper 实现副本自动切换,使用 HAProxy/Nginx 做查询入口的负载均衡。
通过上述步骤,你可以对 ClickHouse 的集群化部署有一个系统的认识,并掌握使用 Distributed 引擎将数据分布到多个节点、并行查询以提高性能的核心技能。
评论已关闭