几十台机器日志集中收集,最直接的做法是采用轻量级采集端加统一消息队列再加存储检索端的组合架构,也就是下沉采集、汇聚传输、集中存储这三层模型,用Filebeat采集、Kafka缓冲、Elasticsearch存储加Kibana展示是当前最稳妥的默认答案。
这套组合能解决权限分散、采集端资源占用高、日志格式不统一、检索速度慢这几个核心痛点,下面的内容围绕具体怎么落地来展开,从架构选型到实际部署都按真实运维场景来写。
几十台服务器日志收集架构选型:采集端和传输层的取舍
日志集中收集方案怎么搭,先要看采集端,每台机器上部署一个agent,它负责读文件、解析、转发。采集端选择的核心标准是资源占用低、断点续传稳定、配置热更新方便。
对比Filebeat、Fluentd、Logstash的适用边界
- Filebeat:Go语言写的,内存占用通常稳定在30-50MB左右,CPU在低负载情况下几乎可以忽略不计,使用harvester逐行读取文件,自带backpressure机制,当输出端阻塞时会放慢读取速度,不会丢数据,它最适合作为纯采集器,不做复杂处理。
- Fluentd:Ruby生态,插件丰富,输入输出插件数量较多,内置的buffer机制对数据可靠性有保障,但内存占用相对Filebeat来说普遍高出不少,需要调优buffer chunk大小,更适合日志内容需要做复杂解析和转换的场景。
- Logstash:功能最强大,能做过滤、改写、富化,使用Ruby语法写配置,但JVM的底层决定了它天生吃内存,默认堆设置通常在1-4GB,放在生产机器上会显得比较重。
行业共识认为,采集端和业务应用同机部署时,资源隔离的重要性高于功能的丰富程度,因此在几十台机器这个规模上,Filebeat是采集端的优先选择。
消息队列是必须的吗?分规模和可靠性两个维度看
日志集中收集架构中,是否引入Kafka要看下游消费能力和数据可靠性要求,几十台机器的规模,每天日志量通常在几十GB到几百GB,这种情况下:
- 不引入队列直接打到ES:部署最简单,如果ES集群写入性能足够,确实能跑,但ES写入出现抖动或进行集群重启、滚动升级时,采集端数据会积压,Filebeat会阻塞读取,最终可能导致日志文件在磁盘上堆积。
- 引入Kafka作为缓冲层:采集端只负责把日志写进Kafka,ES从Kafka消费数据,两者完全解耦,ES挂了不丢数据,Kafka的多副本机制还能保证broker挂掉一台数据不丢。
对于精细化运维来说,在几十台机器这个规模,引入Kafka作为缓冲层是值得推荐的,因为后期扩展集群规模时,架构不需要改动。
日志集中收集系统搭建步骤:从零到一的具体操作路径
明确了选型,下一步是动手搭建,以下部署路径基于Filebeat、Kafka、ELK这套组合,如果你在考虑日志收集系统怎么搭,可以按这个顺序操作。

第一步:规划目录结构和命名规范
机器多,命名不规范会头疼,给日志文件起名建议遵循以下约定:
- 日志路径统一为:
/data/logs/{应用名}/{服务名}.log - 日志格式统一为:
{时间戳} {级别} {线程名} {类名} {消息内容} - 应用名称和服务名称全部使用小写字母加连字符,
user-service,order-center
部署前先把规范定好,比后面写一堆正则去适配不规则的日志格式要省事得多。
第二步:部署Filebeat采集端
在每台机器上安装Filebeat,几行nginx配置就能跑一个轻量级的负载均衡:
# filebeat.yml 配置要点
filebeat.inputs:
- type: filestream
enabled: true
paths:
- /data/logs//.log
parsers:
- ndjson: ~
output.kafka:
hosts: ["kafka1:9092", "kafka2:9092", "kafka3:9092"]
topic: "app-logs"
partition.hash:
reachable_only: true
required_acks: 1
注意这里用的filestream类型是Filebeat新版本推荐的,相比旧的log类型,管理状态文件的方式更稳定,重命名文件或者日志轮转时不容易丢数据。
第三步:部署Kafka缓冲层
Kafka的部署参数,分区数建议与ES索引分片数保持一致,主题根据日志类型拆分,比如访问日志单独一个topic,业务日志单独一个topic。
kafka-topics.sh --create --topic app-logs --partitions 12 --replication-factor 2 --bootstrap-server kafka1:9092
分区数12是因为ES索引分片数通常也设12,这样可以均匀分布到3个ES节点上。
第四步:部署Logstash消费端
Logstash从Kafka拉取数据,进行字段拆分、类型转换、索引名路由,然后写入ES,这个日志收集方案的流程中,只有Logstash是有状态的节点,需要关注其的堆内存配置和消费组分配。
input {
kafka {
bootstrap_servers => "kafka1:9092,kafka2:9092"
topics_pattern => "app-logs"
group_id => "logstash-es"
codec => "json"
consumer_threads => 4
}
}
output {
elasticsearch {
hosts => ["es1:9200", "es2:9200", "es3:9200"]
index => "app-logs-%{+yyyy.MM.dd}"
}
}
第五步:ES冷热分离和索引生命周期
ES部署完,需要配置索引生命周期管理(ILM),将索引按照时间进行热温冷阶段转换:热阶段存放最近3天数据,使用SSD磁盘;温阶段存放最近15天数据,使用普通SATA盘;冷阶段存放超过15天的数据,只保留副本在更廉价的存储上,这种分层方案能有效控制成本。

