4. 日志收集架构:常见日志收集系统(ELK、Loki、Flume)及其在熔断下的表现
日志收集是整个可观测性的基石。平时风平浪静时,这套系统看上去都挺靠谱。一旦熔断发生,流量瞬间被切断,大量日志产生的模式也突变。这时候,不同架构的真实差距就暴露出来了。我参与过不少系统的故障复盘,很多日志丢失的问题其实不是熔断本身导致的,而是收集系统扛不住压力,自己先垮了。
下面这张图,梳理了我们这章要聊的三个主流架构,以及它们在熔断场景下的核心差异。你可以先看一眼,有个整体印象。
4.1 ELK(Elasticsearch + Logstash + Kibana)家族
ELK 是目前使用最广泛的组合。但说实话,它在熔断下的表现,我持保留态度。为什么?因为它的日志传输是典型的“推模型”。
Logstash 作为中间件,从应用端拉取日志后,会经过 filter 处理,然后批量推送给 Elasticsearch。这个过程本身没什么问题。问题在于,当下游 Elasticsearch 因为高负载触发写入熔断(HTTP 429)时,Logstash 的默认处理策略非常简单:要么阻塞,要么丢弃。
如何优化?我个人的习惯是,必须启用 Logstash 的持久化队列。这是一种基于磁盘的缓冲机制。
配置示例:
# 在 pipeline.yml 或 logstash.yml 中
queue.type: persisted
queue.max_bytes: 10gb
queue.drain: true # 优雅关闭时等待队列清空
这相当于给 Logstash 加了一层“蓄水池”。当 ES 熔断时,日志会堆积在磁盘上而不是直接丢弃。等 ES 恢复后,Logstash 自动重放。不过要注意,磁盘 I/O 和队列管理本身也有开销,千万别设成无限大。
4.2 Grafana Loki
聊完 ELK,我们看看 Loki。它跟 ELK 的理念完全不同。ELK 是全文索引,Loki 则“索引标签,不索引日志内容”。这个设计差异,在熔断场景下带来了巨大的好处。
Loki 的日志采集采用的是拉模型。Promtail 作为代理部署在每台机器上,主动去本地文件或系统日志中拉取内容,然后推给 Loki。你不妨想想,这里的关键点在哪?日志的生产者和采集者解耦了。
就算 Loki 服务端挂了,Promtail 也只会不断重试。它不会反过来拖死你的应用程序。因为应用写日志到本地文件,这是磁盘操作,基本不受网络影响。
Loki 也有短板。它的查询性能不如 ES 灵活,特别是对日志全文内容做模糊搜索时。但在“保障数据完整性”这个核心指标上,它很省心。
4.3 Apache Flume
Flume 在大数据生态里用的比较多,但它处理日志流的思路非常经典。它把整个流程分成三块:Source、Channel、Sink。
- Source:从数据源(如日志文件、网络端口)采集数据。
- Channel:缓冲数据。这是核心。可以选择 Memory Channel(快但丢数据)或 File Channel(慢但安全)。
- Sink:把数据写出到目标(如 HDFS、Kafka、ES)。
熔断降级发生时,通常影响的是 Sink 这一侧。比如 Sink 要写入的 HDFS 集群挂了,或者写入目标响应超时。这时候 Flume 本身会怎样?
如果配置了 File Channel,Flume 会把事件数据持久化到磁盘的 checkpoint 和 data 目录。Sink 那边的线程会不断重试。这个机制,说白了就是用磁盘空间换数据安全。我见过一个生产系统,File Channel 扛住了长达 2 小时的 HDFS 宕机,事后数据零丢失。当然,代价是需要预留足够的磁盘空间,监控 Channel 的填充率。
4.4 三者在熔断场景下的关键对比
我整理了一张表格,把它们的核心差异放在一起,方便你快速参考。
| 对比维度 | ELK(Logstash + ES) | Grafana Loki | Apache Flume(File Channel) |
|---|---|---|---|
| 日志传输模式 | 推模型(应用→Logstash→ES) | 拉模型(Promtail→Loki) | 推模型(Source→Channel→Sink) |
| 熔断时数据完整性 | 低。默认内存缓冲,极易丢数据 | 高。文件拉取+重试机制,基本不丢 | 高。File Channel 持久化,稳扎稳打 |
| 对上游应用的影响 | 中。Logstash 阻塞可能拖拽应用 | 低。应用只管写文件,完全无感 | 低。Source 只读一次,写入 Channel 后和上游无关 |
| 资源消耗 | 高。ES 索引和存储很吃资源 | 低。对象存储为主,计算资源少 | 中。磁盘 I/O 是主要开销 |
| 配置复杂度 | 高。需要调优 ES 熔断器、Logstash 队列 | 低。开箱即用,运维友好 | 中。需要合理设置 Channel 参数 |
| 最佳场景 | 查询需求频繁、需要全文检索 | 注重可靠性和低成本 | 大数据生态、对数据完整性要求极高 |
最后留一点题外话。不管你选哪个架构,我建议一定要加上日志分级的兜底策略。比如,核心业务日志走一条高可靠的通道,非核心审计日志可以容忍适当丢弃。别让普通错误日志,冲垮了你最重要的接口轨迹。