你们用 ClickHouse 存什么数据?MergeTree 表引擎为什么适合这个场景?
这个问题我会先说项目结论:MergeTree 将每批写入保存为不可变数据片段,并在后台持续合并;数据按排序键组织,查询可以通过稀疏主键索引跳过大量无关数据。
我会先交代项目背景和选型结论。理解分区、排序键、数据片段与后台合并。MergeTree 将每批写入保存为不可变数据片段,并在后台持续合并;数据按排序键组织,查询可以通过稀疏主键索引跳过大量无关数据。
具体落地时,我会沿着实际调用链来讲。沿着「批量写入数据块 → 排序并生成新 Part → 记录列文件与稀疏索引 → 后台选择 Parts 合并 → 查询按分区和主键裁剪」观察输入、状态与输出,这些阶段都可以从日志、指标或源码里验证。 批量写入数据块 客户端批次先转换为 Block,批次过小会产生大量独立写入事务和元数据。 排序并生成新 Part 每次 INSERT 把数据按 ORDER BY 排序并落成不可变 Part,写入不是原地修改旧文件。 system.parts:Part 数、行数和级别。 src/Storages/MergeTree:写 Part 与后台 merge。 我会先确认请求实际走到了哪条路径,再用运行数据验证,不会只看类名或配置猜测。
参数和容量不能靠默认值,我会结合业务量来定。用每行/千行/万行批次持续写 30 分钟,对比 Part 生成与合并净速率。
效果要用数据证明,线上问题也要能闭环。固定输入和基线 先在没有故障注入的环境执行上述配置,固定数据规模、并发度、运行时版本和预热时间。以「active parts」为主基线,记录值应满足「记录稳态基线」;同时保存 active parts 数、后台 merge 队列,使后续变化能够回到同一时间轴比较。 每条事件单独 INSERT,单分区产生数万小 Part,后台合并追不上,查询需打开大量文件。客户端攒批、Kafka Engine 汇聚并限制分区粒度后,active parts 恢复稳定。 小批写入制造 Part 爆炸:active parts 数:客户端攒批或 asyncinsert。
最后我会主动说明这个方案不适合什么场景。方案:更适合的场景:主要收益:代价与边界。 MergeTree:通用明细事实表:列存、排序与后台合并能力完整:更新删除不是行存式原地操作。 Log 系列表引擎:小型临时数据:结构简单:缺少主键和高级合并能力。 外部表/湖存储:低频历史与跨系统共享:存算分离、成本低:延迟和功能依赖外部格式。 选型至少带上 日增量、分区规模、查询并发、扫描行数和压缩比,并用上面的量化基线验证;未知数据应明确为待测假设。