3. 市场数据特征
在构建 ClickHouse 市场数据监控与容量规划体系之前,必须先回到数据本身。市场数据并不是普通的业务流水,它同时具备高频写入、强时序性、维度丰富、查询模式多样四个叠加特征。这四个特征彼此耦合,决定了表结构、分区键、排序键、物化视图、TTL 以及监控指标的设计方向。如果只按“普通日志表”的思路建表,往往在数据量增长到数十亿行后才会暴露问题,而那时迁移成本已经很高。
一、核心原理:四类特征如何共同作用于存储引擎
高频写入意味着每秒可能有数万到数百万行行情快照、逐笔成交或订单簿变更进入系统。ClickHouse 的 MergeTree 家族采用批量写入 + 后台合并模型,单条 INSERT 会产生大量小 part,因此写入侧必须依赖客户端攒批或 Kafka 引擎表做缓冲。时序性意味着数据天然按时间递增,时间字段应作为分区和排序的第一维度,使范围查询能够快速裁剪 part。维度丰富意味着同一份行情数据可能包含交易所、品种、合约、方向、价格档位、用户类型等数十个低基数或中基数标签,这些标签适合放入排序键前缀或使用 LowCardinality 编码。查询模式则决定了预聚合粒度:监控看板通常查最近 1 分钟到 24 小时的聚合值,而复盘分析可能查某合约某日的逐笔明细。
二、方法流程:从数据特征到监控指标的映射
建议按以下流程把数据特征转化为可落地的设计与监控项:
- 采集写入频率与批量大小:统计峰值 TPS、平均行宽、单批行数,判断是否需要 Kafka 缓冲。
- 确定时间粒度与分区粒度:逐笔数据按天分区,快照数据可按天或按小时分区,避免分区过多。
- 识别维度基数:交易所、品种等低基数列使用 LowCardinality,高基数如订单号不放入排序键。
- 归纳查询模式:区分点查、范围聚合、TopN、明细回放四类,分别设计主键与物化视图。
- 定义监控指标:写入延迟、part 数量、合并队列、查询 P99、磁盘增长速率。
下面是一个典型的行情快照表定义,体现了时间分区、维度排序与编码策略:
CREATE TABLE market.snapshot
(
ts DateTime64(3),
exchange LowCardinality(String),
symbol LowCardinality(String),
last_price Decimal64(4),
bid_price Decimal64(4),
ask_price Decimal64(4),
volume UInt64,
ingest_time DateTime DEFAULT now()
)
ENGINE = MergeTree
PARTITION BY toDate(ts)
ORDER BY (exchange, symbol, ts)
TTL ts + INTERVAL 90 DAY
SETTINGS index_granularity = 8192;
该表按天分区,排序键以交易所和品种为前缀,使单品种时间范围查询能高效定位。TTL 控制冷数据自动清理,避免磁盘无限增长。
三、案例场景:监控需求如何驱动容量规划
假设某平台接入 5 个交易所、2000 个合约,行情快照每秒写入 20 万行,单行约 120 字节。按此估算,日增原始数据约 2TB,压缩后约 300GB。若保留 90 天,热数据约 27TB。此时监控需求至少包括:
| 监控维度 | 指标示例 | 告警阈值参考 | 对应数据特征 |
|---|---|---|---|
| 写入 | INSERT 行数/秒、写入延迟 | 延迟 > 5s | 高频写入 |
| 存储 | 活跃 part 数、磁盘使用率 | part > 3000 | 时序合并 |
| 查询 | P99 查询耗时、扫描行数 | P99 > 2s | 查询模式 |
| 维度 | 各交易所写入量偏差 | 偏差 > 30% | 维度丰富 |
当 part 数持续升高,说明后台合并跟不上写入速度,需要调整 max_insert_block_size 或增加 Kafka 消费批大小。当某交易所写入量骤降,可能是采集链路故障,而非 ClickHouse 本身问题。
四、误区与复盘:常见设计陷阱
误区二:对高基数订单号使用 LowCardinality。LowCardinality 适合低基数,高基数会带来额外字典开销。
误区三:只监控 CPU 和内存,不监控 part 数和合并队列。市场数据场景下,part 膨胀往往先于查询变慢出现。
复盘时应重点回答三个问题:写入峰值是否超过单分区合并能力?查询是否命中排序键前缀?TTL 与分区粒度是否匹配保留周期?只有把数据特征、表设计和监控指标三者对齐,容量规划才有可靠依据。