ClickHouseNotes

第 31 章:面试题精讲

zjc 于 2026-01-31 发布

这是《ClickHouse 零基础实战指南》的独立章节版。本章从概念、实操和生产排查三个视角展开,代码块保留了原书可直接运行的版本。 本章整理高频面试问题,并给出能体现工程判断的回答思路。

31.1 ClickHouse 为什么快?

回答要点:

  1. 列式存储,只读需要的列;
  2. 高压缩率,减少 IO;
  3. 稀疏索引和分区剪枝;
  4. 向量化执行和 SIMD;
  5. MergeTree 批量追加;
  6. 分布式并行扫描;
  7. 预聚合、投影和字典优化。

加分项:说明自己会看 read_rowsread_bytesmemory_usageProfileEvents 来验证。

31.2 MergeTree 的 part 是什么?

INSERT 生成 part
part 内按 ORDER BY 排序
后台 merge 合并同分区 part
inactive part 延迟清理

面试重点:解释小写入导致 Too many parts,以及 part 数量、合并和查询性能的关系。

31.3 分区和排序键的区别?

分区负责生命周期和粗粒度剪枝;排序键决定 part 内物理顺序和稀疏索引。常见错误是把分区当索引,或者按小时分区导致 part 爆炸。

31.4 ReplacingMergeTree 是否保证唯一?

不能保证查询瞬间唯一。它只在后台合并时按排序键替换,查询侧应使用 argMax(value, version) 或受限 FINAL。分布式场景还要保证同一业务键路由到同一分片。

31.5 FINAL 为什么慢?

FINAL 会在查询时应用合并语义,可能需要读取和处理多个 part、比较版本、临时物化结果。大范围 FINAL 会放大 CPU、内存和 IO。应先过滤分区和键范围,或预物化最新状态。

31.6 SummingMergeTree 查询是否还要 sum?

要。合并可能尚未完成,或仍有多个大 part。SummingMergeTree 是减少物理行数的手段,不是查询层免聚合的保证。

31.7 UV 为什么不能直接相加?

UV 是去重指标,跨批次、跨城市、跨日期相加会重复计数。可选方案:

  1. 保留明细;
  2. uniqState / uniqMerge
  3. 近似 uniq;
  4. bitmap 或 HLL;
  5. 按业务定义接受误差。

31.8 物化视图什么时候触发?

源表有新数据块写入时触发,对每个 insert block 执行 SELECT 并写入目标表。历史数据不会自动回填,删除源数据也不会自动删除目标数据。

31.9 Projection 和物化视图怎么选?

Projection 属于表内数据,可改变排序或固定聚合,由优化器选择,适合简单模式。物化视图是独立对象,写入目标表,适合复杂转换、多目标分发和更灵活的 SQL。

31.10 副本和分片的区别?

副本存储同一份数据,提高可用性和读吞吐;分片存储不同数据,提高写容量和存储规模。常见组合是每个分片两副本。

31.11 Keeper 的作用是什么?

保存副本日志、块信息、leader 选举和分布式 DDL 队列等协调元数据。它不是业务数据存储;多数派不可用时副本写入和集群 DDL 会受影响。

31.12 分片键如何设计?

考虑数据均衡、查询局部性和业务语义。常用实体 ID hash,如 cityHash64(user_id);状态表必须保证业务键稳定路由。时间做分片容易热点,时间通常交给分区。

31.13 如何优化慢查询?

标准回答:

看 query_log
确认 read_rows / read_bytes / memory
检查分区条件
检查排序键前缀
减少列和结果集
优化 GROUP BY / JOIN
考虑预聚合、投影、字典
设置资源限制
并发压测

31.14 Too many parts 怎么处理?

短期限流写入、降低补数并发、处理磁盘瓶颈;长期改成大批量写入、减少分区数、优化表结构或扩容。不要依赖频繁 OPTIMIZE。

31.15 为什么 ClickHouse 不适合 OLTP?

它没有传统事务、行级锁和高频随机更新的执行模型。设计目标是批量追加和大扫描分析。强事务、点查、高频更新场景应选择 OLTP 数据库。

31.16 如何保证数据不丢?

分层回答:

  1. Kafka 保留和重放;
  2. 写入端重试与死信;
  3. 目标表幂等;
  4. 副本避免单点;
  5. 备份处理误删和集群级故障;
  6. 监控 lag 和对账。

31.17 Kafka lag 增长怎么办?

排查顺序:

  1. 生产端是否暴增;
  2. 消费者是否停止;
  3. 分区是否均衡;
  4. 消息是否有坏格式;
  5. ClickHouse 是否写入失败;
  6. 磁盘或合并是否到瓶颈;
  7. 是否需要扩分区和消费者。

31.18 如何设计实时报表?

说明分层:DWD 明细、DWS 汇总、ADS 报表;明确事件时间、去重口径、迟到数据、幂等、对账和降级。不要只讲建表 SQL。

31.19 系统设计题:亿级事件日增

回答框架:

容量估算
分片副本规划
表引擎和排序
写入微批
Kafka 消费
预聚合
查询限流
监控告警
备份恢复
扩容方案

31.20 高频反模式

  1. 高频小 INSERT;
  2. 按小时或用户分区;
  3. 滥用 FINAL;
  4. UV 直接相加;
  5. 大表在线 JOIN;
  6. 没有分页限制;
  7. 无资源配额;
  8. 只有副本没有备份;
  9. 不做对账;
  10. 忽略版本差异。

本章小结

面试中展示判断力比背概念更重要:先讲模型和边界,再讲实现和验证方式。ClickHouse 的高频考点集中在 MergeTree、合并语义、分区排序、分布式架构、实时链路和性能治理。

思考题

  1. 如何向面试官解释 ClickHouse 的性能来源?
  2. ReplacingMergeTree 的一致性边界是什么?
  3. 如何设计一个亿级行为分析平台?
  4. 数据不丢和不重如何同时设计?
  5. 你经历过哪些 ClickHouse 生产反模式?