4、日志存储选型:Elasticsearch vs ClickHouse vs Loki

日志存哪?这个问题我几乎每次做风控平台都要纠结一遍。

说实话,没有完美的存储方案。Elasticsearch、ClickHouse、Loki 这三兄弟,各有各的脾气。你选错了,后面查询慢、存储贵,运维想骂人。我经历过,所以今天把底裤都翻出来给你看。

4.1 三款引擎的核心差异

先看一张对比表,心里有个底:

特性 Elasticsearch ClickHouse Loki
数据模型 倒排索引 + JSON 列式存储 日志流 + 标签
写入性能 中等(需调优) 极高(批量写入) 高(追加写入)
全文检索 ★★★★★ ★★☆☆☆ ★★★☆☆
聚合分析 ★★★☆☆ ★★★★★ ★★☆☆☆
存储压缩比 1:3 ~ 1:5 1:5 ~ 1:10 1:8 ~ 1:15
运维复杂度

嗯,这张表你得存着。选型的时候翻出来看一眼,能省不少事。

4.2 Elasticsearch:搜索之王,但别当数仓用

Elasticsearch 最擅长什么?全文检索。风控场景里,你要查某笔交易的原始请求报文,或者搜某个 IP 在过去一周的所有行为,ES 就是首选。

但有个坑——ES 不适合做大规模聚合分析。比如你要统计「每个商户今天触发了多少次规则 A」,用 ES 的 Terms Aggregation 跑一次,节点 CPU 直接飙到 90%。

⚠️ 我曾经踩过的坑:

有一次线上 ES 集群,每天写入 2TB 日志。查询一个简单的 count 聚合,响应时间从 200ms 慢慢涨到 8 秒。最后发现是分片数设少了,数据倾斜严重。重新建索引,折腾了一整晚。

所以我的建议是:ES 只存「需要被搜索」的日志,别把全量数据往里塞。

存储成本方面,ES 默认的 _source 字段会存原始 JSON,膨胀率很高。我一般会做两件事:

  • 关闭不需要的字段的 _source 存储
  • 用 best_compression 压缩

这样能省 40% 左右的磁盘空间。

4.3 ClickHouse:分析利器,写入快到离谱

ClickHouse 是我个人最偏爱的日志存储引擎。为什么?因为它写入快、查询更快。

风控平台每天少说几十亿条日志,ClickHouse 的列式存储和向量化执行引擎,做聚合分析简直是降维打击。

举个例子,你要查「过去 1 小时,每个风控规则的触发次数、平均耗时、最大耗时」:

SELECT
    rule_id,
    count() AS trigger_count,
    avg(process_time_ms) AS avg_time,
    max(process_time_ms) AS max_time
FROM risk_logs
WHERE event_time > now() - INTERVAL 1 HOUR
GROUP BY rule_id
ORDER BY trigger_count DESC
LIMIT 20

这个查询在 ClickHouse 里,几百毫秒就出结果。换 ES 试试?同样的数据量,没个 5 秒下不来。

但 ClickHouse 也有短板——全文检索能力弱。你想搜一条包含特定关键词的日志,得用 LIKE 或者 tokenbf_v1 索引,性能远不如 ES。

💡 我的实战经验:

我习惯把 ClickHouse 作为「分析层」,ES 作为「搜索层」。简单说:

  • 需要聚合统计的 → 走 ClickHouse
  • 需要全文检索的 → 走 ES

两套引擎各司其职,互不干扰。

4.4 Loki:轻量级选手,适合 Kubernetes 环境

Loki 是 Grafana 家的产品。它的设计理念很特别——不建立全文索引,只索引标签

这意味着什么?写入速度极快,存储成本极低。Loki 的压缩比能做到 1:10 以上,比 ES 省 3 倍以上的磁盘空间。

但代价是查询能力受限。你不能像 ES 那样搜「包含某个关键词的所有日志」,只能通过标签(如 pod_name、namespace)来过滤。

