2. ClickHouse基础

市场数据监控系统对写入吞吐、查询延迟和数据保留策略有极高要求。ClickHouse 之所以能在行情快照、逐笔成交、指标聚合等场景中成为主流选择,核心在于三件事:列式存储带来的 I/O 裁剪、MergeTree 引擎提供的分区与排序能力,以及分布式架构支撑的水平扩展。理解这三者的协作方式,是后续容量规划的前提。

一、列式存储:为什么市场数据查询快

行式存储按整行连续写入,适合事务型点查;列式存储把同一列的值连续存放,适合“读少数列、扫大量行”的分析型查询。市场数据监控的典型查询是“某合约在某时间段内的最新价、成交量、买卖盘口”,只涉及少量列,却要扫描大量行,列式布局能显著减少磁盘读取量。

列式存储还带来两个直接收益:同列数据类型一致,压缩率远高于行存;按列独立读取,配合向量化执行,CPU 缓存命中率更高。对于逐笔成交这类高基数、低重复度的数据,压缩比通常仍能达到 5~10 倍,直接降低存储成本与 I/O 压力。

列式存储并非“所有查询都快”。如果查询需要返回整行宽表字段,或频繁做点更新,列存的优势会被削弱。市场数据场景应尽量按“列族”拆分查询需求,避免宽表全列扫描。

二、MergeTree引擎:分区、排序与合并

MergeTree 是 ClickHouse 最核心的表引擎家族。它把数据按分区键切分为多个 part,每个 part 内部按排序键有序存储,后台线程持续将小 part 合并为大 part。分区用于裁剪扫描范围,排序键用于加速范围过滤和主键索引定位,合并则控制 part 数量、维持查询效率。

市场数据场景中,常见的建表策略如下:

CREATE TABLE market.tick
(
    exchange   LowCardinality(String),
    symbol     LowCardinality(String),
    ts         DateTime64(3),
    price      Decimal64(4),
    volume     UInt64,
    side       Enum8('buy'=1, 'sell'=2)
)
ENGINE = MergeTree
PARTITION BY toYYYYMMDD(ts)
ORDER BY (exchange, symbol, ts)
TTL ts + INTERVAL 30 DAY DELETE
SETTINGS index_granularity = 8192;

这里分区键按天切分,便于按时间淘汰;排序键以交易所、合约、时间排列,使同一合约的时间范围查询能连续读取;TTL 自动清理过期数据,降低运维负担。需要强调的是,排序键顺序直接影响索引效率,应把过滤频率最高、基数适中的列放在前面。

三、分布式架构:分片与副本

单机 MergeTree 受限于磁盘与 CPU,当写入量或数据量增长时,需要引入分布式表。ClickHouse 集群由多个分片组成,每个分片可配置多个副本。分布式表本身不存数据,只负责把查询路由到各分片并汇总结果;本地表才是实际存储数据的载体。

组件职责市场数据场景要点
分片(Shard)水平切分数据,分散写入与查询压力按交易所或合约哈希分片,避免热点
副本(Replica)数据冗余,提升可用性与读吞吐至少 2 副本,保障行情不中断
分布式表查询路由与结果聚合写入可走分布式表,也可直写本地表
ZooKeeper / ClickHouse Keeper协调副本一致性副本表必须依赖,需独立规划

分布式查询的执行过程是:客户端查询分布式表,Coordinator 将查询下发到各分片,各分片在本地并行执行,最后汇总返回。若查询包含 GROUP BY 或 ORDER BY,聚合会在各分片先做局部聚合,再在发起节点做最终合并。因此,分片键选择不当会导致数据倾斜,某些分片成为瓶颈。

分布式表不保证写入原子性。批量写入时若部分分片失败,可能出现数据不一致。生产环境应使用带重试的写入客户端,并监控各分片 part 数量与延迟。

四、市场数据场景与常见误区

以行情监控为例,典型数据流是:采集端写入逐笔与快照,MergeTree 按天分区存储,物化视图实时聚合分钟级指标,监控面板查询分布式表获取最新状态。容量规划需要同时考虑原始数据增长、副本放大、合并临时空间以及 TTL 清理节奏。

市场数据写入与查询路径 行情采集端 逐笔 / 快照 分布式表写入 按分片键路由 分片1 本地表 MergeTree 分区 副本 ×2 分片2 本地表 MergeTree 分区 副本 ×2 物化视图 分钟级聚合 监控查询 分布式表聚合 容量告警 磁盘 / part 数 分区裁剪 → 排序键定位 → 分片并行 → 结果汇总

常见误区有三类。第一,把分布式表当作普通表频繁点查,忽略网络聚合开销;第二,分区键粒度过细,导致 part 数量爆炸,合并跟不上写入;第三,只规划原始数据容量,忽略副本、合并临时空间和 TTL 删除延迟。复盘时应重点检查 part 数量、合并队列长度、各分片磁盘使用率是否均衡。

容量规划的核心公式可简化为:所需磁盘 ≈ 原始数据量 × 压缩比倒数 × 副本数 × (1 + 合并余量)。市场数据写入高峰明显,建议按峰值写入速率的 1.5~2 倍预留合并与查询资源。

掌握列式存储、MergeTree 与分布式架构的协作关系后,下一步才能准确评估写入吞吐、查询延迟与存储成本之间的平衡点,为后续监控指标设计和容量模型打下基础。