日志采集与存储:选对工具,事半功倍

日志采集和存储,是整个日志分析体系的基石。说白了,你后面分析得再花哨,如果源头数据没采好、存得乱,那一切都是白搭。我在这个环节踩过的坑,比后面分析阶段多得多。今天咱们就把这块掰开揉碎了讲清楚。

日志采集工具:三驾马车怎么选?

目前主流的采集工具就三个:Filebeat、Logstash、Fluentd。很多人纠结选哪个,其实没那么复杂。我个人的习惯是:轻量级采集用 Filebeat,复杂处理用 Logstash,云原生场景用 Fluentd。

Filebeat:轻量级选手

Filebeat 是 Elastic 家的轻量采集器。它最大的优点就是轻——资源占用极低,部署简单。你想想看,如果要在几百台服务器上装采集器,Filebeat 几乎是无感的。

核心特点:

  • 基于 Golang 编写,内存占用通常不到 20MB
  • 支持自动多行合并(比如 Java 异常栈)
  • 内置 Elasticsearch 和 Logstash 输出
  • 支持 SSL/TLS 加密传输

我曾经在一个金融项目中,用 Filebeat 采集了 2000+ 台服务器的 Nginx 日志。部署完一看,每台机器 CPU 占用不到 1%。嗯,这就是轻量的好处。

Logstash:重型数据处理引擎

Logstash 是 ELK 栈里的老大哥。它功能强大,但代价就是吃资源。我建议只在需要复杂数据转换的场景下用它。

举个例子,你采集的日志里 IP 地址需要转换成地理位置,或者需要从 JSON 里提取嵌套字段,这时候 Logstash 的 filter 插件就派上用场了:

input {
  beats {
    port => 5044
  }
}

filter {
  geoip {
    source => "client_ip"
    target => "geo"
  }
  mutate {
    rename => { "[geo][location]" => "[geo][coordinates]" }
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "nginx-%{+YYYY.MM.dd}"
  }
}

避坑指南:我曾经在一个日志量日均 50TB 的项目里,直接用 Logstash 做采集。结果呢?集群 CPU 直接飙到 90%,最后不得不改成 Filebeat + Kafka + Logstash 的架构。记住:Logstash 不适合做第一层采集,它更适合做中间处理层。

Fluentd:云原生时代的宠儿

Fluentd 是 CNCF 毕业项目,在 Kubernetes 生态里用得特别多。它的插件生态非常丰富,有 1000+ 个插件。我个人觉得,如果你在用 K8s,Fluentd 几乎是标配。

特性 Filebeat Logstash Fluentd
资源占用 极低 较高 中等
数据处理能力 弱 强 中
插件生态 有限 丰富 非常丰富
K8s 支持 一般 一般 原生支持
学习曲线 低 中 中
典型场景 轻量采集 复杂处理 云原生

日志存储方案:ELK、Loki、ClickHouse 怎么选?

存日志这件事,没有银弹。不同的场景,适合不同的方案。我这些年三个都用过,说说我的真实感受。

ELK:经典组合,功能全面

ELK(Elasticsearch + Logstash + Kibana)是日志领域的黄金标准。它最大的优势是全文搜索能力极强,而且 Kibana 的可视化做得非常好。

适合场景:

  • 需要全文搜索日志内容
  • 需要复杂的聚合分析
  • 团队有 Elasticsearch 运维经验

我的建议:ELK 虽然好用,但别盲目上。我见过太多团队把 ELK 当数据库用,结果集群动不动就挂。记住:ELK 是搜索引擎,不是存储系统。日志保留周期一定要规划好,热数据 7 天,温数据 30 天,冷数据归档到对象存储。

Loki:轻量级日志聚合系统

Loki 是 Grafana 团队推出的,它和 Prometheus 的理念很像——只索引元数据,不索引日志内容。这意味着它比 ELK 省资源得多。

我为什么喜欢 Loki?因为它和 Grafana 无缝集成。你可以在同一个 Dashboard 里看指标和日志,不用来回切换。对于中小团队来说,Loki 的运维成本比 ELK 低太多了。

