← 返回博客
2026-08-11 13:00:01

日志系统选型:ELK 还是 Loki?先别急,看看 ClickHouse 怎么截胡的

日志系统选型:ELK 还是 Loki?先别急,看看 ClickHouse 怎么截胡的

场景:一个 200 节点集群的日志之痛

某团队维护的 Kubernetes 集群规模约 200 节点,日增日志量约 1.2TB。最初使用 ELK(Elasticsearch + Logstash + Kibana),但三个月后,ES 集群(3 主 6 数据节点,每节点 32GB 内存)的堆内存长期处于 85% 以上,GC 停顿频繁,查询延迟从 200ms 恶化到 3.5s。更棘手的是,每次扩容 ES 节点都需要重新均衡分片,运维窗口动辄数小时。

这不是虚构场景——该团队在迁移到替代方案前,曾尝试将 ES 的 refresh_interval 从 1s 调到 30s,但代价是日志检索延迟指数级上升,排障时等日志刷新的体验相当煎熬。

方案一:ELK——成熟但重

ELK 的核心优势在于全文检索聚合分析的成熟度。但它的代价是:

关键配置示例(elasticsearch.yml):

indices.memory.index_buffer_size: 10%
indices.queries.cache.size: 5%
thread_pool.write.queue_size: 200

这段配置试图通过限制缓存和队列来缓解内存压力,但实际效果有限——GC 问题依然存在。关键在于:ELK 适合日志量可控、查询模式复杂的场景,但如果日志量超过 TB 级/天,ES 的运维成本会呈非线性增长。

方案二:Loki——轻量但查询受限

Loki 的定位是"日志即标签",它不建全文索引,而是只索引标签(如 Pod 名、命名空间),日志内容以压缩块存储。这带来了显著的成本优势:

但代价是查询能力受限。日志内容检索({namespace="prod"} |= "ERROR")实际是暴力扫描,在 1.2TB/天的日志量下,一个不带标签过滤的全文搜索耗时超过 60s。此外,Loki 的 LogQL 语法远不如 ES 的 Query DSL 灵活,复杂聚合(如按用户 ID 做 1 小时窗口的去重计数)难以实现。

# loki-config.yaml 关键段
schema_config:
  configs:
    - from: 2024-01-01
      store: tsdb
      object_store: s3
      schema: v13
      index:
        prefix: loki_index_
        period: 24h

注意schema: v13 是当前推荐版本,但升级时需确保所有 Loki 实例版本一致,否则会触发索引读写兼容性问题——这是 Loki 社区最常见的踩坑点。

方案三:ClickHouse——被低估的截胡者

ClickHouse 作为列式 OLAP 数据库,处理日志场景有天然优势:

实测数据(来自上述 200 节点集群的迁移测试):同样的 30 天日志查询(按 namespace 聚合,统计错误码分布),ClickHouse 耗时 1.8s,ES 耗时 12.4s,Loki 耗时 28.7s(因需扫描全量块)。

部署配置(docker-compose.yml 片段):

services:
  clickhouse:
    image: clickhouse/clickhouse-server:24.8
    ports:
      - "8123:8123"
      - "9000:9000"
    volumes:
      - ./clickhouse-storage:/var/lib/clickhouse
    ulimits:
      nofile: 262144

日志表结构设计是核心:

CREATE TABLE logs (
  timestamp DateTime64(3),
  level LowCardinality(String),
  namespace String,
  pod_name String,
  message String,
  trace_id UUID
) ENGINE = MergeTree()
PARTITION BY toYYYYMMDD(timestamp)
ORDER BY (namespace, timestamp)
TTL toDateTime(timestamp) + INTERVAL 30 DAY

关键点ORDER BY 决定了查询性能——将 namespace 放在首位,配合 timestamp 做范围扫描,查询效率远高于 ES 的倒排索引。注意LowCardinality 类型用于 level 字段可显著降低存储,但不要滥用,否则会适得其反。

三方案对比总结

维度ELKLokiClickHouse
存储成本高(3-5x 原始)极低(0.5-1x)低(0.8-1.2x)
查询能力强(全文检索)弱(仅标签+扫描)中强(SQL + 聚合)
运维复杂度
适用场景复杂查询、审计轻量排障、成本敏感大规模日志、指标聚合

最终结论:混合架构才是正解

没有银弹。该团队最终采用分层方案:

  1. 实时排障用 Loki(保留 7 天),通过 {namespace="prod"} 快速定位问题
  2. 历史分析与聚合用 ClickHouse(保留 90 天),支撑 BI 报表和容量规划
  3. ELK 彻底下线,释放的 6 个数据节点被重新分配为 ClickHouse 和 Loki 节点

核心收获:日志系统选型应基于查询模式而非日志量。如果 80% 的查询是"按时间范围查某 Pod 的错误日志",Loki 足够;如果涉及多维聚合(如"过去 30 天每个接口的 5xx 分布"),ClickHouse 性价比最高;ELK 仅在需要复杂全文检索(如代码搜索、安全审计)时才值得保留。

下一步行动:建议先用 docker-compose 部署一套 ClickHouse 和 Loki 的 PoC,导入一周的生产日志(脱敏后),用真实查询场景对比性能。测试时注意记录查询延迟分位数磁盘占用两个指标,这比理论对比更有说服力。

本文关键词:ClickHouse、Loki、ELK、日志系统、Kubernetes