索引分片建议单分片大小控制在30-50GB,通过index.routing.allocation配置强制将冷热索引分布到不同节点。
日志集中收集常见故障:采集端到ES链路中的坑
方案搭好只是开始,运行中会遇到各种问题,下面这些场景是多机日志收集架构中比较常见的。
Filebeat不读文件或重复读文件
Filebeat有个registry文件,记录每个文件采集到的offset,如果这个文件损坏,会出现重复采集或者不采集,处理方式:
# 停掉filebeat systemctl stop filebeat # 备份并删除registry mv /var/lib/filebeat/registry /var/lib/filebeat/registry.bak # 重新启动 systemctl start filebeat
这种情况会丢失原registry中记录的offset状态,相当于重新从头读一遍文件,如果需要断点续传,需要设置clean_removed: false来保留历史状态。
Kafka消费者组积压量持续上涨
在监控Kafka消费延迟时,Lag值持续上涨说明消费能力跟不上生产速度,排查思路:
- 看Logstash的堆内存是否频繁触发GC,Heap使用率超过75%时需要调大
-Xmx - 看ES节点的bulk拒绝率,如果
thread_pool.bulk.rejected数量增加,说明ES写入已经到瓶颈 - 检查是否有超大日志行(几百KB甚至几MB),这会导致ES分词和索引过程卡顿
采集端和ES之间的通讯需要认证和加密吗
企业内部网络情况下,很多公司选择明文传输,但安全要求较高的团队会启用TLS加密,Filebeat到Logstash之间可以通过output.logstash.ssl配置启用TLS双向认证,对采集性能的影响约3%-5%,多数情况下这个成本是值得承担的。
日志集中收集方案的成本控制:数据量大了怎么省钱
几十台机器日志集中收集是一个持续投入资源的组件,初期建设成本和后期维护成本都需要考虑进去。
ES资源消耗的构成和分析
ES最吃存储,因为默认会把原始日志内容_source完整存储,加上所有字段的倒排索引,存储放大效应通常在1.5-2.5倍,例如每天产生100GB原始日志,ES实际占用磁盘可能达到200GB左右,在容量规划时需要将这些因素考虑进去。
优化方案是使用best_compression压缩_source,并将不需要检索的字段通过index: false去掉索引。
分析型索引与检索型索引的分层存储
日志数据可以按价值分层:
- 访问日志和系统日志:只保留30天,不设置分片副本
- 业务日志:保留90天,单副本
- 审计日志:保留一年以上,冷存储
这种分层方案能让存储成本降低不少。
是否需要考虑国内服务器日志收集的特殊环境
如果机器部署在国内的云服务器上,需要考虑网络带宽和跨地域传输的问题,跨可用区传输日志会产生较高的流量费用,建议在同一地域内部署日志收集系统的Kafka和ES集群,如果存在跨地域传输的场景,需要在采集端配置压缩传输(Filebeat支持

compression_level参数,推荐设为5),减少公网流量消耗。
日志集中收集方案对比:自建ELK与云托管服务的取舍
很多团队面临一个现实选择:是自建日志收集架构,还是直接用云厂商的日志服务,这里有一个对比表格:
| 维度 | 自建ELK+Filebeat+Kafka | 云托管日志服务 |
|---|---|---|
| 初始投入 | 需要4-6台机器做ES集群,加上Kafka节点 | 按量付费,无初始硬件投入 |
| 运维成本 | 需要管理ES索引生命周期、集群节点扩缩容 | 云厂商负责基础设施 |
| 数据安全 | 数据完全可控 | 需要信任云厂商 |
| 查询能力 | 基于ES的DSL查询,灵活自由 | 使用厂商提供类SQL语法,有一定限制 |
| 长期成本 | 固定机器成本和人力成本 | 数据量越大单价越高 |
结论是:如果团队已有运维人力且机器数据量大(每天超过500GB),自建的成本优势明显,如果数据量较小或没有专职运维,云托管服务更省心。
最后收束一下:日志集中收集的核心在于解耦和规范,用Filebeat解决采集,Kafka解决缓冲,ES解决检索,三者的组合能应对多数日志收集架构的挑战,先把简单的方案跑起来,再根据实际情况按需演进,自然能形成最适合自己团队的技术栈。
关于几十台机器日志集中收集的常见问题
Q:几十台机器日志集中收集需要上Kafka吗?
A:如果日志量每天不超过100GB,且ES集群节点数不低于3个,可以不用Kafka,如果未来有扩容计划,或者ES集群需要重启升级时业务日志不能中断,则建议一开始就引入Kafka,避免后期改造采集端配置的麻烦。
Q:日志收集方案中Filebeat和Logstash可以合并吗?
A:可以,用Logstash直接采集文件日志,但Logstash的JVM内存开销较高,在业务机器上部署一个独立的Logstash进程通常不太划算,如果要精简链路,用Logstash替代Filebeat采集端,建议将Logstash部署在独立机器上,而不是业务所在机器上。
Q:日志集中收集后如何做告警?
A:ElastAlert或Kibana自带的elastalert功能能实现ES数据查询触发告警,配置一个简单的规则,例如5分钟内ERROR级别日志数量超过阈值就发送webhook通知到飞书或钉钉,更轻量的方案是在Filebeat采集端做简单的关键词过滤并直接输出到告警webhook,但这种方式只能匹配关键词,不能做聚合统计,适合简单的关键词场景。