# Loki 的配置示例
auth_enabled: false

server:
  http_listen_port: 3100

ingester:
  lifecycler:
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1

schema_config:
  configs:
    - from: 2020-10-24
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: index_
        period: 24h

注意:Loki 不适合需要全文搜索的场景。比如你要查某个特定的错误信息,Loki 的查询速度会比 ELK 慢很多。它更适合基于标签的日志检索,比如查某个 Pod、某个服务的所有日志。

ClickHouse:列式存储的异类

ClickHouse 本来是做 OLAP 分析的,但很多人发现它存日志也特别好用。为什么?因为日志数据的特点就是写多读少、按时间范围查询,这正好是 ClickHouse 的强项。

我曾经在一个广告系统里,每天产生 100 亿条点击日志。用 ELK 根本扛不住,后来换成 ClickHouse,查询速度提升了 10 倍以上。

方案 查询速度 存储成本 运维复杂度 全文搜索 典型场景
ELK 快(全文搜索) 高 高 支持 通用日志分析
Loki 中等(标签查询) 低 低 不支持 K8s 日志、指标关联
ClickHouse 极快(聚合查询) 低 中 有限 海量日志、实时分析

日志轮转策略:别让磁盘爆了

日志轮转是个老生常谈的问题,但很多人就是不在意。我见过最夸张的一次,某台服务器因为日志没轮转,直接把 2TB 的磁盘写满了,导致整个业务挂了 3 个小时。

Linux 下最常用的轮转工具是 logrotate。它的配置其实很简单,但有几个关键点要注意:

/var/log/nginx/*.log {
    daily                    # 每天轮转一次
    rotate 30                # 保留 30 天的日志
    compress                 # 压缩旧日志
    delaycompress            # 延迟一天压缩
    missingok                # 日志文件不存在不报错
    notifempty               # 空文件不轮转
    create 0640 nginx adm    # 创建新日志文件的权限
    sharedscripts            # 所有日志轮转后执行一次脚本
    postrotate
        /usr/sbin/nginx -s reopen  # 通知 Nginx 重新打开日志文件
    endscript
}

轮转策略的核心原则:

  1. 按时间轮转:每天或每小时轮转一次,方便按时间范围查询
  2. 按大小轮转:设置最大文件大小,防止单个文件过大
  3. 压缩旧日志:文本日志压缩率很高,通常能压缩到原来的 10%
  4. 设置保留周期:根据磁盘空间和业务需求,确定保留天数

我个人习惯的配置是:每天轮转一次,保留 30 天,超过 30 天的自动删除。如果日志量特别大,可以改成每小时轮转一次,保留 7 天。

小技巧:很多应用在写日志时,会持有文件句柄。如果直接删除日志文件,应用可能不会释放句柄,导致磁盘空间无法回收。所以一定要用 copytruncate 或者通知应用重新打开日志文件的方式。嗯,这个坑我踩过两次才记住。

整体架构图

下面这张图,是我在实际项目中常用的日志采集与存储架构。你可以看到,从日志产生到最终存储,每个环节都有对应的工具和策略。

日志采集与存储架构图 日志采集与存储整体架构 应用服务器日志 Kubernetes Pod 日志 网络设备 Syslog Filebeat(轻量采集) Fluentd(云原生采集) Rsyslog(Syslog采集) Kafka / RabbitMQ(消息队列缓冲) Logstash(数据清洗与转换) Elasticsearch Loki ClickHouse 说明:实际部署时可根据场景跳过某些层。例如小规模可直接 Filebeat → Elasticsearch,大规模建议加入 Kafka 缓冲层

这张图展示的是我比较推荐的通用架构。你想想看,从日志产生到最终存储,中间经过采集、缓冲、处理、存储四个环节。每个环节都有多种选择,关键是根据你的业务场景来取舍。

好了,日志采集与存储这块就聊这么多。记住一句话:没有最好的方案,只有最适合的方案。选工具的时候,多想想你的业务场景、团队能力、运维成本,别盲目跟风。