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 做冷数据存储。这样各司其职,系统才能跑得稳、跑得快。