Clickhouse 架构详解
ClickHouse 是一款开源、高性能、列式存储的实时联机分析处理(OLAP)数据库,由俄罗斯 Yandex 公司研发。它彻底区别于 MySQL 这类行式事务数据库(OLTP),核心优势是海量数据秒级分析、超高压缩比、低存储成本、支持实时写入。
本文摒弃晦涩的学术术语,用通俗化逻辑、底层原理、实战代码、运维规范全方位拆解 ClickHouse 架构,帮助读者从「会用」进阶到「懂原理、会调优、能落地」。
一、核心定位与底层设计思想(架构基石)
想要读懂 ClickHouse 架构,首先要理解它的设计初衷:专门解决「海量结构化数据的快速统计分析」问题,放弃了传统数据库的事务、高频更新能力,极致优化查询和写入性能。其核心设计思想有5个核心维度,也是它性能碾压传统大数据组件的关键。
1.1 列式存储:OLAP 场景的最优解
传统 MySQL 是行式存储,存储逻辑为「一行所有字段连续存储」,适合增删改查、单条数据查询;而 ClickHouse 采用纯列式存储,存储逻辑为「同一列的所有数据连续存储」。
通俗举例:一张用户行为表包含用户ID、姓名、访问时间、页面地址、停留时长5个字段。若需要统计「今日平均停留时长」,行式数据库需要读取整行5个字段数据,而列式数据库仅需读取「停留时长」一列数据,IO 开销直接降低 80% 以上。
同时,同列数据数据类型一致、特征相似,可实现超高压缩比(常见压缩比 3:1~10:1),大幅降低磁盘存储和读取开销。
1.2 向量化执行:批量数据计算,碾压逐行计算
普通数据库执行SQL时,是「逐行读取、逐行计算」,CPU 频繁切换指令,效率极低。ClickHouse 内置向量化执行引擎,默认将 8192 行数据封装为一个向量块,基于 CPU SIMD 指令实现「单指令批量处理多行数据」。
该设计让数据计算效率提升 3~5 倍,彻底消除了单行计算的 CPU 冗余开销,是其大查询秒级返回的核心原因之一。
1.3 稀疏索引:平衡索引效率与存储开销
传统数据库为每行数据建立索引,索引体积甚至超过数据本身,海量数据场景完全不可用。ClickHouse 采用稀疏主键索引,默认每 8192 行(索引粒度 index_granularity)建立一个索引标记。
索引文件仅记录每8192行的主键最大值、数据磁盘偏移量,索引体积极小、加载极快。查询时先通过索引过滤无效数据块,再精准读取目标数据,完美平衡了索引查询效率和存储成本。
1.4 后台数据合并:有序存储优化查询
ClickHouse 支持高并发实时写入,写入时不会立即排序合并数据,而是批量生成小数据块,避免写入阻塞。后台线程会异步对小数据块进行合并、排序、去重、聚合,最终生成有序的大文件。
该设计实现了「高吞吐写入」和「有序高效查询」的双赢,也是 MergeTree 引擎的核心设计逻辑。
1.5 无锁架构+线程池复用
ClickHouse 核心读写逻辑采用无锁设计,避免多线程锁竞争开销;同时内置固定线程池,复用线程资源,杜绝频繁创建销毁线程的性能损耗,高并发场景稳定性极强。
二、ClickHouse 整体分层架构(全局总览)
ClickHouse 整体架构分为四层核心架构+辅助组件,从请求接入到数据存储层层解耦,结构清晰、职责单一,同时支持单机和集群两种部署模式。
2.1 整体四层核心架构
1. 接入层(访问层)
负责接收客户端请求,支持多种通用协议,适配各类业务场景。支持 TCP、HTTP 双协议,兼容 JDBC/ODBC、Python、Go、命令行客户端等各类接入方式,同时管理用户会话、权限校验、请求限流等基础能力。
2. 查询处理层(核心计算层)
整个架构的大脑,负责SQL的全流程处理,分为三个核心模块:
- 解析器:校验SQL语法,将SQL语句解析为抽象语法树,剔除非法语句;
- 优化器:自动优化SQL执行逻辑,例如裁剪无效列、下推过滤条件、优化聚合顺序、分布式查询分片;
- 执行器:基于向量化引擎执行计算,分布式场景下负责跨节点任务调度、结果聚合。
3. 存储层(数据持久层)
ClickHouse 的核心底座,负责数据落地、索引管理、文件合并、冷热数据清理。核心为MergeTree 系列存储引擎,所有业务核心表均基于此系列引擎构建,其他引擎仅作为辅助。数据以分区文件、标记文件、索引文件的形式持久化在磁盘,支持数据压缩、分区管理、TTL 自动清理。
4. 集成层
负责与外部系统联动,支持 Kafka、MySQL、HDFS、S3 等数据源的实时同步、批量导入,同时支持数据导出、备份恢复、监控对接等扩展能力。
2.2 单机架构 vs 分布式架构
1. 单机架构
所有组件集成在单个节点,部署简单、运维成本低,适合中小数据量(千万级 ~ 亿级)、测试环境、小型业务分析场景。单机模式下无分片、无副本,数据读写均在本地完成。
2. 分布式架构(生产主流)
基于「分片+副本+协调」架构搭建集群,支撑十亿级、百亿级海量数据,支持高可用、水平扩容,是生产环境标准架构,核心概念如下:
- 本地表:每个节点真实存储数据的物理表,仅当前节点可读写;
- 分布式表:逻辑虚拟表,不存储数据,负责将SQL请求分发到所有分片本地表,聚合结果后返回客户端;
- 分片:将数据均匀拆分到多个节点,实现读写负载分担、容量扩容;
- 副本:每个分片部署多个副本节点,实现数据高可用,单节点故障不影响业务;
- ZooKeeper:集群协调核心,负责副本数据同步、节点健康检测、分布式DDL同步、数据合并调度。
三、核心存储引擎:MergeTree 深度解析(架构核心)
存储引擎是 ClickHouse 的灵魂,而 MergeTree 是唯一支持生产核心业务的引擎,所有高性能、高可用能力均基于此实现。其他引擎(Memory、Buffer、CSV 等)仅用于临时数据、数据中转、外部导入。
3.1 MergeTree 核心特性
- 支持实时高吞吐写入,支持秒级千万级数据写入;
- 支持分区、主键索引、稀疏索引、数据压缩;
- 后台异步数据合并,自动整理碎片化数据;
- 支持 TTL 自动过期清理冷热数据;
- 支持副本高可用、分布式分片存储。
3.2 MergeTree 核心衍生引擎(生产常用)
原生 MergeTree 仅支持基础存储,官方基于其内核衍生出4个高频实用引擎,适配不同业务场景,附实战建表代码。
1. ReplacingMergeTree(去重引擎)
适用于存在重复数据、需要自动去重的场景(如用户行为重放、数据重试写入)。合并数据时,会根据版本字段保留最新一条数据,删除历史重复数据。
-- 实战建表:用户访问日志去重表
CREATE TABLE user_visit_log (
user_id UInt64 COMMENT '用户ID',
visit_time DateTime COMMENT '访问时间',
page_url String COMMENT '访问页面',
create_version UInt32 COMMENT '数据版本'
) ENGINE = ReplacingMergeTree(create_version)
PARTITION BY toYYYYMM(visit_time) -- 按月分区
ORDER BY (user_id, visit_time) -- 排序主键(去重依据)
PRIMARY KEY (user_id)
TTL visit_time + INTERVAL 30 DAY DELETE; -- 30 天自动清理冷数据
2. SummingMergeTree(预聚合引擎)
适用于指标统计场景,写入明细数据后,后台自动对指定字段求和聚合,查询时直接读取聚合结果,大幅提升统计查询速度。
-- 实战建表:用户每日访问指标聚合表
CREATE TABLE user_daily_metric (
user_id UInt64,
stat_date Date,
click_count UInt32 COMMENT '点击次数',
income Float64 COMMENT '收益金额'
) ENGINE = SummingMergeTree
PARTITION BY toYYYYMM(stat_date)
ORDER BY (user_id, stat_date)
-- 自动聚合字段:click_count求和、income求和
SUMMING COLUMNS (click_count, income);
3. AggregatingMergeTree(复杂聚合引擎)
支持计数、去重、最大值、最小值等复杂聚合,搭配物化视图可实现实时预计算指标,是大屏实时报表的核心方案。
4. MergeTree(原生基础引擎)
仅存储明细数据,无自动聚合、无自动去重,适用于无需预处理的原始日志存储场景。
3.3 MergeTree 数据存储结构
每张 MergeTree 表的数据会按「分区-数据块」分层存储,磁盘核心文件包含:
- .bin 数据文件:存储真实的列数据,经过高压缩处理;
- .idx 索引文件:稀疏主键索引,记录每8192行数据的主键和磁盘位置;
- .mrk 标记文件:记录数据块偏移量,快速定位读取位置;
- partition 分区目录:按时间/自定义字段分区,实现分区裁剪、批量清理。
四、SQL 查询执行全流程(通俗拆解)
以分布式集群查询为例,完整拆解一条SQL从请求到返回结果的全流程,帮助理解架构运行逻辑:
- 请求接入:客户端通过HTTP/TCP发送SQL查询请求,接入层完成权限校验、限流;
- SQL解析优化:解析器校验语法,优化器自动下推where过滤条件、裁剪无用列、生成分布式执行计划;
- 分布式调度:分布式表将查询任务分发到集群所有分片节点;
- 本地数据查询:各分片节点执行本地查询,通过稀疏索引过滤无效数据块,读取目标列数据;
- 向量化计算:执行器以向量块为单位完成过滤、聚合、排序计算;
- 结果聚合返回:协调节点汇总所有分片结果,合并去重、二次聚合后,返回最终数据给客户端。
五、适用场景与禁用场景(架构适配核心)
ClickHouse 的所有架构设计都为「海量数据实时分析」服务,场景适配是落地关键,用对场景性能翻倍,用错场景完全不可用。
5.1 核心适用场景
- 实时日志分析:业务日志、服务器日志、网关日志海量存储与实时检索;
- 用户行为分析:用户点击、浏览、下单行为明细存储、用户画像统计;
- 实时数据大屏:电商交易额、UV/PV、设备监控指标实时统计展示;
- 时序数据分析:物联网设备数据、监控指标、时序数据批量分析;
- 离线批量分析:替代Hive,实现海量数据秒级交互式查询。
5.2 绝对禁用场景
- 事务业务(OLTP) :不支持事务、行级锁,无法用于订单、支付、用户账号等需要强一致性的业务;
- 高频更新/删除:不支持单行高频update/delete,批量更新性能极差;
- 小数据量频繁查询:架构针对海量数据优化,小数据量场景优势不明显,资源开销高于 MySQL;
- 关联复杂查询:多表大JOIN性能较弱,不适合复杂多表关联业务。
六、编程实战:核心常用代码示例
本节提供生产高频使用的可运行代码,涵盖建表、写入、查询、物化视图、分区管理核心操作。
6.1 基础建表(标准生产模板)
-- 业务日志明细表(生产通用模板)
CREATE TABLE business_log (
log_id String COMMENT '日志唯一ID',
app_name String COMMENT '应用名称',
event_type String COMMENT '事件类型',
user_id UInt64 COMMENT '用户ID',
request_time DateTime COMMENT '请求时间',
cost_time UInt32 COMMENT '请求耗时ms',
error_msg Nullable(String) COMMENT '错误信息'
) ENGINE = MergeTree
PARTITION BY toDate(request_time) -- 按天分区
ORDER BY (app_name, event_type, request_time) -- 排序主键
PRIMARY KEY (app_name, event_type)
INDEX idx_cost_time cost_time TYPE minmax GRANULARITY 2 -- 二级索引
TTL request_time + INTERVAL 15 DAY DELETE -- 15 天自动清理
SETTINGS index_granularity = 8192;
6.2 批量数据写入(高性能推荐)
-- 批量插入(单次写入 ≥ 1000 行,杜绝单行频繁写入)
INSERT INTO business_log VALUES
('10001','order-service','pay_success',10086,now(),12,NULL),
('10002','order-service','pay_fail',10087,now(),56,'余额不足'),
('10003','user-service','login',10088,now(),8,NULL);
6.3 实时物化视图(预计算指标)
无需定时任务,写入明细数据自动聚合指标,实现实时大屏:
-- 创建每日应用事件统计物化视图
CREATE MATERIALIZED VIEW app_event_mv
ENGINE = SummingMergeTree
PARTITION BY toYYYYMMDD(request_time)
ORDER BY (app_name, event_type, request_time)
AS SELECT
app_name,
event_type,
toDate(request_time) as stat_date,
count(log_id) as event_total -- 事件总数
FROM business_log
GROUP BY app_name, event_type, stat_date;
6.4 常用运维SQL
-- 查看表分区
SELECT partition, name, rows, disk_size FROM system.parts WHERE table = 'business_log';
-- 手动触发分区合并(紧急数据整理)
OPTIMIZE TABLE business_log FINAL;
-- 删除指定分区
ALTER TABLE business_log DROP PARTITION '2026-05-20';
七、生产运维核心要点与性能调优
ClickHouse 的性能上限不仅由架构决定,更依赖规范的运维调优,本节总结生产核心运维规则与避坑点。
7.1 写入运维规范
- 禁止单行写入:必须批量写入,单次写入1000~10000行,大幅减少小文件生成;
- 高频写入使用Buffer引擎中转:短时超高并发写入,通过Buffer表聚合数据后批量落地,避免频繁合并;
- 分区粒度合理:数据量千万级用天分区,亿级用小时分区,杜绝单分区数据过大。
7.2 性能调优核心技巧
- 主键设计精简:ORDER BY 字段不宜过多,仅保留查询过滤高频字段,减少索引开销;
- 开启数据压缩:生产默认启用LZ4 压缩,冷数据可开启ZSTD 高压缩算法,节省磁盘空间;
- 查询条件下推:尽量在WHERE中过滤数据,减少聚合计算的数据量;
- 避免大JOIN:优先通过预聚合、宽表设计规避多表关联。
7.3 高可用运维要点
- 集群必须部署ZooKeeper,保障副本同步、故障自动切换;
- 每个分片至少2个副本,杜绝单节点故障数据丢失;
- 定时备份元数据与核心数据,定期清理过期分区、碎片化文件;
- 集群所有节点时区、时间同步,避免时间分区查询异常。
7.4 常见坑点规避
- ReplacingMergeTree 去重仅在数据合并后生效,实时查询可能存在重复数据,需加FINAL关键字;
- 后台数据合并会占用CPU、磁盘IO,业务高峰期避免手动触发OPTIMIZE合并;
- 分区数量不宜过多,单表分区数建议不超过 1000,避免元数据加载缓慢。
八、架构总结与生产最佳实践
ClickHouse 的核心架构优势可以总结为:列式存储降IO、向量化计算提速度、稀疏索引省资源、异步合并保吞吐、分布式架构撑容量,是目前开源领域性价比最高的实时OLAP数据库。
生产落地最佳实践:
- 中小数据量采用单机部署,大数据量采用「分片+双副本+ZooKeeper」集群架构;
- 核心业务全部使用MergeTree系列引擎,搭配物化视图实现指标预计算;
- 严格适配场景,只做分析不做事务、只批量写入不做单行更新;
- 通过分区、TTL、批量写入、预聚合四大手段,实现性能与运维的最优平衡。