1. 课程导入
在金融交易、量化投研与行情分发系统中,行情数据是最典型的高吞吐、强时序、低延迟场景之一。无论是股票 Level-1/Level-2 快照、逐笔委托与成交,还是期货、期权、数字货币的盘口与深度数据,都具有“写入密集、查询实时、维度丰富、时间敏感”的共同特征。本课程围绕 ClickHouse 这一列式实时分析数据库,系统讲解行情数据的建模、入库与实时聚合,帮助你把“能存、能查、能算得快”真正落地到生产环境。
一、行情数据场景:为什么它比普通业务数据更难处理
行情数据通常以“快照 + 增量”的方式持续产生。以 A 股 Level-2 为例,单市场每日逐笔成交与委托可达数亿条,盘口快照按 3 秒或更细粒度切片,叠加多交易所、多品种、多合约后,日增数据量轻松达到 TB 级。它同时具备以下难点:
- 写入吞吐极高:开盘与收盘时段瞬时峰值可达每秒数十万到数百万行,要求写入链路具备批量、异步、可回压能力。
- 查询模式多样:既有点查最新盘口,也有区间扫描、K 线聚合、因子计算、历史回放与实时监控。
- 时间维度强:几乎所有查询都带时间范围,且要求按交易所时间、本地时间、业务日期多口径对齐。
- 乱序与重复:网络抖动、采集重连、多源合并会导致数据乱序、重复、缺失,需要幂等与去重策略。
- 实时性要求高:监控、风控、策略信号往往要求秒级甚至亚秒级可见。
传统方案中,关系型数据库在写入吞吐和聚合扫描上容易成为瓶颈;HBase 等 KV 存储擅长点查但弱于多维聚合;Kafka 适合缓冲但不适合长期分析与回放。ClickHouse 的出现,恰好补上了“高吞吐写入 + 实时聚合 + 低成本存储”这一关键环节。
二、ClickHouse 的核心优势与原理要点
ClickHouse 是面向 OLAP 的列式数据库,其性能来自一整套协同设计,而不是单一技巧。理解这些原理,才能做出正确的建模与参数选择。
- 列式存储:同一列数据连续存放,聚合查询只读取必要列,I/O 大幅减少,压缩率显著提升。
- 向量化执行:按块(Block)批量处理,配合 SIMD 指令,单核吞吐远高于逐行处理。
- 稀疏主键索引:按 ORDER BY 建立稀疏索引,快速定位 granule,适合时间范围扫描。
- MergeTree 家族:支持分区、排序键、TTL、副本、物化视图与后台合并,天然适配时序数据。
- 多样引擎:ReplacingMergeTree 去重、SummingMergeTree 预聚合、AggregatingMergeTree 存中间态,覆盖行情常见需求。
- 实时写入:通过 Kafka 表引擎、Buffer、异步插入与批量攒批,实现高吞吐低延迟入库。
三、核心方法流程:从数据源到实时聚合
本课程将行情链路拆解为“采集—缓冲—建模—入库—聚合—服务”六个阶段,每一阶段都有明确的工程取舍。
- 采集:从交易所网关、行情源或文件回放获取原始报文,解析为结构化字段。
- 缓冲:使用 Kafka/Pulsar 削峰填谷,保证上游抖动不影响数据库稳定性。
- 建模:确定表引擎、分区键、排序键、字段类型与编码,决定后续查询性能上限。
- 入库:批量写入、异步插入、幂等去重,控制 part 数量与合并压力。
- 聚合:用物化视图或 AggregatingMergeTree 预计算 K 线、盘口统计与指标。
- 服务:面向查询 API、监控看板与策略回测提供稳定低延迟读取。
下面是一段典型的建表与写入示例,体现行情快照表的基本建模思路:
CREATE TABLE market.snapshot
(
exchange LowCardinality(String),
symbol LowCardinality(String),
ts DateTime64(3, 'Asia/Shanghai'),
last_price Decimal64(4),
volume UInt64,
bid1 Decimal64(4),
ask1 Decimal64(4)
)
ENGINE = ReplacingMergeTree
PARTITION BY toYYYYMMDD(ts)
ORDER BY (exchange, symbol, ts)
TTL ts + INTERVAL 90 DAY;
INSERT INTO market.snapshot
SELECT * FROM market.snapshot_kafka;
该示例中,PARTITION BY toYYYYMMDD(ts) 控制分区粒度,ORDER BY (exchange, symbol, ts) 支撑按标的与时间的高效扫描,ReplacingMergeTree 用于处理重复快照,TTL 控制冷数据生命周期。
四、案例场景:一个实时行情聚合看板
假设我们需要为多交易所、多品种构建一个实时行情看板,展示最新价、涨跌幅、分钟 K 线与成交量排行。数据流如下:行情网关 → Kafka → ClickHouse Kafka 引擎表 → 物化视图 → 聚合结果表 → 查询 API。写入侧按秒级批量落盘,聚合侧用 AggregatingMergeTree 维护分钟级 OHLC 与成交量,查询侧直接读取预聚合结果,避免每次扫描原始逐笔。
| 阶段 | 关键对象 | 典型参数/策略 | 目标 |
|---|---|---|---|
| 采集 | 行情网关、解析器 | 多源合并、字段标准化 | 结构化、低延迟 |
| 缓冲 | Kafka Topic | 分区数、副本数、保留时长 | 削峰、可回放 |
| 建模 | MergeTree 表 | 分区键、排序键、编码 | 查询性能上限 |
| 入库 | Kafka 引擎、异步插入 | 批量大小、并发度 | 高吞吐、低 part |
| 聚合 | 物化视图、AggregatingMergeTree | 聚合粒度、TTL | 实时指标 |
| 服务 | 查询 API、看板 | 缓存、限流 | 稳定低延迟 |
五、常见误区与复盘
- 误区一:单行插入。ClickHouse 每次插入都会生成 part,高频单行写入会拖垮合并线程,必须批量攒批。
- 误区二:滥用 Nullable。Nullable 列带来额外存储与判断开销,行情字段应尽量用默认值或枚举替代。
- 误区三:忽视乱序。多源合并与重连会产生乱序,需在排序键与去重策略中显式处理。
- 误区四:把 ClickHouse 当 KV 用。高频点查应通过物化视图、Redis 缓存或外部索引解决。
本课程的学习目标可以归纳为三点:第一,掌握行情数据的建模方法,能独立设计快照表、逐笔表与聚合表;第二,掌握高吞吐入库链路,能配置 Kafka 引擎、异步插入与幂等去重;第三,掌握实时聚合与查询优化,能用物化视图与 AggregatingMergeTree 支撑生产级看板与策略服务。整体课程将按“场景认知—建模—入库—聚合—优化—实战”的主线推进,每一章都配有可运行的 SQL 与配置示例。
当你完成本章学习,应当能够清晰描述行情数据从产生到消费的完整链路,理解 ClickHouse 在该链路中承担的角色,并知道后续每一章要解决的具体问题。接下来,我们将从行情数据的字段体系与查询模式出发,进入建模的第一站。