日志采集架构:Agent、Logstash、Fluentd、Filebeat
日志采集是整个存储链路的“水源”。水源脏了、断了,后面存再多也没用。我见过不少团队上来就搭 Elasticsearch 集群,日志格式、采集方式一概不管,最后排错排到崩溃。嗯,这一章我们就聊聊怎么选采集器,怎么搭架构。
说白了,采集层要解决两件事:一是把日志从千奇百怪的地方捞出来,二是保证不丢、不重、不乱序。市面上主流方案就那么几个——Agent、Logstash、Fluentd、Filebeat。我一个个说。
4.1 采集器的职责与定位
先理清角色。采集器不是存数据的,它是“搬运工”。我的习惯是把采集器分成两类:
- 轻量级转发器:只负责读文件、发数据。典型代表是 Filebeat、Fluent Bit。
- 重量级处理管道:能解析、过滤、转换、路由。典型代表是 Logstash、Fluentd。
为什么区分这个?因为资源消耗差很多。你在每台业务机器上跑 Logstash?JVM 堆 1GB 起,跑 1000 台就是 1TB 内存,老板会找你谈心的。所以我的推荐很明确:采集端用轻量级工具,集中处理用重量级工具。
4.2 四大采集器深度对比
| 特性 | Filebeat | Fluentd | Logstash | 传统 Agent |
|---|---|---|---|---|
| 开发语言 | Go | Ruby + C | Java (JRuby) | 因实现而异 |
| 资源占用 | 极低 (~10MB) | 中等 (~50MB) | 较高 (~256MB+) | 不定(通常较高) |
| 数据可靠性 | 内置背压 + ACK | Buffer 插件保证 | 持久化队列 | 需自行实现 |
| 过滤能力 | 弱(基本字段处理) | 强(插件生态丰富) | 极强(丰富 Filter) | 弱到中 |
| 吞吐性能 | 极高(10万 EPS+) | 高(数万 EPS) | 中(受 JVM GC 影响) | 因实现而异 |
| 典型场景 | 边缘采集、容器环境 | 统一日志平台、Ruby/云原生 | 集中处理、复杂解析 | 遗留系统集成 |
我的建议:生产环境标配是 Filebeat + Logstash。Filebeat 塞到每台服务器上,Logstash 做集中过滤。这套组合我在好几个项目里都用过,上万台机器也没出过问题。
4.3 架构模式:分层与聚合
采集架构不是一条直线。我画个框架图帮你理解典型的架构分层:
你会看到三层结构。边缘层跑 Filebeat,聚合层跑 Logstash,存储层接 Elasticsearch 或 Kafka。每一层只干自己的事,出了问题排查也简单。
我来说说各层的细节。
4.4 边缘采集:Filebeat 实战
Filebeat 是我最常用的边缘采集器。Go 写的,单进程几 MB 内存,CPU 占用基本忽略不计。为什么?因为它内部用了一种叫“harvester”的机制,只读增量内容,不是全量扫文件。
给你看一份我项目里的配置:
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/app/*.log
- /data/logs/*.json
fields:
env: production
service: order-api
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: true
reload.period: 10s
output.logstash:
hosts: ["logstash01:5044", "logstash02:5044"]
loadbalance: true
ssl.enabled: true
ssl.certificate_authorities: ["/etc/filebeat/ca.crt"]
我曾经踩过的坑:Filebeat 默认的 harvester_limit 是 0(无限制)。有一次我们在一个目录下监控了 5000+ 日志文件,Filebeat 直接开了 5000 个文件句柄,系统 ulimit 被捅穿了。后来我强制设置 harvester_limit: 100,配合 close_inactive: 5m,问题才解决。
Filebeat 只有三个核心概念:
- Input:定义读什么、从哪读、怎么读。
- Harvester:负责具体读取每个日志文件的协程。
- Output:数据发往哪里,支持 Logstash、Kafka、ES 等。
对了,Filebeat 还有一个“模块”系统。比如你想采集 Nginx 日志,直接 filebeat modules enable nginx 就自动配置好解析规则。这个特性很适合快速上线。
4.5 集中处理:Logstash 与 Fluentd 对比
到了聚合层,我们需要能“折腾”日志的工具。Logstash 和 Fluentd 是两大主力。我两个都深度用过,说说感受。
Logstash 优势在生态:输入插件 50+,过滤插件 60+,输出插件 70+。你想到的格式它基本都能解析。缺点是吃内存,JVM 的垃圾回收(GC)在大流量下会抖动。
Fluentd 优势在性能:Ruby 写的内核,但底层 C 插件效率很高。内存占用稳定,GC 影响小。插件数量略少,但对于 90% 的场景够用了。
我个人的选择标准:
- 团队熟悉 Java 栈?用 Logstash,排查 JVM 问题有经验。
- 追求极致资源?用 Fluentd,或者 Fluent Bit(轻量版)。
- 需要复杂分析(grok、geoip、kv)?Logstash 更顺手。
一个真实案例:某金融项目要求每秒 5 万条日志实时入库。一开始用单机 Logstash,发现 GC 停顿导致偶发 3-5 秒延迟。后来改成 Logstash + 持久化队列(queue.type: persisted),并把 worker 数调到 CPU 核心数的 2 倍,延迟稳定在 200ms 以内。这个调节参数我做了很多次实验才找到最佳值。
4.6 采集架构的几个关键参数
无论用哪种采集器,下面这几个参数你一定要调:
| 参数 | 推荐值 | 为什么重要 |
|---|---|---|
| harvester_limit | 100 - 200 | 防止文件句柄撑爆 ulimit |
| close_inactive | 5m - 10m | 自动关闭不活跃文件,减少资源 |
| pipeline.workers | CPU 核数 × 2 | Logstash/Fluentd 并行处理调优 |
| queue.type | persisted (生产环境) | 防止进程重启导致数据丢失 |
| flush_interval | 1s - 5s | 批量写入,减少网络 IO 次数 |
| retry_limit | 5 - 10 | 重试策略,避免死循环 |
最后一点,关于数据的可靠性。我的原则是:边缘层尽量不存,聚合层必须排队。Filebeat 可以配置 registrty 文件记录读取偏移,Logstash 用持久化队列。两层保障下来,99.99% 的场景不会丢数据。