Logstash向Elasticsearch发送日志延迟高,如何定位问题来源
延迟问题隔离排查方案
第一步:快速定位延迟所属组件
直接修改Logstash配置做对照测试:
- 临时将output段替换为仅输出到控制台,关闭Elasticsearch输出:
output { stdout { codec => dots } }
- 运行10分钟后对比应用自带timestamp和Logstash生成timestamp的差值:
- 如果差值缩小到秒级甚至更低,说明延迟来自Elasticsearch侧
- 如果差值仍然很大,说明延迟来自Logstash侧的输入/过滤环节
第二步:Logstash侧问题排查(如果上述测试确认是Logstash问题)
优先排查配置性能缺陷
当前配置存在2个明显的性能瓶颈点:
- Grok规则使用贪婪匹配
{.*}定义APPJSON,正则回溯开销极高,高吞吐下会导致filter阶段大量积压- 优化方案:如果应用日志的JSON部分和异常栈之间有固定分隔符,优先用dissect插件替代grok,性能可以提升10倍以上;如果必须用grok,替换
{.*}为(?<appjson>{[^{}]*+(?:(?R)[^{}]*)*+)}精准匹配JSON结构,减少回溯
- 优化方案:如果应用日志的JSON部分和异常栈之间有固定分隔符,优先用dissect插件替代grok,性能可以提升10倍以上;如果必须用grok,替换
- Multiline codec规则存在匹配范围过宽的问题,容易出现大量日志行被误归到同一条日志的情况,导致后续JSON解析失败、积压
- 优化方案:调整multiline的pattern,优先匹配正常日志的行首格式(比如正常日志行首是时间戳、日志级别这类特征),增加
negate => true配置,只有不符合正常行首规则的行才归到上一条
- 优化方案:调整multiline的pattern,优先匹配正常日志的行首格式(比如正常日志行首是时间戳、日志级别这类特征),增加
借助监控确认积压环节
调用Logstash监控API查看各阶段耗时:
- 执行
curl http://<logstash节点IP>:9600/_node/stats/pipelines - 查看以下指标:
events.in、events.out:如果out远小于in,说明存在整体积压filters.duration_in_millis:该值过高说明过滤阶段是瓶颈outputs.duration_in_millis:该值过高说明输出到ES的环节是瓶颈
第三步:Elasticsearch侧问题排查(如果上述测试确认是ES问题)
- 先查看ES节点的bulk线程池状态:执行
GET _cat/thread_pool/bulk?v,如果队列(queue)长时间大于0、有拒绝(rejected)记录,说明ES写入能力不足 - 优化ES写入配置:
- 调整日志索引的
refresh_interval为30s,写入阶段关闭不必要的副本(写入完成后再打开) - 确保日志索引分片数合理:单分片大小控制在20GB-50GB区间
- 升级Logstash的Elasticsearch output配置,增加
bulk_size => 1500调整批量写入大小,和pipeline.batch.size匹配
- 调整日志索引的
内容的提问来源于stack exchange,提问作者Moshe
相关产品推荐
相关产品推荐

