ClickHouse从入门到精通:一款高性能列式数据库的完整实战指南
一、ClickHouse是什么?为什么它这么快?
1.1 列式存储的革命性设计
ClickHouse是一款真正的列式数据库管理系统,由俄罗斯搜索引擎巨头Yandex开源,专为联机分析处理(OLAP)而生。与传统的行式数据库(如MySQL、PostgreSQL)不同,ClickHouse将同一列的数据连续存储,而非将整行数据捆绑存放。
行式存储示意(文档第1页)
text
Row#0: WatchID=89354350662, JavaEnable=1, Title=Investor Relations, EventTime=2016-05-18 05:19:20 … Row#1: WatchID=903295099580, JavaEnable=1, Title=Contact us, EventTime=2016-05-18 08:10:20 …
列式存储示意(文档第1页)
text
WatchID: [89354350662, 903295099580, 899537060541, …] JavaEnable: [1,1,1,…] Title: [Investor Relations, Contact us, Mission, …] EventTime: [2016-05-18 05:19:20, 2016-05-18 08:10:20, 2016-05-18 07:38:00, …]
这一看似简单的变化,带来超过100倍的查询加速,原因在于:
-
I/O极大减少——分析查询通常只涉及百列中的少数几列,列式存储仅读取必要列。
-
压缩率飙升——同列数据具有极高相似性,压缩比可达5~10倍甚至更高。
-
CPU缓存友好——批量处理向量数据,充分利用CPU流水线和SIMD指令。
1.2 OLAP场景的天然王者
ClickHouse专为以下OLAP关键特征量身打造(文档第2页):
-
读请求压倒性多于写请求
-
以大批次(>1000行)插入为主,极少单行更新
-
宽表、海量列,但每次查询只取一小部分列
-
查询并发相对较低(单机每秒数百次)
-
允许50ms左右的查询延迟
-
数据以数字和短字符串为主
-
高吞吐量处理(单机每秒数十亿行)
-
无需完整事务,一致性要求宽松
-
查询结果显著小于源数据
1.3 从Yandex.Metrica到全球开源
ClickHouse诞生于Yandex内部,用于支撑世界第二大Web分析平台——Yandex.Metrica。2014年,该系统每天处理约120亿事件,存储20.3万亿行数据,压缩后2PB,未压缩达17PB。374台服务器的集群支撑了这一切。2016年开源后迅速成为OLAP领域的事实标准,用户列表覆盖全球顶级企业(文档第7-11页):
Bloomberg、Cisco、CERN、Uber、腾讯、新浪、Spotify、Cloudflare、德意志银行等数百家公司。
二、ClickHouse核心特性全景图
2.1 真正的列式DBMS
与HBase、Cassandra等“列族”数据库不同,ClickHouse不在值旁边存储长度,紧凑的固定长度数值类型(如UInt8)直接连续存放,解压速度达每秒数十亿未压缩字节。
2.2 数据压缩的艺术
ClickHouse不仅提供LZ4、ZSTD等通用压缩,还内置针对特定数据类型的专用编解码器:
-
Delta、DoubleDelta:适合单调递增的时间序列,压缩比极高。 -
Gorilla:Facebook Gorilla论文实现,对缓慢变化的浮点数极致压缩。 -
T64:裁剪整数列未使用的高位,特别适合小范围枚举值。
(编解码器详细清单见文档第275-276页)
2.3 多核与分布式并行
-
多核并行:单个查询自动利用服务器所有CPU核心。
-
分布式处理:数据可水平切分至多个分片,每个分片可设置副本,查询在所有分片上并行执行,用户无感知。
2.4 支持SQL·贴近标准
ClickHouse支持基于SQL的声明式查询,包含GROUP BY、ORDER BY、FROM、JOIN、IN及非关联子查询。窗口函数、关联子查询正在开发中。
特别注意:ClickHouse的SQL是强类型的,禁止隐式类型转换;函数名大小写敏感(除标准SQL关键字外)。
2.5 向量化执行引擎
数据不仅按列存储,还按列块(向量)进行处理,每个操作作用于整个向量,极大降低函数调用开销。这是ClickHouse高速查询的核心秘密。
2.6 实时数据更新·主键索引
-
MergeTree家族支持增量有序写入,数据以片段形式追加,后台自动合并。
-
稀疏主键索引:每
index_granularity行(默认8192)记录一次主键值,索引常驻内存,几十毫秒内完成数十亿行中的特定值定位。
2.7 近似计算与在线查询
-
近似聚合函数:
uniq(HyperLogLog)、quantile(T-Digest)、topK等,允许牺牲微小精度换取数量级性能提升。 -
采样查询:通过
SAMPLE子句仅扫描部分数据,快速获得统计趋势。
2.8 Adaptive Join Algorithm
ClickHouse优先使用哈希连接,当右表过大时自动降级为合并连接,适应不同数据规模。
2.9 多主复制·强一致
-
异步多主复制:写入任意副本,系统后台自动同步至其他副本。
-
数据完整性:所有传输块均带校验和,合并时跨副本字节级一致。
2.10 基于SQL的访问控制
支持角色、行策略、配额、设置集的完整RBAC模型,可通过CREATE USER、GRANT等SQL语句管理,也可通过users.xml配置。
2.11 已知限制
-
无完整事务支持(不支持回滚)
-
不支持高频低延迟的单行修改/删除(但可通过
ALTER DELETE批量操作,符合GDPR) -
稀疏索引不适合点查询——千万行中查单行需扫描整个颗粒
三、性能·数字不说谎
3.1 单个大查询吞吐量
-
内存态:简单查询可达2~10 GB/秒(未压缩),极限30 GB/秒。
-
磁盘态:取决于磁盘速度与压缩率,例如400 MB/s磁盘+3倍压缩→1.2 GB/s处理速度,对应1~2亿行/秒。
-
分布式:吞吐量近乎线性扩展。
3.2 短查询延迟
使用主键且行数少(几十万)、数据已缓存时,延迟<50ms,最佳<10ms。
若数据未缓存,HDD延迟公式:查找时间(10ms)×查询列数×查询数据块数。
3.3 大量短查询吞吐量
单机可承载每秒数百个查询(最佳数千),但OLAP场景建议每秒不超过100次。
3.4 写入性能
-
每次写入不少于1000行,或每秒不超过1个写入请求。
-
MergeTree写入速度约50~200 MB/秒(TabSeparated格式),1KB/行时对应5~20万行/秒。
-
并行插入可线性提升性能。
四、安装部署·五分钟上手
4.1 系统要求
-
CPU:x86_64支持SSE4.2,或AArch64、PowerPC64LE(需源码编译)。
-
RAM:至少4GB用于重要查询,更多用于GROUP BY、JOIN等。
-
磁盘:推荐SSD,机械硬盘需RAID10/RAID6+大缓存。
-
网络:10G以上网络最佳。
4.2 安装方式
DEB包(Ubuntu/Debian)
bash
sudo apt-get install apt-transport-https ca-certificates dirmngr sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv E0C56BD4 echo "deb https://repo.clickhouse.com/deb/stable/main" | sudo tee /etc/apt/sources.list.d/clickhouse.list sudo apt-get update sudo apt-get install -y clickhouse-server clickhouse-client sudo service clickhouse-server start clickhouse-client
RPM包(CentOS/RedHat)、Tgz通用包、Docker、源码编译方式详见文档第12-14页。
4.3 启动与验证
bash
# 手动启动(前台) clickhouse-server --config-file=/etc/clickhouse-server/config.xml # 连接测试 clickhouse-client :) SELECT 'Hello, ClickHouse!';
五、快速入门:单节点与示例数据
5.1 单节点教程(文档第15-16页)
-
创建数据库与表
sql
CREATE DATABASE IF NOT EXISTS tutorial; CREATE TABLE tutorial.hits_v1 ... ENGINE = MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)); CREATE TABLE tutorial.visits_v1 ... ENGINE = CollapsingMergeTree(Sign) ...;
-
下载并导入Yandex.Metrica样本数据
bash
curl https://datasets.clickhouse.com/hits/tsv/hits_v1.tsv.xz | unxz --threads=$(nproc) > hits_v1.tsv clickhouse-client --query "INSERT INTO tutorial.hits_v1 FORMAT TSV" --max_insert_block_size=100000 < hits_v1.tsv
-
执行分析查询(文档第22页)
sql
SELECT StartURL AS URL, AVG(Duration) AS AvgDuration FROM tutorial.visits_v1 WHERE StartDate BETWEEN '2014-03-23' AND '2014-03-30' GROUP BY URL ORDER BY AvgDuration DESC LIMIT 10;
5.2 集群部署(文档第22-24页)
配置remote_servers,创建分布式表:
xml
<remote_servers>
<perftest_3shards_1replicas>
<shard><replica><host>example01</host><port>9000</port></replica></shard>
...
</perftest_3shards_1replicas>
</remote_servers>
sql
CREATE TABLE tutorial.hits_all AS tutorial.hits_local ENGINE = Distributed(perftest_3shards_1replicas, tutorial, hits_local, rand());
六、11个经典示例数据集(文档第24-91页)
ClickHouse官方提供多个公开数据集,覆盖Web分析、广告、交通、地理、金融等场景,是学习与性能测试的绝佳资源:
| 数据集 | 规模 | 核心表 | 文档页码 |
|---|---|---|---|
| Yandex.Metrica | 1亿行hits,1000万visits | hits_v1, visits_v1 | P24-27 |
| Star Schema Benchmark | 6亿~60亿行 | lineorder, customer, part, supplier | P34-39 |
| WikiStat | 2007-2016维基页面统计 | wikistat | P39-40 |
| Criteo | 1TB点击日志 | criteo_log | P40-41 |
| AMPLab Big Data Benchmark | 1节点/5节点 | rankings, uservisits | P41-44 |
| Brown University MgBench | 机器生成日志 | logs1, logs2, logs3 | P44-50 |
| 纽约出租车 | 11亿次行程 | trips, trips_mergetree | P50-58 |
| OpenSky Network | 6600万航班 | opensky | P58-65 |
| UK Property Price Paid | 2632万房产交易 | uk_price_paid | P65-77 |
| Cell Towers | 4328万基站 | cell_towers | P77-80 |
| NYPL Menu | 130万菜单项 | menu_item_denorm | P80-87 |
| OnTime | 1987-2018航班准点 | ontime | P87-93 |
每个数据集的导入脚本、建表语句和典型查询均在文档中详细列出,可直接复制使用。
七、SQL参考·从基础到进阶
7.1 SELECT查询结构(文档第244页)
sql
[WITH expr_list|(subquery)] SELECT [DISTINCT] expr_list [FROM [db.]table | (subquery) | table_function] [FINAL] [SAMPLE sample_coeff] [ARRAY JOIN ...] [GLOBAL] [ANY|ALL|ASOF] [INNER|LEFT|RIGHT|FULL|CROSS] JOIN ... [PREWHERE expr] [WHERE expr] [GROUP BY expr_list] [WITH TOTALS] [HAVING expr] [ORDER BY expr_list] [WITH FILL] [FROM expr] [TO expr] [STEP expr] [LIMIT [offset_value, ]n BY columns] [LIMIT [n, ]m] [WITH TIES] [UNION ALL ...] [INTO OUTFILE filename] [FORMAT format]
关键特性:
-
ARRAY JOIN:将数组列展开为多行 -
WITH FILL:填充排序空缺值 -
WITH TIES:包含与第N行并列的行 -
FORMAT:支持60+种输入输出格式
7.2 表操作DDL
创建表(文档第271-279页)
sql
-- 显式定义
CREATE TABLE [IF NOT EXISTS] [db.]table_name (
name1 [type1] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|ALIAS expr1] [CODEC(...)] [TTL expr1],
...
) ENGINE = engine
-- 复制结构
CREATE TABLE new_table AS old_table ENGINE = engine
-- 从SELECT创建并填充
CREATE TABLE table_name ENGINE = engine AS SELECT ...
修改表(文档第289-298页)
-
ADD COLUMN、DROP COLUMN、RENAME COLUMN、MODIFY COLUMN -
ADD INDEX、DROP INDEX、MATERIALIZE INDEX -
ATTACH|DETACH|DROP PARTITION -
DELETE、UPDATE(异步mutation)
7.3 数据类型全览
基础类型:
-
整数:
Int8~Int256,UInt8~UInt256 -
浮点:
Float32,Float64 -
定点数:
Decimal(P,S),精度最高38位 -
字符串:
String,FixedString(N) -
日期时间:
Date,Date32,DateTime,DateTime64 -
枚举:
Enum8,Enum16 -
UUID
-
布尔值:用
UInt8(0/1)表示
复合类型:
-
数组:
Array(T) -
元组:
Tuple(T1, T2, …) -
嵌套:
Nested(Name1 Type1, Name2 Type2, …)——等价于多个同前缀数组 -
映射(实验性):
Map(key, value) -
聚合函数状态:
AggregateFunction(func, types) -
简单聚合函数:
SimpleAggregateFunction(func, type)
特殊类型:
-
IPv4,IPv6(Domain类型) -
Point,Ring,Polygon,MultiPolygon(地理类型,实验性) -
Interval(时间间隔) -
Nothing(仅用于表示空数组)
7.4 函数体系
常规函数(文档第371页起)
-
算术、比较、逻辑、类型转换
-
字符串:
substring,concat,replace,match,ngramDistance -
日期时间:
toDate,toDateTime,date_add,dateDiff -
URL:
domain,path,extractURLParameter -
数组:
length,arrayConcat,arrayMap,arrayFilter -
JSON:
JSONExtract,JSONHas(基于simdjson) -
哈希:
sipHash64,cityHash64,xxHash64 -
加密:
encrypt,decrypt,aes_encrypt_mysql
聚合函数(文档第506页起)
-
标准:
count,sum,avg,min,max,any -
去重:
uniq,uniqExact,uniqCombined,uniqHLL12 -
分位数:
quantile,quantiles,quantileExact,quantileTDigest -
统计:
varPop,stddevPop,covarPop,corr -
机器学习:
stochasticLinearRegression,stochasticLogisticRegression -
位图:
groupBitmap,groupBitmapAnd,groupBitmapOr -
其他:
topK,groupArray,groupUniqArray,windowFunnel,retention
组合器(Combinators)(文档第560页)
-
-If:条件聚合,如sumIf -
-Array:处理数组列 -
-State:返回聚合中间状态 -
-Merge:合并聚合状态 -
-ForEach:对数组元素分别聚合 -
-OrDefault/-OrNull:空输入时返回默认值/NULL -
-Resample:按时间/数值区间分组聚合
八、表引擎·存储的灵魂
8.1 MergeTree家族——生产首选
核心特性:主键排序、分区、数据副本、TTL、数据采样。
建表示例(文档第174页):
sql
CREATE TABLE table_name
(
EventDate DateTime,
CounterID UInt32,
UserID UInt64
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(EventDate)
ORDER BY (CounterID, EventDate, intHash32(UserID))
SAMPLE BY intHash32(UserID)
SETTINGS index_granularity = 8192;
常见变种:
-
ReplacingMergeTree:合并时保留每组排序键的最后一行。 -
SummingMergeTree:合并时将数值列按主键求和。 -
AggregatingMergeTree:存储聚合函数状态,实现增量聚合。 -
CollapsingMergeTree/VersionedCollapsingMergeTree:通过标记行实现实时更新/删除。 -
GraphiteMergeTree:专为Graphite监控数据优化,支持预定义的降采样规则。
TTL(生存时间)(文档第181页):
sql
-- 列级TTL ALTER TABLE table_name MODIFY COLUMN c String TTL d + INTERVAL 1 DAY; -- 表级TTL(自动删除过期行) ALTER TABLE table_name MODIFY TTL d + INTERVAL 1 MONTH;
数据跳过索引(文档第179页):
sql
INDEX idx_name (column) TYPE minmax GRANULARITY 4; INDEX bf_idx (str) TYPE ngrambf_v1(3, 256, 2, 0) GRANULARITY 1;
支持minmax、set(max_rows)、ngrambf_v1、tokenbf_v1、bloom_filter五种类型。
8.2 日志引擎·轻量级
-
TinyLog:最简单的文件存储,每列单独文件,适合一次写入多次读取的小表。 -
Log:带标记文件,支持并发读取,写入阻塞。 -
StripeLog:所有列存储在同一文件中,节省描述符。
8.3 集成引擎·无缝连接外部系统
| 引擎 | 功能 | 文档页 |
|---|---|---|
Kafka | 直接消费Kafka消息 | P222-224 |
RabbitMQ | 消费RabbitMQ队列 | P207-210 |
MySQL | 查询/写入远程MySQL表 | P224-225 |
PostgreSQL | 查询/写入远程PostgreSQL表 | P210-212 |
MongoDB | 只读MongoDB集合 | P201 |
ODBC / JDBC | 通过ODBC/JDBC连接任意数据库 | P215-218 |
HDFS | 读写HDFS文件 | P218-222 |
S3 | 读写Amazon S3对象 | P201-205 |
EmbeddedRocksDB | 嵌入RocksDB作为键值存储 | P206 |
SQLite | 读写SQLite数据库文件 | P205-206 |
8.4 分布式引擎
Distributed(cluster, database, table [, sharding_key])
本身不存储数据,作为集群的统一访问入口,支持自动路由、负载均衡、本地副本优先。
8.5 其他实用引擎
-
Dictionary:将外部字典映射为表,支持dictGet函数。 -
Merge:合并多个同结构表的虚拟视图。 -
File/URL:直接读写文件或HTTP服务器。 -
Null:写入丢弃,读取为空,用于测试。 -
Memory:全内存表,重启丢失。 -
Buffer:内存缓冲表,定期写入目标表。 -
Set/Join:专门用于IN子句和JOIN操作的右表,常驻内存。
九、系统表·服务器的“体检报告”
ClickHouse将自身状态以表的形式暴露在system数据库中(文档第692页起)。
| 系统表 | 用途 |
|---|---|
system.tables / system.columns | 元数据查询 |
system.parts / system.parts_columns | 数据部分信息、行数、磁盘占用 |
system.replicas / system.replication_queue | 复制状态、队列 |
system.query_log / system.query_thread_log | 查询历史、性能剖析 |
system.metrics / system.events | 实时监控指标 |
system.asynchronous_metrics | 后台采集的指标(内存、CPU) |
system.trace_log | 采样查询堆栈(性能火焰图) |
system.dictionaries | 外部字典状态 |
system.merges | 正在进行的合并 |
system.mutations | 正在执行的异步修改操作 |
system.zookeeper / system.zookeeper_log | ZooKeeper交互调试 |
system.clusters | 配置的集群信息 |
system.errors | 错误累计计数器 |
system.stack_trace | 服务器线程堆栈(调试神器) |
十、运维·让生产系统坚如磐石
10.1 配置管理(文档第763页)
ClickHouse采用XML配置,支持主配置文件config.xml和config.d/覆盖目录。关键配置项:
-
<path>:数据目录 -
<logger>:日志级别、轮转 -
<mark_cache_size>:标记缓存(MergeTree索引) -
<uncompressed_cache_size>:未压缩数据缓存 -
<max_concurrent_queries>:并发查询限制 -
<merge_tree>:合并策略、阈值 -
<zookeeper>:复制集群ZooKeeper地址 -
<remote_servers>:分布式集群定义
10.2 用户·角色·权限·配额
SQL驱动权限管理(推荐,需设置access_control_path):
sql
CREATE USER john IDENTIFIED WITH sha256_password BY 'qwerty'; CREATE ROLE analyst; GRANT SELECT ON db.* TO analyst; GRANT analyst TO john; SET DEFAULT ROLE analyst TO john;
行级安全:
sql
CREATE ROW POLICY filter ON mydb.mytable USING department = 'sales' TO sales_team;
配额限制:
sql
CREATE QUOTA qa FOR INTERVAL 60 minute MAX queries = 1000 TO john;
10.3 数据备份与恢复
-
快照备份(文档第682页):
sql
ALTER TABLE table_name FREEZE [PARTITION partition_expr];
在/var/lib/clickhouse/shadow/下生成硬链接,复制后解冻:
sql
ALTER TABLE table_name UNFREEZE [PARTITION 'part_expr'] WITH NAME 'backup_name';
-
部分导出/导入:
sql
INSERT INTO FUNCTION file('export.tsv') SELECT * FROM table;
INSERT INTO table SELECT * FROM file('export.tsv', 'TSV', 'col1 Type1, ...');
-
clickhouse-copier:跨集群大规模数据迁移与重分片。
10.4 监控与告警
-
内置
system.metrics、system.events、system.asynchronous_metrics提供丰富指标。 -
支持向Graphite发送时序数据(文档第779页)。
-
HTTP接口
/ping健康检查,/replicas_status副本延迟监控。 -
与Prometheus、Grafana无缝集成,官方exporter已存在。
10.5 升级策略
-
滚动升级:逐个节点升级,集群仍可用。
-
特别注意:1.1.54378版本后启用了
use_minimalistic_part_header_in_zookeeper,降级需谨慎(文档第791页)。
十一、开发指南·从源码到PR
11.1 编译ClickHouse(文档第1158页)
依赖:CMake、Ninja、Clang 11+
交叉编译ARM64、Mac OS X、FreeBSD均有详细步骤。
bash
git clone --recursive https://github.com/ClickHouse/ClickHouse.git mkdir build && cd build CC=clang-11 CXX=clang++-11 cmake .. ninja clickhouse-server clickhouse-client
11.2 测试体系(文档第1159页)
-
功能测试:
tests/queries/0_stateless,SQL脚本与.reference结果文件。 -
集成测试:Docker容器模拟多节点、依赖服务。
-
单元测试:gtest,位于
src/下*_tests目录。 -
性能测试:
tests/performance,XML定义查询,对比基准。 -
模糊测试:AST随机变形、libFuzzer。
11.3 代码风格(文档第1167页)
-
缩进4空格,大括号独占一行。
-
类名CamelCase,函数camelCase,变量snake_case。
-
使用
using而非typedef,优先enum class。 -
智能指针管理内存,异常代替返回码。
-
clang-format已配置,提交前建议格式化。
11.4 贡献流程
-
Fork官方仓库,创建功能分支。
-
提交代码,确保通过CI:
Fast Test、Build Check、Style Check、Functional Tests等。 -
填写PR模板,添加ChangeLog分类。
-
等待Review,合并后你的名字将出现在
system.contributors中。
十二、常见问题精解(文档第833-845页)
Q:ClickHouse可以作为Key-Value存储吗?
A:不推荐。稀疏索引导致点查询效率低,若必须使用,可考虑Join表引擎 + joinGet,或单行聚合方案。
Q:如何删除旧数据?
A:三种方式:
-
TTL:自动删除过期数据。
-
ALTER DELETE:异步mutation,适合不规则删除。
-
DROP PARTITION:最快的方式,需合理设计分区键。
Q:如何选择稳定版还是LTS版?
A:stable每月发布,包含最新特性,推荐大多数用户。lts每年两版,支持期一年,适合对升级频率敏感的场景。
Q:从MySQL/Oracle迁移有哪些注意事项?
A:可通过MaterializedMySQL(实验性)同步,或使用mysql表函数、ODBC桥接。注意数据类型映射、NULL处理、字符集。
十三、总结
ClickHouse凭借列式存储、向量化执行、分布式架构、极致压缩四大支柱,重新定义了OLAP数据库的速度极限。它不只是一个数据库,更是一个完整的生态系统——从数十种表引擎、百款数据格式到完整的RBAC、配额、监控体系,能够独立承载PB级实时分析业务。
参考资料:
-
本文所有内容均整理自ClickHouse中文官方文档(2026年2月版),原文档共1216页,涵盖自2017年至2024年的全部变更日志。
-
文中提及的所有图片、架构图、数据流图均位于原文档对应页码,此处仅以文字说明指代。
-
最新文档请访问:ClickHouse官方文档
更多推荐
所有评论(0)