深入 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](仅 qu...
深入 Logstash 12 - Multiple Pipelines 与 pipeline-to-pipeline
上一篇讲清了 DLQ 如何把逻辑上永久无法处理的 event 隔离到独立存储、等待补救管道重处理。这一篇进入另一个维度的隔离:一个 Logstash 进程里运行多条管道,管道之间互不干扰,又能通过 virtual address 串联成拓扑。 核心问题是三个:多管道的资源和生命周期如何隔离,pipeline-to-pipeline 通信怎么实现,以及什么时候该用多管道而不是在单管道里写 conditional。 单管道的局限 单管道(一个 logstash.conf)在简单场景下够用,但遇到两类需求时会暴露问题: 123456789101112问题一:不同数据流的处理要求差异大 - syslog 流:高吞吐、无状态 filter、8 个 worker - 慢查询日志:低频、复杂 Grok、2 个 worker - 同一管道里 worker 数只能统一设,无法按流分配资源问题二:任一 output 挂掉,整条管道停摆 - Logstash 默认在任一 output 不可用时阻塞整条管道 (这是 at-least-once 投递保证的代价,不是缺陷) - 同时写 ES...
深入 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 参数控制。 1234567891011121314Memory 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 请求;索引模板与 data stream 如何决定文档落在哪个物理存储;哪些失败会被重试、哪些会真的丢掉 event;ES 的慢响应如何一路传导成 input 侧的减速。 数据流:event 从 filter 出口到 ES 的路径 123456789101112131415161718192021222324pipeline worker(同一线程内跑完 filter 再跑 output) │ ▼ 攒批边界:pipeline.batch.size 条 或 pipeline.batch.delay 到时 elasticsearch output plugin ...
深入 Logstash 07 - 常用 filter 组合:mutate、date、geoip 与条件
上一篇讲完了 dissect 如何用分隔符驱动的线性扫描替代 Grok 的回溯正则,代价是无法处理非均匀格式。这一篇进入 filter 阶段最常见的后续加工链:mutate 改写字段、date 把日志时间戳覆盖 @timestamp、geoip 用 IP 换取地理信息,以及用条件判断和 tag 做分支路由。 核心问题:date filter 为什么一定要改写 @timestamp,而不是新增一个字段;条件判断和 tag 驱动的分支是 Logstash 唯一的路由原语,它和消息系统的 topic 路由有何本质区别。 数据流:event 经过 filter 链的变换过程 1234567891011121314 ┌──────────────────────────────────────────────────────┐ │ filter block │ │ ...
深入 Logstash 06 - dissect 与结构化 filter:放弃回溯换吞吐
官方基准里,同条件单 filter 的 dissect 比 Grok 快一成到两成。这个数字小到不值得为它改配置。dissect 真正值钱的地方在另一头:它不用正则引擎,回溯那条会让单条 event 从微秒跳到秒级的路径在它这里根本不存在。 顺着这个判断往下,本篇落到三件具体的事:线性扫描的每一步怎么走、dissect 的语法能覆盖到哪、以及同一个管道里 dissect 和 Grok 怎么分工。 123456789101112131415同一行日志,两条处理路径:message: "2026-08-06T13:40:00 INFO pay-svc user=42 amount=99.50" │ ├── dissect ──── 找分隔符 ──── O(n) 线性扫描 ──── 字段 │ 无正则引擎 │ 无回溯 │ └── grok ─────── ...
深入 Logstash 05 - Grok 的本质:命名正则加预定义 pattern
Grok 的全部机制可以用一句话交代:%{PATTERN:field} 在管道启动时被递归展开成一段纯正则,字段名就是命名捕获组的组名,匹配交给一个回溯式正则引擎执行一次。它的性能上限、失败语义、调试手段都能从正则的性质直接推出来,不需要额外的心智模型。 这条线索往下追会落到三个具体问题:展开时哪些默认值决定了"到底有没有字段产出"、匹配失败与匹配超时为什么打的是两个不同的 tag、以及灾难性回溯除了"写 pattern 时小心"之外还有没有运行时的保险。 123456789101112131415161718192021222324input event message: "203.0.113.5 GET /api 200" │ ▼┌───────────────────────────────────────────┐│ grok filter ││ ...
深入 Logstash 04 - input 插件:拉取、监听与 Beats 接入
input 层能给出多强的可靠性,由一件事决定:"读到哪里"这个状态存放在哪里、在什么时刻推进。file input 把它写进本地 sincedb 文件;kafka input 交给 broker 侧的 consumer group;beats input 自己不存,靠 Filebeat 的 registry 配合一次 ACK 来推进。三种介质完全不同,推进时刻却停在同一条线上:event 进入 Logstash 内部队列,而不是写进下游成功之后。 这一篇沿这条线索展开三件事:sincedb 到底记了哪几列、beats 的 ACK 语义边界在哪里、kafka 的 offset 提交时机由哪个参数控制。顺带回答一个更靠前的问题——拉模型和推模型的分野,落到可靠性上究竟差在哪。 1234567891011121314151617┌──────────────────────────────────────────────────────────┐│ INPUT 层 ││...





