技术探索与实践总结:从一次日志平台升级说起
开篇:技术人的日常就是不断解决问题

大家好,我是某互联网公司的一名后端开发工程师,目前主要负责公司内部日志平台的维护与优化。在我们公司,日志平台是支撑多个业务线的核心系统之一,承担着日志采集、存储、查询、分析等重要职责。随着业务规模的扩张和日志数据量的激增,原有的架构逐渐暴露出性能瓶颈和运维复杂度高的问题。
这篇文章我打算结合最近一次日志平台的升级改造过程,聊聊我们在技术探索与实践中的具体经历。希望通过分享这次实战经验,能给正在面对类似挑战的朋友一些启发,也希望能引发更多关于“如何平衡技术先进性与工程落地性”的思考。
项目背景:为什么要做这次升级?

我们原来的日志平台基于 ELK(Elasticsearch + Logstash + Kibana)搭建,整体运行还算稳定。但随着接入的日志量持续增长(高峰期 QPS 超过 50,000),我们开始遇到几个明显的问题:
- Elasticsearch 集群压力大:索引写入性能下降,查询响应变慢,频繁出现 GC 停顿。
- Logstash 占用资源高:多个 Logstash 实例并行处理日志,CPU 和内存消耗严重。
- 日志丢失风险存在:在网络抖动或下游服务异常时,部分日志会丢失,无法保证可靠性。
- 查询性能瓶颈:用户使用 Kibana 进行聚合查询时响应时间超过预期,影响排查效率。
这些问题最终促使我们启动了日志平台的重构升级计划。
面临的挑战:不只是技术选型
在技术层面,我们需要考虑以下几个关键点:
- 日志采集层:是否继续使用 Logstash?还是引入更轻量级的替代方案?
- 消息队列层:是否需要 Kafka?还是使用 RabbitMQ 或者其他中间件?
- 存储引擎:Elasticsearch 是否仍是最佳选择?有没有更高效的替代方案?
- 高可用与灾备:如何保证整个链路的稳定性?
- 监控与告警体系建设:如何实现对各个组件的实时监控?
更重要的是,我们还需要权衡以下几点:
- 现有系统的兼容性:升级不能影响已有业务。
- 团队的技术栈匹配度:新技术的学习成本和维护成本是否可控?
- 运维复杂度:新方案是否易于部署、监控和扩展?
- 上线节奏:能否支持灰度发布、逐步替换?
解决思路:从架构设计到技术选型
架构分层设计
我们将新的日志平台重新划分为以下几个层次:
日志来源 -> 日志采集(Agent)-> 消息队列 -> 数据处理 -> 存储 -> 查询/分析
每一层都明确了其职责,并尽量解耦,提高可扩展性和容错能力。
关键技术选型对比
| 组件 | 备选方案A | 备选方案B | 最终选择 |
|---|---|---|---|
| 采集器 | Logstash | Fluentd / Filebeat | Filebeat |
| 消息队列 | Kafka | Pulsar | Kafka |
| 数据处理 | Spark Streaming | Flink | Flink |
| 存储 | Elasticsearch | Loki | Elasticsearch |
| 查询 | Kibana | Grafana + Loki DS | Kibana + 自研查询接口 |
采集层:从 Logstash 到 Filebeat
虽然 Logstash 功能丰富,但我们发现其占用资源偏高,且插件机制有时不够灵活。于是我们转向使用 Filebeat,它轻量级、低资源消耗,且支持多种日志源配置方式。
Filebeat 的一个关键优势是 Tail-based 日志收集策略,可以自动识别新生成的日志文件,并支持多行日志合并,非常适合我们的场景。
数据传输层:Kafka vs Pulsar
我们曾一度考虑尝试 Apache Pulsar,因为它具备更强的多租户和延迟消息能力。但从运维角度出发,Pulsar 相对较新,社区活跃度虽高但文档和成熟案例略逊于 Kafka。
最终我们选择了 Kafka,因为:
- 我们有成熟的 Kafka 运维经验;
- 支持横向扩展且写入性能强;
- 社区活跃,资料丰富,学习成本低;
- 消费者生态完善,与后续处理层对接顺畅。
数据处理层:Flink 替代 Spark Streaming
Spark Streaming 是微批处理模型,延迟较高;而 Flink 的流处理是真正意义上的实时处理,而且状态管理做得更好。
我们使用 Flink 对日志进行预处理,比如字段提取、格式标准化、错误日志过滤等操作,极大提升了后续查询的效率。
存储层:Elasticsearch 仍是首选
Loki 确实是一个优秀的日志系统,在轻量级和云原生友好方面表现不错,但考虑到我们已有大量基于 ES 的查询逻辑和索引结构,迁移成本过高。
因此我们决定继续使用 Elasticsearch,同时引入了一些优化措施:
- 使用 ILM(Index Lifecycle Management)策略控制索引生命周期;
- 引入 hot-warm-cold 架构降低存储成本;
- 调整分片数量以提升写入性能。
代码实践:核心模块代码片段
Filebeat 配置示例

filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/app/*.log
fields:
service: app
fields_under_root: true
output.kafka:
hosts: ["kafka-broker1:9092", "kafka-broker2:9092"]
topic: 'logs'
Flink 日志处理逻辑片段(Java)
DataStream<String> logs = env.addSource(new KafkaSource<>(...));
logs.map(new MapFunction<String, JsonNode>() {
@Override
public JsonNode map(String value) throws Exception {
// 解析 JSON 格式日志
return objectMapper.readTree(value);
}
})
.filter(jsonNode -> {
// 过滤掉 error_level 为 warn 以下的日志
return jsonNode.get("error_level").asInt() >= 2;
})
.addSink(new ElasticsearchSink<>(...));
Elasticsearch 索引模板配置
{
"index_patterns": ["logs-*"],
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
},
"mappings": {
"dynamic": false,
"properties": {
"timestamp": { "type": "date" },
"service": { "type": "keyword" },
"message": { "type": "text" }
}
}
}
踩坑记录:那些让你崩溃的时刻
1. Kafka 吞吐上不去?
我们在初期测试时发现,Filebeat 发送到 Kafka 的吞吐始终上不去,即便调整了 batch.size、linger.ms 等参数依然不理想。
后来通过抓包发现,Kafka broker 的磁盘 IO 成为了瓶颈。我们最终通过以下几个优化解决了这个问题:
- 增加 Kafka 的磁盘条数,做 RAID 0;
- 启用压缩(snappy)减小网络带宽;
- 增加副本因子,避免单节点热点。
2. Elasticsearch 写入抖动
上线初期,我们发现 Elasticsearch 的写入速度波动很大,GC 时间不稳定。
经过分析,是因为默认的 heap size 设置不合理,导致频繁 Full GC。最后我们根据官方建议,将堆内存设置为物理内存的 50%,不超过 30G,并且启用了 G1GC。
3. Flink Checkpoint 频繁失败
在使用 RocksDB 作为状态后端时,我们经常遇到 Checkpoint 超时的问题。
解决方法是:
- 增大 checkpoint interval;
- 将 state backend 拆分为 FsStateBackend 和 RocksDB;
- 增加 TaskManager 内存;
- 启用增量 Checkpoint。
4. 用户查询体验差
用户反馈说 Kibana 查询响应慢,尤其是聚合类查询。
我们一方面优化了 DSL 查询语句,另一方面引入了一个自研的查询缓存中间层,将高频查询结果缓存下来,减少 ES 的计算压力。
实施效果:改造后的成果
经过几个月的努力,我们完成了整个日志平台的升级迭代,取得了如下成果:
- 日志采集吞吐量提升 3x,QPS 可稳定在 150,000 左右;
- 查询平均响应时间降低 60%,用户反馈良好;
- 资源利用率显著下降:CPU 使用率平均下降 25%,内存节省约 30%;
- 可靠性增强:日志丢失率从原先的 0.1% 下降到几乎为零;
- 扩展性增强:新增日志源只需简单配置,无需修改代码。
最重要的是,整个平台变得更加稳定、易维护,运维同学也轻松了不少。
经验分享:给同行的一些建议

如果你也在考虑重构或者优化你们的日志系统,我想分享几点建议:
1. 技术选型不要盲目追求“新”
很多新潮框架看起来很酷,但如果你们团队没有相关经验,或者周边生态不成熟,贸然使用可能会带来更大风险。要结合团队能力、历史包袱和长期投入来判断。
2. 分阶段、灰度推进最关键
我们这次采用了灰度升级的方式,先上线一部分日志源,再逐步覆盖全部。过程中不断调优,避免了一次性大规模切换带来的不可控风险。
3. 性能监控一定要前置
在整个链路中埋点监控非常关键,包括采集、传输、处理、落盘每个环节的指标都要采集到位,这样才能及时发现问题。
4. 留意日志格式的统一化
不同服务输出的日志格式差异大,容易造成处理困难。尽早推动规范定义,比如统一 timestamp、字段命名、结构化程度等标准。
5. 不要忽视用户体验
技术再牛,如果终端用户觉得不好用也没意义。我们这次特别重视 Kibana 的查询体验优化,甚至做了自研的查询封装层,让用户的搜索更高效。
结语:技术成长就在不断踩坑中
回想这次日志平台的升级过程,确实遇到了不少挑战,也踩了不少坑。但正是这些实际问题的解决,让我们对整个系统有了更深的理解,也积累了宝贵的经验。
技术这条路没有捷径,只有不断动手、不断试错、不断总结。希望我的分享能帮到你,也欢迎留言交流,一起探讨更多技术落地的可能性。

评论 0