采集层设计:日志采集器选型与性能调优
采集层是整个审计分层的入口,说白了就是“怎么把日志‘捞’起来的”一部分。我见过不少团队上来就追求高大上的架构,结果光采集就丢数据、卡瓶颈。嗯,今天我就拿经验聊聊这东西。
日志采集器选型:Filebeat vs. Fluentd
主流的日志采集器无非两个:Filebeat 和 Fluentd。你可能要问:“为什么不是Logstash?”其实Logstash太重了,一般只做服务端处理,采集层我会优先选轻量的选手。
| 对比维度 | Filebeat | Fluentd |
|---|---|---|
| 资源占用 | 极低,Go语言编写,通常 < 30MB内存 | 中低,Ruby + C实现,基础约 50-70MB |
| 性能上限 | 单节点约 10万行/秒(纯转发) | 单节点约 3-5万行/秒(插件较多时) |
| 插件生态 | 有限,主要输出到ES/Logstash/Kafka | 丰富,输入/输出/过滤插件 1000+ |
| 数据处理 | 弱,仅支持简单字段裁剪和多行合并 | 强,支持正则解析、yaml转换、路由 |
| 部署难度 | 简单,二进制直接跑 | 中等,依赖Gem或Docker |
我个人习惯:
- 如果只是简单转发JSON日志,无复杂过滤 → 我选 Filebeat。我之前帮人调一个电商的网关日志,用 Filebeat 配合 Elasticsearch,CPU 常年稳定在 5%。
- 如果还需要做数据清洗、格式转换甚至下发告警 → 我选 Fluentd。它有“input + filter + output”三段管道,几乎每个环节都能插自定义插件。
multiline 配置可以帮你把 Java 堆栈的多行异常合并成一条。我曾经处理过一个微服务 Full GC 日志,就是用 Fluentd 的 multiline_flush 插件避免数据分裂。
数据源接入:Kafka 和 HTTP
有了采集器,日志往哪送?一般两种情况:异步进消息队列,或同步直接把日志发到某个采集端点。
接入 Kafka
这是大型审计系统的标配。Kafka 充当缓冲区,下游消费能力不足时,日志不会丢。
典型配置(Filebeat 输出到 Kafka):
output.kafka:
hosts: ["192.168.1.10:9092", "192.168.1.11:9092"]
topic: "audit-log"
codec.json:
pretty: false
compression: gzip
max_message_bytes: 1048576 # 1MB
我见过有人在生产环境把 max_message_bytes 调得太大,导致 Kafka 内存占用飙升,甚至 OOM。这里我建议:
- 单条日志不超过 1MB(默认就差不多);
- 启用压缩(gzip/zstd),可以节省 60-70% 带宽;
- 分区数最好 3-5 个,不多不少,避免重复消费。
接入 HTTP
如果你没有中间件,或者日志源是一个不支持输出到 Kafka 的遗留系统,那就走 HTTP 接入。
建议用 Fluentd 的 HTTP 输入插件做接收端,再结合限流 @type throttle:
<source>
@type http
port 9880
bind 0.0.0.0
add_http_headers true
<transport tls>
cert_path /etc/td-agent/cert.pem
private_key_path /etc/td-agent/key.pem
</transport>
</source>
<filter audit.**>
@type throttle
threshold 1000
interval 1
</filter>
采集性能优化:不是堆机器就行
优化采集性能,说白了就是要解决三个矛盾:CPU 不够用、IO 跟不上、网络打宽了也没用。
- 调整并发和缓冲区
- Filebeat:
harvester_buffer_size默认 16384,可以适当调到 32768 提升吞吐,但注意内存。 - Fluentd:设置
flush_interval 5s和chunk_limit_size 4m,别让块太小或太大。
- Filebeat:
- 启用磁盘缓冲
这是保命手段。Filebeat 默认自带 registry 文件,记录了每个文件的读取位置,如果宕机重启也不会重复读取全部日志。Fluentd 则需要显式配置
buffer_type file:<buffer> @type file path /var/log/fluentd/buffer/ flush_interval 10s retry_max_times 5 retry_wait 10s </buffer>我曾经遇到流量突增时,Fluentd 的 memory buffer 全丢了。换成 file buffer 后,即使进程崩溃,日志还在磁盘上,重启就能恢复。
- 多级队列:采集端与服务端分离
别把采集器和数据处理混一起。我一般用这种模式:
- 单节点 Filebeat + Kafka:稳定 50000 ~ 80000 行/秒,CPU 15% 以内;
- 单节点 Fluentd + Kafka(带正则解析):约 15000 ~ 30000 行/秒,CPU 30% 左右;
- 如果超过上限,加机器比加配置更经济——反正采集器本身是无状态的。
总结一下:性能问题 80% 是因为“数据积压 + 缓冲区配错”导致的。在项目初期预留磁盘缓冲、控制单条日志大小、选对采集器,就能避开大部分坑。我之前见过有人因为讨厌配置 Fluentd,直接把数据裸写到 ES,结果写入节点压垮,排了一周的错……所以,采集层稳了,后面才稳。