说实话,Loki 更适合运维日志、容器日志这种场景。风控平台的业务日志,查询需求复杂,Loki 不太够用。

📌 我的建议:

如果你的风控平台跑在 K8s 上,可以用 Loki 存「系统日志」和「容器日志」,配合 Grafana 做监控告警。但「业务日志」和「风控事件日志」,还是老老实实用 ES 或 ClickHouse。

4.5 存储成本与查询性能的权衡

说白了,这就是个 trade-off。你要快,就得花钱;你要省钱,就得忍受慢。

我一般会从三个维度来评估:

  1. 查询频率:热数据(最近 7 天)需要毫秒级响应,冷数据(30 天以上)可以接受秒级
  2. 查询类型:是全文检索多,还是聚合分析多?
  3. 数据量:每天多少条?每条多大?

举个例子,我之前的项目每天产生 50 亿条风控日志。如果全量存 ES,光磁盘成本一个月就要 20 万。后来我们做了分层:

  • 热数据(7 天):ES,SSD 存储,3 副本
  • 温数据(7-30 天):ClickHouse,HDD 存储,2 副本
  • 冷数据(30 天以上):压缩后存对象存储(S3/MinIO)

成本直接降了 60%。

4.6 冷热数据分离策略

冷热分离,是日志存储的必修课。不做冷热分离,你的存储成本会像滚雪球一样越滚越大。

我常用的策略有三种:

策略 实现方式 适用场景
基于时间分区 按天/周建表,定期删除旧分区 ClickHouse、ES(ILM)
基于存储介质 热数据 SSD,冷数据 HDD ES(冷热节点)
基于压缩归档 冷数据压缩后存对象存储 所有引擎

以 ClickHouse 为例,我一般这样设计:

-- 热数据表(7 天)
CREATE TABLE risk_logs_hot (
    event_time DateTime,
    rule_id String,
    ...
) ENGINE = MergeTree()
PARTITION BY toYYYYMMDD(event_time)
ORDER BY (event_time, rule_id)
TTL event_time + INTERVAL 7 DAY TO VOLUME 'cold'
SETTINGS storage_policy = 'hot_cold_policy';

-- 冷数据表(30 天)
CREATE TABLE risk_logs_cold (
    event_time DateTime,
    rule_id String,
    ...
) ENGINE = MergeTree()
PARTITION BY toYYYYMMDD(event_time)
ORDER BY (event_time, rule_id)
TTL event_time + INTERVAL 30 DAY TO DELETE;

嗯,这里要注意:TTL 删除不是实时的,ClickHouse 默认每天合并一次分区时才会清理。如果你需要精确控制,可以手动执行 ALTER TABLE ... DROP PARTITION

💡 一个小技巧:

冷数据压缩后,查询性能会下降 3-5 倍。但风控平台的「历史回溯」场景,用户通常能接受 10 秒以内的响应。所以冷数据用 HDD + 高压缩比,性价比最高。

4.7 一张图看懂选型逻辑

说了这么多,我画了张流程图,帮你快速决策:

日志存储选型决策流程 日志存储选型 需要全文检索? Elasticsearch 需要聚合分析? ClickHouse Loki 注:实际选型还需考虑数据量、运维能力、成本预算等因素

这张图的核心逻辑很简单:先问自己「要不要搜内容」,再问「要不要做统计」。两个问题问完,答案基本就出来了。

4.8 我的最终建议

如果你还在纠结,我给你一个「无脑方案」:

  • 中小规模(每天 < 1 亿条):只用 ES,配合 ILM 做冷热分离
  • 大规模(每天 > 1 亿条):ES + ClickHouse 双引擎,ES 管搜索,CK 管分析
  • K8s 环境:Loki 存系统日志,ES/CK 存业务日志

记住,没有银弹。选型不是选「最好的」,而是选「最适合你当前场景的」。

好了,这一章就聊到这。下一章我们聊聊日志采集的架构设计——怎么把几十亿条日志从业务系统里捞出来,还不影响线上性能。


公众号:蓝海资料掘金营,微信deep3321