3. ClickHouse入门

在金融时序数据平台中,ClickHouse之所以能成为高频行情、逐笔委托、指标快照等场景的主力存储,并不是因为它“快”这一个标签,而是因为它在存储布局、执行模型和表引擎三个层面做了协同设计。理解这三层,才能判断哪些查询能跑出极致性能,哪些用法会把它拖回普通数据库的水平。

一、核心特性:为分析型负载而生的取舍

ClickHouse是面向OLAP的列式数据库,它的设计目标非常明确:在海量数据上做高吞吐的聚合与扫描。围绕这个目标,它形成了几个关键特性。

  • 列式存储:同一列的数据连续存放,天然适合只读取少数列的聚合查询,压缩比也远高于行存。
  • 向量化执行:以列块(Block)为单位批量处理,而不是逐行解释执行,充分利用CPU缓存与SIMD指令。
  • 数据分区与排序键:通过分区裁剪和主键索引跳过大量无关数据,减少I/O。
  • MergeTree引擎家族:提供主键索引、数据分区、副本、分布式、聚合预聚合等能力,是ClickHouse的核心存储抽象。
  • SQL支持与实时写入:支持标准SQL的大部分语法,同时支持高吞吐批量写入,适合近实时分析。
ClickHouse不擅长高频单行更新和删除,也不适合作为OLTP事务库。把它用在时序分析、日志分析、指标聚合场景,才能发挥其优势。

二、列式存储与向量化执行:性能的两大支柱

列式存储解决的是“读多少”的问题。假设一张行情表有20个字段,查询只关心symbol、price、ts三列,列存只需读取这三列的数据文件,而行存需要把整行读出来再丢弃无用字段。对于动辄数十亿行的时序数据,这个差距是数量级的。

向量化执行解决的是“怎么算”的问题。传统执行器一次处理一行,函数调用和分支判断开销大;ClickHouse把数据组织成列块,一次对一批值执行相同操作,编译器更容易优化,CPU流水线也更少停顿。两者结合,才形成ClickHouse“扫描快、聚合快”的体感。

列式存储 + 向量化执行:从磁盘到CPU的数据通路 磁盘列文件 symbol 列 price 列 ts 列 volume 列 列块 Block price[0..N] ts[0..N] volume[0..N] 批量列向量 向量化执行引擎 SIMD 批量计算 聚合 / 过滤 / 表达式 结果列块输出 高吞吐低开销

三、MergeTree引擎家族:ClickHouse的存储核心

MergeTree是ClickHouse最核心的表引擎,几乎所有生产表都基于它或其变体。它的基本思想是:数据按分区写入,后台异步合并成更大的有序片段,查询时利用主键索引和分区裁剪快速定位数据。

引擎 核心能力 典型金融场景
MergeTree 分区、排序键、主键索引、TTL 逐笔成交、行情快照原始表
ReplacingMergeTree 按排序键去重,保留最新版本 订单状态最新值、维表更新
SummingMergeTree 合并时对数值列求和 按分钟/小时预聚合成交量
AggregatingMergeTree 合并时按聚合函数状态合并 复杂指标预聚合、物化视图
ReplicatedMergeTree 基于ZooKeeper/Keeper的多副本 高可用行情数据表
Distributed 跨分片查询路由 集群化时序数据平台

一个典型的行情表建表语句如下:

CREATE TABLE market.tick
(
    symbol   LowCardinality(String),
    ts       DateTime64(3),
    price    Decimal64(4),
    volume   UInt64,
    exchange String
)
ENGINE = MergeTree
PARTITION BY toYYYYMMDD(ts)
ORDER BY (symbol, ts)
TTL ts + INTERVAL 90 DAY
SETTINGS index_granularity = 8192;

这里PARTITION BY按天分区,便于TTL清理和分区裁剪;ORDER BY (symbol, ts)决定主键索引顺序,查询某只股票某时间段的数据时能快速定位;index_granularity控制索引粒度,默认8192行一个标记。

排序键顺序非常关键。如果查询经常按ts范围过滤再按symbol筛选,而排序键是(symbol, ts),则无法有效利用主键索引。应根据最高频的过滤条件设计排序键。

四、安装部署:从单机到集群

ClickHouse支持多种安装方式,金融生产环境通常选择官方仓库安装或Docker部署。单机快速验证可使用以下命令:

# Ubuntu/Debian 官方仓库安装
sudo apt-get install -y apt-transport-https ca-certificates
sudo apt-get install -y clickhouse-server clickhouse-client

# 启动服务
sudo systemctl start clickhouse-server
sudo systemctl enable clickhouse-server

# 连接验证
clickhouse-client --host 127.0.0.1 --port 9000

Docker方式更适合快速搭建测试环境:

docker run -d --name clickhouse-server \
  -p 8123:8123 -p 9000:9000 \
  -v /data/clickhouse:/var/lib/clickhouse \
  clickhouse/clickhouse-server:24.3

生产集群部署需要关注几个要点:

  1. 配置Keeper:ClickHouse Keeper替代ZooKeeper,用于副本协调和分布式DDL。
  2. 分片与副本:通过remote_servers配置分片,副本数建议至少2。
  3. 资源隔离:为写入和查询配置不同的用户与资源配额,避免大查询拖垮写入。
  4. 数据目录:使用独立SSD盘,避免与系统盘争抢I/O。
  5. 监控:接入Prometheus,关注MergeTree后台合并、查询队列、磁盘使用率。

五、常见误区与复盘

  • 误区一:把ClickHouse当OLTP用。高频单行更新会导致大量小part,后台合并压力剧增。应使用批量写入和ReplacingMergeTree处理更新。
  • 误区二:排序键随意设置。排序键决定索引效率,必须结合查询模式设计,而不是照搬主键。
  • 误区三:忽略分区粒度。分区过细会产生大量小分区,过粗则TTL和裁剪效果差。按天或按月分区通常较合适。
  • 误区四:直接查原始表做复杂聚合。应利用物化视图和AggregatingMergeTree做预聚合,降低查询延迟。