深入 Logstash 17 - Logstash 的演进与 Elastic Agent 的冲击
上一篇把 Logstash 和 Fluentd、Vector 放在一起横向对比。这一篇转向纵向:Logstash 自 2009 年诞生以来历经哪些关键演进,Elastic Agent 和 OpenTelemetry Collector 的出现又如何重新划定了它的边界。 核心问题:持久队列、DLQ、pipeline-to-pipeline 一路补齐的是什么——当 Elastic Agent 分走了边缘采集场景、OTel 提供了厂商中立的替代方案,Logstash 今天的定位是什么。 演进时间线 1234567891011版本 年份 关键变化──────────────────────────────────────────────────────────────1.x 2009 诞生,Ruby 实现,内存队列,单管道2.x 2014 性能改进,引入 pipeline worker 概念5.0 2016 持久队列(PQ)正式发布,多管道配置初步支持6.0 2017 死信队列(D...
深入 Logstash 16 - Logstash vs Fluentd vs Vector:日志管道的三种取舍
上一篇厘清了 Logstash、Beats、Ingest Pipeline 在 Elastic Stack 内部的分工。这一篇跳出 Elastic 生态,把 Logstash 和来自 CNCF 生态的 Fluentd 以及新兴的 Vector 放在一起比较,回答一个跨生态的架构选择问题。 核心问题:三者在插件生态、资源占用、性能、可靠性这四个维度上各自取了什么——JVM 系与原生系的根本差异体现在哪里,什么场景下差异会决定选型。 三者的基本参数 12345工具 语言运行时 诞生年份 归属──────────────────────────────────────────────────Logstash JVM + JRuby 2009 ElasticFluentd CRuby + C ext 2011 CNCF (graduated)Vector Rust (native) 2019 Datadog (开源) Logstash 是三者里最老、插件最多、与 Ela...
深入 Logstash 15 - Logstash vs Beats vs Ingest Pipeline:该用谁
上一篇讲完了性能调优的系统方法。这一篇进入演进对比阶段,把 Logstash、Beats 和 Elasticsearch Ingest Pipeline 三者并排放,回答一个工程决策问题:同样是把数据搬进 ES,三种路径在哪里分叉,分叉的依据是什么。 核心问题:轻量采集用 Beats,简单解析下沉到 Ingest Pipeline,复杂转换才留给 Logstash——这条分工逻辑背后的资源、能力和可靠性代价是什么? 三者的定位 Elastic Stack 的数据接入层有三个层次,各自定位不同: 1234567891011数据源 │ ├─▶ [Beats] Go 语言,轻量级进程,单一职责,低资源 │ │ │ ├─▶ [ES Ingest Pipeline] 运行在 ES 节点内,无独立进程,简单变换 │ │ │ └─▶ [Logstash] JVM 进程,200+ 插件,复杂转换,PQ 可靠性 │ │ │ ...
深入 Logstash 14 - 性能调优:JVM heap、批处理与持久队列磁盘
上一篇解决了怎么用 Node Stats API 和 hot threads 定位瓶颈在哪一段。这一篇进入调优执行层:拿到瓶颈定位结论之后,heap 大小、GC 策略、batch 与 worker 组合、持久队列磁盘 I/O 各应该怎么调。 核心问题:heap 大小与 GC 停顿之间的取舍;pipeline.workers 与 pipeline.batch.size 的组合效果;持久队列磁盘成为瓶颈时的判断和处置。 调优对象全景 1234567891011121314151617181920212223 调优旋钮分布图┌────────────────────────────────────────────────────────┐│ JVM 层 ││ heap size (jvm.options: -Xms / -Xmx) ││ GC 算法 (G1GC 默认; ZGC 可选) ││ G...
深入 Logstash 13 - 监控:Node Stats API、hot threads 与瓶颈定位
上一篇解决了 Multiple Pipelines 的隔离与路由问题。这一篇进入运维调优阶段的第一个主题:怎么从指标判断管道卡在 input、filter 还是 output,以及 hot threads API 的读法。 核心问题:一条管道吞吐下降时,靠什么指标定位瓶颈在哪一段?plugin 级别的耗时从哪里拿到?hot threads 输出能读出什么信息? 监控数据的来源 12345678910111213141516171819202122 Logstash 进程┌──────────────────────────────────────────────┐│ ││ input plugins ││ └─ events.in counter ││ ││ [queue] ...
深入 Logstash 12 - Multiple Pipelines 与 pipeline-to-pipeline
上一篇讲清了 DLQ 如何把逻辑上永久无法处理的 event 隔离到独立存储、等待补救管道重处理。这一篇进入另一个维度的隔离:一个 Logstash 进程里运行多条管道,管道之间互不干扰,又能通过 virtual address 串联成拓扑。 核心问题是三个:多管道的资源和生命周期如何隔离,pipeline-to-pipeline 通信怎么实现,以及什么时候该用多管道而不是在单管道里写 conditional。 单管道的局限 单管道(一个 logstash.conf)在简单场景下够用,但遇到两类需求时会暴露问题: 123456789问题一:不同数据流的处理要求差异大 - syslog 流:高吞吐、无状态 filter、8 个 worker - 慢查询日志:低频、复杂 Grok、2 个 worker - 同一管道里 worker 数只能统一设,无法按流分配资源问题二:一条 filter 处理慢导致全局堵塞 - 单管道共享一个 queue - 某条 filter 插件慢(如重 geoip lookup),占用所有 worker slot - 其他数据流的 event 在 ...
深入 Logstash 11 - 死信队列(DLQ):无法处理的 event 去哪
上一篇讲清了持久队列如何在崩溃边界上把 at-least-once 的保证落盘。这一篇进入另一类失败:event 本身在逻辑上就无法被 output 接受,不管重试多少次都不会成功。这类 event 的归宿是死信队列(Dead Letter Queue,DLQ)。 核心问题是三个:什么样的失败会写进 DLQ,DLQ 里的 entry 长什么样,以及怎么读出来重新处理。 两类失败:重试能解的和重试解不了的 持久队列解决的是"崩溃之后不丢 event",但"不丢"和"能处理"是两回事。一个 event 从 PQ 里出来、送往 Elasticsearch,ES 有可能返回两类错误: 12345678瞬时失败(transient): ES 集群暂时不可达、写入超时、节点临时过载 → 重试就有机会成功,Logstash 的 retry 逻辑能处理永久失败(permanent / document-level): mapping 冲突(往 integer 字段写了 string 值) index 的 mapping 不接受这...
深入 Logstash 10 - 内存队列 vs 持久队列:可靠性的分界线
上一篇(09)拆解了 pipeline 执行模型:worker 并发、batch 凑批、背压自然传导。这一篇进入队列本身:内存队列和持久队列的结构差异,崩溃时各自保住了什么、保不住什么,以及 at-least-once 语义的真实边界。 核心问题:开启持久队列(PQ)之后,Logstash 崩溃重启能恢复哪些 event,又有哪些情况它依然无能为力? 两种队列的基本结构 Logstash pipeline 内部在 input 和 filter/output 之间有一个队列,起到解耦和缓冲的作用。队列类型由 logstash.yml(或 pipelines.yml)里的 queue.type 参数控制。 12345678910111213Memory Queue(queue.type: memory)input thread ──▶ [ event | event | event | event | event ] ──▶ worker ↑ RAM 里的有界环形缓冲区 进程退出 →...
深入 Logstash 09 - pipeline 执行模型:worker、batch 与背压
上一篇(08)覆盖了 Elasticsearch output 的 bulk 写入机制。这一篇进入 pipeline 执行模型本身:pipeline.workers、pipeline.batch.size、pipeline.batch.delay 三个参数各自控制什么,它们共同决定了 filter 和 output 阶段的并发方式;当下游变慢时,背压如何从 output 一路传回 input。 核心问题:为什么把 pipeline.workers 调大,有时吞吐上升、有时毫无变化甚至更差? pipeline 执行结构 Logstash 的 pipeline 里有两类线程,职责分开、数量独立配置: 1234567891011121314input 线程(1 条或多条,取决于 input 插件) │ 每条 event 写入队列 ▼ ┌──────────────────────────────┐ │ queue(内存 / PQ) │ └──────────────────────────────┘ │ 每次拉取一批(...
深入 Logstash 08 - output 插件:Elasticsearch output 与批量写入
上一篇把 filter 阶段的常用加工链梳理完:mutate 改写字段、date 覆盖 @timestamp、geoip 扩展地理信息、条件块用 tag 做分支路由。这一篇进入 output 阶段最常见的目标:Elasticsearch output 插件,重点是批量写入机制、索引命名策略、重试语义和背压来源。 核心问题:Logstash 如何把一批 event 打包成 Elasticsearch bulk 请求;索引模板与数据流如何决定文档落在哪个物理存储;429/503 重试和 400 丢弃背后是什么语义;ES 的慢响应如何一路传导成 input 侧的减速。 数据流:event 从 filter 出口到 ES 的路径 123456789101112131415161718192021222324filter workers │ ▼ output queue (per-pipeline batch) │ ▼ (flush_size events or idle_flush_time elapsed) elasticsearch output p...
