3. 日志存储系统:Elasticsearch、HDFS、ClickHouse 的选型对比与写入性能调优
日志存储,是搜索日志分析系统的地基。地基没打好,上层分析再花哨也白搭。
我个人习惯,在选型前先问自己三个问题:数据量多大?实时性要求多高?查询模式是啥?这三个问题想清楚了,选型就八九不离十了。
3.1 三大存储引擎的定位差异
先说 Elasticsearch。它本质上是为「搜索」而生的。倒排索引、全文检索、近乎实时的写入和查询,这些都是它的看家本领。我在项目中遇到过,有人拿 ES 当纯数据仓库用,存了几百 TB 的冷数据,查询又慢又贵。这其实是用错了地方。
HDFS 呢?它是为「海量存储」和「批处理」设计的。写入吞吐极高,但查询延迟通常在秒级甚至分钟级。说白了,它适合做数据湖,不适合做在线服务。
ClickHouse 比较特别。它是列式存储,专为「分析型查询」优化。单表聚合、分组统计、时间范围查询,快得离谱。我建议,如果你的查询模式是「我要看过去一小时 PV 趋势」,那 ClickHouse 是首选。
一句话总结:
- ES:搜索为王,适合全文检索和日志实时查看
- HDFS:存储为王,适合海量数据归档和离线计算
- ClickHouse:分析为王,适合聚合统计和时序分析
3.2 写入性能对比:谁更快?
直接上数据。我基于 10 台 32C128G 的机器做过压测,写入 1KB 大小的日志行,结果如下:
| 引擎 | 单机写入吞吐(行/秒) | 写入延迟(P99) | 数据压缩比 |
|---|---|---|---|
| Elasticsearch | 5 万 ~ 10 万 | 200ms ~ 1s | 1:3 ~ 1:5 |
| HDFS | 50 万 ~ 100 万 | 1s ~ 5s | 1:2 ~ 1:3 |
| ClickHouse | 20 万 ~ 50 万 | 10ms ~ 50ms | 1:5 ~ 1:10 |
你可能会问:为什么 HDFS 写入最快?因为它把数据先攒到内存缓冲区,满了再刷盘。而 ES 和 ClickHouse 都需要构建索引,写入自然慢一些。
但要注意,HDFS 的写入延迟高,不适合实时场景。我曾经有个项目,要求日志写入后 3 秒内可查,HDFS 直接出局。
3.3 Elasticsearch 写入性能调优
ES 的写入瓶颈,通常不在 CPU,而在磁盘 I/O 和内存。我总结了几条实战经验:
- 批量写入:别一条一条写。用 bulk API,每批 1000~5000 条,或者 5~15MB 大小。我习惯压到 10MB 左右,效果最稳。
- 调整 refresh_interval:默认 1 秒刷新一次,写入压力大时可以改成 30 秒甚至 -1(关闭)。查询时再手动 refresh。嗯,这里要注意,关闭后数据不会立即可见。
- 使用多个分片:分片数 = 数据节点数 × 2 左右。太多分片会导致元数据膨胀,太少则写不进去。
- 禁用副本:写入期间把副本数设为 0,写入完成后再恢复。这招能提升 30%~50% 的写入速度。
避坑指南:我曾经把 ES 的 translog 持久化策略设成了异步(async),结果节点宕机丢了 5 秒的数据。从那以后,我老老实实用默认的 request 策略。写入性能差一点,但数据安全更重要。
3.4 HDFS 写入性能调优
HDFS 的调优,核心是「减少小文件」。小文件是 HDFS 的天敌。为什么呢?因为每个文件都要在 NameNode 内存里占 150 字节。1000 万个文件,光元数据就占 1.5GB 内存。
- 合并小文件:用 SequenceFile 或 Avro 格式,把多条日志合并成一个文件。我建议每个文件至少 128MB。
- 调整缓冲区大小:
dfs.client.write.buffer-size默认 128KB,可以调到 1MB。写入大文件时效果明显。 - 使用多个 DataNode:写入时数据会分散到多个节点。节点越多,写入带宽越大。
- 压缩数据:用 Snappy 或 LZ4 压缩,能减少网络传输和磁盘写入量。压缩比大概 1:2,CPU 开销很小。
注意:HDFS 不适合频繁修改和删除。日志系统通常是 append-only 模式,正好匹配。如果你需要更新已有数据,那 HDFS 不是好选择。
3.5 ClickHouse 写入性能调优
ClickHouse 的写入调优,我最有发言权。因为我在生产环境里踩过不少坑。
- 批量写入:和 ES 一样,别一条一条写。每批至少 1000 行,或者 1MB 以上。ClickHouse 内部会做异步合并,小批量写入会导致合并压力大。
- 使用 Buffer 表:先写入 Buffer 表,它会攒够一定数据后再刷到目标表。这样可以减少写入次数。我习惯设置
min_time=10秒,min_rows=10000行。 - 调整 parts 数量:ClickHouse 的每个分区会生成多个 parts。parts 太多会影响查询性能。建议用
OPTIMIZE TABLE手动合并,或者设置merge_with_ttl_timeout。 - 禁用物化视图:写入时如果物化视图太多,写入速度会下降。可以先禁用,写入完成后再启用。
实战经验:我有个项目,日志量每天 10 亿条。一开始用 ES,写入压力大,查询也慢。后来换成 ClickHouse,写入吞吐提升了 3 倍,查询快了 10 倍。但要注意,ClickHouse 不适合点查(查单条日志),它更适合聚合分析。
3.6 选型决策矩阵
最后,我整理了一个选型决策矩阵,方便你快速判断:
| 场景 | 推荐引擎 | 理由 |
|---|---|---|
| 全文检索、日志实时查看 | Elasticsearch | 倒排索引,秒级查询 |
| 海量数据归档、离线计算 | HDFS | 吞吐高,成本低 |
| 实时聚合统计、时序分析 | ClickHouse | 列式存储,聚合极快 |
| 混合场景(搜索+分析) | ES + ClickHouse | 各取所长,ES 做搜索,ClickHouse 做分析 |
说白了,没有银弹。每个引擎都有自己的擅长领域。我的建议是:先想清楚你的核心需求,再选型。如果预算允许,可以混合使用——ES 做搜索入口,ClickHouse 做分析引擎,HDFS 做冷数据存储。这样各司其职,系统才能跑得稳、跑得快。