聊聊 ClickHouse 在日志分析场景的实际表现
David Ng | 2026-09-09T14:08:00 | Database
把日志分析从 Elasticsearch 迁移到了 ClickHouse,查询速度快了 5 倍,存储成本降了 70%。分享一下迁移过程和调优经验。
我们的日志分析之前用的 Elasticsearch,随着日志量增长到每天 50GB,ES 集群越来越吃力。查询个 7 天的日志经常要 30 秒以上,磁盘也撑不住了。后来迁移到了 ClickHouse,效果出乎意料地好。 ## 为什么离开 Elasticsearch - **查询慢**:聚合查询(GROUP BY、COUNT DISTINCT)在大数据量下很慢 - **资源消耗大**:3 个节点 16C64G 才能勉强撑住,内存占用特别高 - **存储膨胀**:ES 的倒排索引占用大量磁盘,50GB 原始日志存进去要 150GB+ ## ClickHouse 的优势 ### 查询速度 同样的聚合查询: - ES: 28 秒 - ClickHouse: 1.8 秒 ClickHouse 是列式存储,聚合操作只需要读取相关的列,不像 ES 要扫描整个文档。 ### 存储压缩 ClickHouse 的压缩率非常惊人: - 原始日志:50GB/天 - ES 存储:~150GB/天 - ClickHouse 存储:~12GB/天 LZ4 压缩 + 列式存储的同类数据聚在一起,压缩率可以达到 10:1 以上。 ### 资源消耗 单节点 8C32G 就能处理我们的日志量,以前 ES 需要 3 个 16C64G 节点。 ## 建表设计 ```sql CREATE TABLE logs ( timestamp DateTime, service String, level Enum8('DEBUG'=0, 'INFO'=1, 'WARN'=2, 'ERROR'=3), trace_id String, message String, extra String -- JSON 格式的额外字段 ) ENGINE = MergeTree() PARTITION BY toYYYYMMDD(timestamp) ORDER BY (service, level, timestamp) TTL timestamp + INTERVAL 30 DAY DELETE; ``` 几个关键点: - 按天分区,方便按时间范围查询和自动清理 - ORDER BY 的列选择很重要,要根据最常用的查询条件来定 - TTL 自动删除 30 天前的数据,不用手动清理 - `level` 用 Enum 而不是 String,节省存储 ## 不适合的场景 ClickHouse 不擅长全文搜索。如果你的日志查询主要是关键词搜索(grep 风格),ES 还是更合适。我们的解决方案是:ClickHouse 做聚合分析,ES 保留最近 3 天的数据做全文搜索。 ## 总结 日志分析这种写多读少、聚合查询多的场景,ClickHouse 比 ES 更合适。如果你的 ES 集群在日志场景下越来越吃力,可以认真考虑迁移。