调整和分析 Logstash 管道性能

编辑

调整和分析 Logstash 管道性能

编辑

Logstash 监控 API 中的流指标可以深入了解事件如何在管道中流动。它们可以揭示您的管道是否受资源限制,管道的哪些部分消耗的资源最多,并在调优时提供有用的反馈。

工作线程利用率

编辑

当管道的 worker_utilization 流指标始终接近 100 时,其所有工作线程都忙于处理管道的过滤器和输出。通过查看插件级别的 worker_utilizationworker_millis_per_event 流指标,我们可以看到管道中哪些插件正在消耗可用的工作线程容量。利用这些信息,我们可以了解如何调整管道的设置以增加资源、如何查找和消除浪费的计算,或者意识到需要向上/向外扩展下游目标的能力。

一般来说,插件分为两类

  • CPU 密集型:对事件内容执行计算而不使用网络或磁盘 IO 的插件,往往受益于逐步增加 pipeline.workers,只要进程有可用的 CPU;一旦 CPU 耗尽,额外的并发可能会导致吞吐量降低,因为管道工作线程争夺资源,并且上下文切换所花费的时间增加。
  • IO 密集型:使用网络来丰富事件或传输事件的插件,往往受益于逐步增加 pipeline.workers 和/或调整下面描述的 pipeline.batch.* 参数。这使它们能够更好地利用网络资源,只要这些外部服务没有施加背压(即使 Logstash 几乎使用了其所有可用的 CPU)。

管道的 worker_utilization 离 100 越远,其工作线程等待事件到达队列的时间就越长。由于大多数管道中的数据量通常不一致,因此目标应该是调整管道,使其拥有在高峰期避免将背压传播到其输入端的资源。

队列背压

编辑

当管道接收事件的速度快于其处理速度时,输入最终会遇到背压,从而阻止它们接收其他事件。根据使用的输入插件,背压可以向上游传播或导致数据丢失。

管道的 queue_backpressure 流指标反映了输入端尝试将事件推入队列所花费的时间。该指标在不同管道之间并非完全可比,而是允许您将单个管道的当前行为与其随时间变化的自身进行比较。当此指标增长时,请查看管道的过滤器和输出的下游,以查看它们是否有效地使用资源,是否分配了足够的资源,或者是否正在经历自身的背压。

持久化队列提供持久性保证,并且可以比默认的内存队列吸收更长时间的背压,但是一旦它已满,它也会传播背压。queue_persisted_growth_events 流指标是衡量持久化队列正在主动吸收多少背压的有用指标,并且在管道的生命周期内应趋于零(或更低)。负数表示队列正在缩小,并且工作线程正在赶上之前产生的延迟。

与调整相关的设置

编辑

选择 Logstash 默认值是为了为大多数用户提供快速、安全的性能。但是,如果您发现性能问题,则可能需要修改一些默认值。Logstash 提供了以下可配置选项来调整管道性能:pipeline.workerspipeline.batch.sizepipeline.batch.delay

有关设置这些选项的更多信息,请参阅 logstash.yml

在修改这些选项之前,请确保您已阅读性能故障排除

  • pipeline.workers 设置确定运行多少个线程进行过滤器和输出处理。如果您发现事件正在备份,或者 CPU 没有饱和,请考虑增加此参数的值以更好地利用可用的处理能力。甚至可以发现将此数字增加到超出可用处理器数量的良好结果,因为当写入外部系统时,这些线程可能会花费大量时间处于 I/O 等待状态。
  • pipeline.batch.size 设置定义单个工作线程在尝试执行过滤器和输出之前从队列中收集的最大事件数。较大的批量大小通常效率更高,但会增加内存开销。输出插件可以将每个批次作为一个逻辑单元进行处理。例如,Elasticsearch 输出会尝试为接收到的每个批次发送单个 批量请求。调整 pipeline.batch.size 设置会调整发送到 Elasticsearch 的批量请求的大小。
  • pipeline.batch.delay 设置很少需要调整。此设置会调整 Logstash 管道的延迟。管道批量延迟是管道工作线程在其当前批次尚未满时等待每个新事件的最大时间(以毫秒为单位)。在此时间过去而没有任何其他事件可用之后,工作线程开始执行过滤器和输出。工作线程在接收事件和在过滤器中处理该事件之间等待的最大时间是 pipeline.batch.delaypipeline.batch.size 设置的乘积。

关于管道配置和性能的说明

编辑

如果您计划修改默认管道设置,请考虑以下建议

  • 正在运行的事件总数由 pipeline.workerspipeline.batch.size 设置的乘积确定。此乘积称为正在运行计数。在调整 pipeline.workerspipeline.batch.size 设置时,请记住正在运行计数的值。间歇性地以不规则的时间间隔接收大型事件的管道需要足够的内存来处理这些峰值。在 jvm.options 配置文件中相应地设置 JVM 堆空间(有关更多信息,请参阅Logstash 配置文件)。
  • 衡量每次更改,以确保它提高而不是降低性能。
  • 确保您留下足够的可用内存来应对事件大小的突然增加。例如,生成异常的应用程序,这些异常表示为大型文本 blob。
  • 工作线程数可以设置得高于 CPU 核心数,因为输出通常在 I/O 等待条件下花费空闲时间。
  • Java 中的线程有名称,您可以使用 jstacktop 和 VisualVM 图形工具来确定给定线程使用的资源。
  • 在 Linux 平台上,Logstash 使用描述性名称标记其线程。例如,输入显示为 [base]<inputname,管道工作线程显示为 [base]>workerN,其中 N 是一个整数。在可能的情况下,还会标记其他线程以帮助您识别其用途。

分析堆

编辑

调整 Logstash 时,您可能需要调整堆大小。您可以使用 VisualVM 工具来分析堆。特别是监视器窗格可用于检查您的堆分配是否足以满足当前工作负载。下面的屏幕截图显示了监视器窗格的示例。第一个窗格检查配置了过多正在运行事件的 Logstash 实例。第二个窗格检查配置了适当数量正在运行事件的 Logstash 实例。请注意,此处使用的特定批量大小很可能不适用于您的特定工作负载,因为 Logstash 的内存需求很大程度上取决于您发送的消息类型。

pipeline overload
pipeline correct load

在第一个示例中,我们看到 CPU 的使用效率不高。实际上,JVM 经常必须停止 VM 以进行“完全 GC”。完全垃圾回收是过度内存压力的常见症状。这在 CPU 图表上的尖峰模式中可见。在配置更高效的示例中,GC 图形模式更加平滑,并且 CPU 的使用方式更加均匀。您还可以看到,在分配的堆大小和允许的最大值之间有充足的余量,这为 JVM GC 提供了很大的工作空间。

使用类似于出色的 VisualGC 插件的工具检查深入的 GC 统计信息表明,与在资源密集型的 Old Gen“完全”GC 中花费的时间相比,过度分配的 VM 在高效的 Eden GC 中花费的时间非常少。

只要 GC 模式是可以接受的,偶尔增加到最大值的堆大小是可以接受的。这种堆大小的尖峰发生在响应通过管道的大型事件爆发时。在一般实践中,请在已用堆内存量和最大值之间保持一定的差距。本文档不是 JVM GC 调优的全面指南。有关该主题的更多信息,请阅读官方Oracle 指南。我们还建议阅读调试 Java 性能