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 enable4. 节点安装与基础配置
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:3888dataDir:保存 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 引擎将数据分布到多个节点、并行查询以提高性能的核心技能。