请描述 ClickHouse 在列存储架构下是如何应对数据压缩和去重这两个问题的?
考察说明
考察对ClickHouse列存储引擎中压缩机制和去重策略的理解。
回答思路
- 【回答框架 1】列存储天然利于压缩:ClickHouse按列存储,同一列的数据类型相同,数值分布往往集中,因此压缩效果好。默认使用LZ4算法,追求高压缩速度;也可配置ZSTD以获取更高压缩比。压缩是逐块进行的,每个数据块独立压缩,便于解压和查询。
- 【回答框架 2】去重并非列存储的内建能力:ClickHouse默认不自动去重,插入时即使重复数据也会被存储。需要在特定MergeTree引擎中显式设置去重机制,常见方案是使用ReplacingMergeTree,在后台合并时按排序键去重,保留每个排序键对应的最新版本(default版本)。
- 【回答框架 3】去重时机是异步的:ReplacingMergeTree只有在后台合并分区时才触发去重,因此查询时可能仍看到重复数据。若需查询时保证唯一结果,需配合使用FINAL关键字或prewhere条件进行手动过滤,或者采用AggregatingMergeTree等引擎在合并时结合聚合函数实现更复杂的去重。
- 【关键点 1】列存储类型一致的数据分布集中,适合块级压缩(LZ4或ZSTD)。
- 【关键点 2】ClickHouse默认不去重,需使用ReplacingMergeTree等引擎在后台合并时去重。
- 【关键点 3】ReplacingMergeTree去重是异步的,查询时需FINAL关键字或手动过滤。
- 【关键点 4】不同MergeTree引擎提供不同的去重语义,如AggregatingMergeTree可结合聚合函数。
- 【易错点 1】误以为ClickHouse自动去重,实际默认不做。
- 【易错点 2】忽略异步合并延迟,直接读取可能得到重复行。
- 【易错点 3】未考虑排序键对去重结果的影响,导致版本保留不符合预期。