第 14/15 天
引言:为什么选择 ClickHouse 作为 OLAP 引擎?
ClickHouse 是由 Yandex 开源的列式数据库管理系统(Columnar DBMS),专为实时分析场景设计。它具备惊人的写入吞吐量和亚秒级查询响应能力,广泛应用于日志分析、用户行为分析、监控指标存储、广告投放统计等 OLAP 场景。
在云原生架构中,将 ClickHouse 部署到 Kubernetes 集群上,可以利用 K8s 的弹性伸缩和滚动升级能力简化运维。而 Ceph RBD 块存储则为 ClickHouse 的数据文件提供了高可靠、低延迟的持久化卷,确保即使在 Pod 重建或节点故障时数据也不丢失。

本篇将使用 Bitnami 官方维护的 bitnami/clickhouse Helm Chart,在已接入 Ceph RBD 存储的 K8s 集群上部署一个多分片多副本的 ClickHouse 分布式集群,并配置 ClickHouse Keeper(内置的 ZooKeeper 协调组件)实现副本同步与高可用。
一、设计架构
1.1 ClickHouse 集群拓扑
ClickHouse 的分布式集群由分片(Shard)和副本(Replica)两个维度构成。本方案部署 2 分片 × 2 副本共 4 个 ClickHouse 节点,外加 3 个 ClickHouse Keeper 节点用于协调:
| 组件 | 角色说明 | 副本数 | 存储需求 |
|---|---|---|---|
| ClickHouse Shard-1 Replica-1 | 分片1主副本 | 1 | Ceph RBD 持久卷 |
| ClickHouse Shard-1 Replica-2 | 分片1备用副本 | 1 | Ceph RBD 持久卷 |
| ClickHouse Shard-2 Replica-1 | 分片2主副本 | 1 | Ceph RBD 持久卷 |
| ClickHouse Shard-2 Replica-2 | 分片2备用副本 | 1 | Ceph RBD 持久卷 |
| ClickHouse Keeper | 分布式协调服务 | 3 | Ceph RBD 持久卷 |
1.2 数据流向
ClickHouse 的数据写入与查询流程如下:
客户端写入 → Distributed 表(路由分发)
→ 分片1: 本地表写入 → MerkleTree 同步 → 副本2
→ 分片2: 本地表写入 → MerkleTree 同步 → 副本2
查询请求 → Distributed 表 → 聚合各分片局部结果 → 合并返回
- 写入:数据按分片键(如 hash() )分发到不同分片,每个分片写入主副本后异步同步到备用副本
- 查询:Distributed 表将查询扇出到所有分片的本地表,各节点并行计算后汇总返回
- 副本同步:ClickHouse Keeper 维护复制日志队列,副本通过拉取日志实现数据同步
1.3 高可用机制
| 高可用维度 | 实现方式 |
|---|---|
| 数据冗余 | 每个分片 2 副本,任一副本宕机不影响读写 |
| 协调服务 | Keeper 3 节点 Raft 共识,容忍 1 节点故障 |
| 存储高可用 | Ceph RBD 块存储多副本(OSD 级别冗余) |
| 查询容错 | Distributed 表自动跳过不可用副本 |
| 服务发现 | K8s Headless Service + StatefulSet 稳定 DNS |
1.4 存储规划
| 数据类型 | StorageClass | 卷大小 | 访问模式 |
|---|---|---|---|
| ClickHouse 数据卷 | ceph-rbd | 100Gi | ReadWriteOnce |
| Keeper 数据卷 | ceph-rbd | 10Gi | ReadWriteOnce |
ClickHouse 的列式压缩通常能达到 5-10 倍压缩比,100Gi 原始卷可存储约 500Gi-1Ti 的原始数据。
二、部署实战
2.1 添加 Bitnami Helm 仓库
# 添加 Bitnami Chart 仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# 查看 ClickHouse Chart 可用版本
helm search repo bitnami/clickhouse –versions | head -10
# 拉取默认 values 以便自定义
helm show values bitnami/clickhouse > /tmp/clickhouse-default-values.yaml
2.2 编写 values.yaml 自定义配置
以下 values.yaml 配置了 2 分片 2 副本的 ClickHouse 集群,存储指向 Ceph RBD StorageClass:
# /tmp/clickhouse-values.yaml
## ClickHouse 集群配置
##
shards: 2
replicaCount: 2
## ClickHouse 认证配置
##
auth:
username: "admin"
password: "ClickHouse@2026"
existingSecret: ""
## ClickHouse Keeper(内置协调服务,替代外部 ZooKeeper)
##
keeper:
enabled: true
replicaCount: 3
auth:
client:
enabled: false
persistence:
enabled: true
storageClass: "ceph-rbd"
accessModes:
– ReadWriteOnce
size: 10Gi
## ClickHouse 持久化存储(核心数据卷)
##
persistence:
enabled: true
storageClass: "ceph-rbd"
accessModes:
– ReadWriteOnce
size: 100Gi
## 资源限制(按需调整)
##
resources:
requests:
cpu: "1000m"
memory: "2Gi"
limits:
cpu: "4000m"
memory: "8Gi"
## Service 配置
##
service:
type: ClusterIP
ports:
http: 8123
tcp: 9000
mysql: 9004
## 集群配置(分布式表 DDL)
##
clickhouse:
configmap:
## 远程服务器定义(自动由 Chart 根据 shards/replicas 生成)
remote_servers: ""
## 日志级别
##
logging:
level: "information"
2.3 Helm 安装部署
# 创建独立命名空间
kubectl create namespace middleware
# 部署 ClickHouse 集群
helm install clickhouse bitnami/clickhouse
–namespace middleware
–version 6.2.0
–values /tmp/clickhouse-values.yaml
–timeout 10m
# 观察 Pod 启动过程
kubectl get pods -n middleware -w
部署完成后,各 Pod 应进入 Running 状态:
# 查看 ClickHouse 与 Keeper Pod 状态
kubectl get pods -n middleware -l app.kubernetes.io/instance=clickhouse
# 预期输出:
# NAME READY STATUS RESTARTS AGE
# clickhouse-shard0-0 1/1 Running 0 3m
# clickhouse-shard0-1 1/1 Running 0 3m
# clickhouse-shard1-0 1/1 Running 0 3m
# clickhouse-shard1-1 1/1 Running 0 3m
# clickhouse-keeper-0 1/1 Running 0 4m
# clickhouse-keeper-1 1/1 Running 0 3m
# clickhouse-keeper-2 1/1 Running 0 2m
2.4 验证 PVC 与 Service
# 查看持久化卷声明(应全部 Bound)
kubectl get pvc -n middleware -l app.kubernetes.io/instance=clickhouse
# 查看 Service
kubectl get svc -n middleware -l app.kubernetes.io/instance=clickhouse
# 查看 StatefulSet
kubectl get sts -n middleware -l app.kubernetes.io/instance=clickhouse
确认所有 PVC 状态为 Bound,且 StorageClass 为 ceph-rbd,说明 Ceph RBD 块存储已正确挂载。
三、登录验证
3.1 通过 Port-Forward 本地连接
# 转发 ClickHouse TCP 端口(原生协议 9000)
kubectl port-forward -n middleware svc/clickhouse 9000:9000 &
# 使用 clickhouse-client 连接
clickhouse-client –host 127.0.0.1 –port 9000
–user admin –password 'ClickHouse@2026'
–query "SELECT version()"
# 预期输出:24.x.x
3.2 验证集群拓扑
— 进入 clickhouse-client 交互模式
— kubectl exec -it -n middleware clickhouse-shard0-0 — clickhouse-client –user admin –password 'ClickHouse@2026'
— 查看集群分片与副本信息
SELECT
shard_num,
replica_num,
host_name,
port
FROM system.clusters
WHERE cluster = 'default';
— 预期输出:4 行(2 分片 × 2 副本)
3.3 创建分布式表测试读写
— 在每个分片创建本地表(使用 ReplicatedMergeTree 引擎)
CREATE TABLE IF NOT EXISTS events_local ON CLUSTER 'default'
(
event_time DateTime,
event_id UInt64,
user_id String,
event_type String
)
ENGINE = ReplicatedMergeTree(
'/clickhouse/tables/{shard}/events_local',
'{replica}'
)
PARTITION BY toYYYYMM(event_time)
ORDER BY (event_id, event_time);
— 创建分布式表(写入与查询的统一入口)
CREATE TABLE IF NOT EXISTS events_distributed ON CLUSTER 'default'
AS events_local
ENGINE = Distributed('default', 'default', 'events_local', rand());
— 插入测试数据
INSERT INTO events_distributed VALUES
(now(), 1, 'user_001', 'click'),
(now(), 2, 'user_002', 'view'),
(now(), 3, 'user_003', 'purchase');
— 查询验证
SELECT count() FROM events_distributed;
— 预期:3
— 验证各分片数据分布
SELECT
hostName() AS node,
count() AS rows
FROM events_distributed
GROUP BY node;
四、日常巡检命令
4.1 集群健康检查
# 检查所有 Pod 运行状态
kubectl get pods -n middleware -l app.kubernetes.io/instance=clickhouse
# 检查 Keeper 集群状态(Raft 共识)
kubectl exec -n middleware clickhouse-keeper-0 —
clickhouse-keeper-client –host clickhouse-keeper-0 –port 9181
–query "ruok"
# 预期:imok
# 检查 PVC 绑定状态
kubectl get pvc -n middleware | grep clickhouse
4.2 数据库内部巡检
# 一键巡检脚本
kubectl exec -it -n middleware clickhouse-shard0-0 —
clickhouse-client –user admin –password 'ClickHouse@2026' –multiquery << 'SQL'
— 1. 查看活跃副本同步状态
SELECT database, table, is_leader, is_readonly, is_session_expired
FROM system.replicas;
— 2. 查看合并队列积压
SELECT database, table, count() AS pending_merges
FROM system.merges
GROUP BY database, table;
— 3. 查看磁盘使用情况
SELECT
name,
path,
formatReadableSize(free_space) AS free,
formatReadableSize(total_space) AS total
FROM system.disks;
— 4. 查看最近慢查询
SELECT
query_duration_ms,
formatReadableSize(read_bytes) AS read_bytes,
substring(query, 1, 80) AS query
FROM system.query_log
WHERE type = 'QueryFinish'
ORDER BY query_duration_ms DESC
LIMIT 5;
SQL
4.3 日志查看与性能监控
# 查看 ClickHouse 服务日志
kubectl logs -n middleware clickhouse-shard0-0 –tail=50
# 查看 Keeper 日志
kubectl logs -n middleware clickhouse-keeper-0 –tail=30
# 查看 HTTP 接口指标(Prometheus 格式)
kubectl exec -n middleware clickhouse-shard0-0 —
curl -s http://admin:ClickHouse%402026@localhost:8123/metrics | head -20
4.4 容量与存储巡检
# 查看各分片数据分区大小
kubectl exec -n middleware clickhouse-shard0-0 —
clickhouse-client –user admin –password 'ClickHouse@2026'
–query "
SELECT
database,
table,
partition,
formatReadableSize(sum(bytes_on_disk)) AS size
FROM system.parts
WHERE active = 1
GROUP BY database, table, partition
ORDER BY size DESC
LIMIT 10
"
# 查看 Ceph RBD 卷的实际使用量
kubectl exec -n middleware clickhouse-shard0-0 — df -h /bitnami/clickhouse/data
五、常见问题
Q1: 副本同步延迟过大怎么办?
A: 首先检查 Keeper 集群是否健康(ruok 返回 imok)。然后查看 system.replicas 表中的 log_pointer 和 absolute_delay 字段——如果 absolute_delay 持续增大,说明副本拉取日志落后。可能原因:网络带宽不足、合并操作过多。解决方案:限制后台合并并发数 background_pool_size,或临时暂停大表的 OPTIMIZE 操作。
Q2: ClickHouse Pod 启动失败,日志报 “Too many parts”?
A: 这通常是因为之前频繁写入小 batch 导致 parts 碎片过多。解决方案:先调大 max_parts_in_total 参数(在 users.xml 或 profiles 中设置),待 Pod 启动后手动执行 OPTIMIZE TABLE table FINAL 合并 parts,然后恢复大批量写入策略(建议单次写入不少于 1000 行)。
Q3: Ceph RBD 卷 I/O 延迟高影响查询性能?
A: ClickHouse 对存储 I/O 极其敏感。排查步骤:①在 Ceph 侧检查对应 RBD image 所在 OSD 的负载与延迟;②确认 Ceph 池副本数不要过高(2 副本通常足够);③在 ClickHouse 配置中启用 cache 磁盘策略,将热点数据缓存到本地 NVMe;④对于超高频查询场景,考虑使用本地 PV + Ceph 备份的混合方案。
六、总结
本篇使用 Bitnami 官方 Helm Chart 在 K8s 上部署了 2 分片 × 2 副本的 ClickHouse 分布式列式数据库集群,配合 ClickHouse Keeper 实现副本自动同步,所有数据卷挂载到 Ceph RBD StorageClass 实现持久化高可用。关键要点回顾:
- 架构设计:ClickHouse 采用分片+副本的双维度扩展,分片实现水平扩展写入,副本实现数据冗余高可用
- Chart 部署:
bitnami/clickhouseChart 内置 Keeper,无需额外部署 ZooKeeper,一键完成集群搭建 - 存储规划:Ceph RBD 提供低延迟块存储,结合列式压缩可达 5-10 倍存储效率
- 验证巡检:通过
system.clusters、system.replicas、system.merges等系统表全面掌控集群状态
下期预告
明天是本系列的收官之作——第 15 天:K8s 中间件统一监控与运维巡检总结(Prometheus + Grafana 全景)。我们将搭建统一的监控平台,将前面 13 篇部署的所有中间件(MySQL、Redis、MongoDB、Kafka、ClickHouse 等)指标统一接入 Prometheus + Grafana,构建完整的云原生中间件运维监控全景图。
系列目录
- ✅ 第 1 天:Ceph 分布式存储回顾与 K8s 存储体系概述
- ✅ 第 2 天:K8s 接入 Ceph RBD 块存储(CSI Driver + StorageClass 配置实战)
- ✅ 第 3 天:K8s 接入 CephFS 共享文件存储(多读场景与性能调优)
- ✅ 第 4 天:K8s 部署 MySQL 高可用集群(Ceph RBD 持久化 + 架构设计 + 登录巡检)
- ✅ 第 5 天:K8s 部署 Redis Cluster 集群(Ceph RBD + 架构设计 + 巡检命令)
- ✅ 第 6 天:K8s 部署 Redis Sentinel 哨兵模式(高可用架构 + 登录验证)
- ✅ 第 7 天:K8s 部署 MinIO 对象存储集群(分布式架构 + 运维巡检)
- ✅ 第 8 天:K8s 部署 MongoDB 副本集集群(Ceph RBD + 架构设计 + 登录)
- ✅ 第 9 天:K8s 部署 Nacos 注册配置中心(集群架构 + 登录巡检)
- ✅ 第 10 天:K8s 部署 Zookeeper 集群(分布式协调架构 + 运维命令)
- ✅ 第 11 天:K8s 部署 Elasticsearch 集群(Ceph RBD + 架构设计 + 巡检)
- ✅ 第 12 天:K8s 部署 Kafka 集群(Ceph RBD + 消息队列架构 + 运维)
- ✅ 第 13 天:K8s 部署 GitLab 代码托管平台(Ceph RBD 持久化 + 架构 + 巡检)
- 📌 第 14 天:K8s 部署 ClickHouse 列式数据库集群(Ceph RBD + 架构设计)(本文)
- 🔜 第 15 天:K8s 中间件统一监控与运维巡检总结(Prometheus + Grafana 全景)

















暂无评论内容