上海网站策划,网站根目录文件 seo,网站页面好了怎么做后端,长沙网站建设软件作者#xff1a;Fae Charlton, Alexandros Sapranidis 内部改进如何降低 Elastic 8.13 中的内存使用。
在 8.12 版本中#xff0c;我们引入了性能预设 —— 一种更简单的方法#xff0c;用于调整 Elastic Agent 和 Beats 以适应各种场景。这提高了常见环境的性能#xff0…作者Fae Charlton, Alexandros Sapranidis 内部改进如何降低 Elastic 8.13 中的内存使用。
在 8.12 版本中我们引入了性能预设 —— 一种更简单的方法用于调整 Elastic Agent 和 Beats 以适应各种场景。这提高了常见环境的性能而过去通常需要进行详细调整。
从 8.13 版本开始我们专注于改进我们的内部库以更好地支持这些预设。其结果是我们的内部事件队列进行了重写为所有 Beats 带来了降低的内存使用。
在我们的内部基准测试套件中Filebeat 8.13 在所有预设上显示出大约 20% 的内存减少。在这篇文章中我们将探讨如何实现这一点。 Beats 事件队列
由 Elastic Agent 和 Beats 接收的事件在发送到输出端时会存储在一个队列中。队列的配置对于需要多少内存来存储这些事件有很大影响。在 8.13 版本之前这种配置涉及一些容易被误解的参数这些参数常常是配置错误的常见来源。
我们来回顾一下这些调优参数及其作用。 bulk_max_size 和 flush.min_events
当输出 worker 准备好发送数据时它会从内部队列请求一批事件。这个请求的大小由 bulk_max_size 控制这是一个重要的输出调优参数。如果 bulk_max_size 是 100那么队列将尝试提供 100 个事件给输出 worker 发送。
队列还有一个 flush.timeout 参数。当这个参数为零时队列会立即返回事件即使它没有足够的事件。在我们的示例中如果请求了 100 个事件但队列中只有 50 个那么输出 worker 将获得 50 个事件。但是当 flush timeout 为正值时队列会等待达到指定的超时时间以收集更多事件。
但是请注意假设我们设置了一个 5 秒的 flush timeout 并请求 100 个事件。你可能会期望如果队列有 100 个事件它将立即返回这 100 个事件否则它将延迟多达 5 秒以达到 100 个事件。从 8.13 版本开始你会是正确的。但是旧的队列并不是这样的队列不是等待填充一个输出请求 —— 它等待填充一个内部队列缓冲区这个缓冲区的大小可能完全不同。
内部队列缓冲区的大小由 flush.min_events 控制这是一个看起来非常类似于 bulk_max_size 的参数经常被误解但是它可能会产生非常不同的影响。 这些问题可能导致以下一些性能问题 示例 1增加内存使用量 bulk_max_size: 50
flush.timeout: 10s
flush.min_events: 1500
最大的问题是内存使用。在 8.13 版本之前队列一次管理一个完整的缓冲区的内存。在此示例配置中一个完整的事件缓冲区可以提供 30 个输出批次每个批次 50 个事件。这意味着我们需要完全处理 30 个批次才能释放最初那一个批次的内存 示例 2增加延迟 bulk_max_size: 100
flush.timeout: 5s
flush.min_events: 200
假设输出请求 100 个事件。队列中有 100 个事件但在填满 200 个事件的完整缓冲区之前它不会返回任何事件。如果不再有更多事件进来它将等待整整 5 秒才返回任何事件尽管请求本可以立即得到满足。
这一直是一个陷阱但在 8.12 版本中我们将默认的 flush.timeout 从 1 秒增加到 10 秒时这个问题变得更加严重。对大多数用户来说这提高了性能因为大批量事件的处理更有效率。但是那些将输出的 bulk_max_size 设置得较低的用户看到了增加的延迟尽管理论上有足够的事件可以立即开始处理。 示例 3事件批次变小 bulk_max_size: 100
flush.timeout: 1s
flush.min_events: 150
我们有一个队列里面有 300 个事件输出每次请求 100 个事件。理论上我们应该能够将 300 个事件作为三批每批 100 个事件发送但队列的缓冲区大小为 150 个事件队列一次只从一个缓冲区返回事件。因此实际上发生的是每个缓冲区被分成两批 —— 一批 100 个事件和一批 50 个事件。
对于大多数配置来说即使队列中还有更多事件输出工作者偶尔也会得到比其请求的少的事件。这不足以造成巨大差异但略微降低了效率如果我们每次都能返回正确数量的事件那将会更好。 我们对此做了什么
我们最终重写了队列完全删除了内部缓冲区的链条。相反我们现在使用一个固定的单一缓冲区根据需要在末尾循环。事件也从这个共享缓冲区中复制出来以组装输出批次。现在flush.timeout 的工作方式与大多数人预期的完全一致如果请求的事件可用队列将立即返回请求的数量的事件否则它将等待达到指定的超时时间来填充请求但仅限于当前请求而不是某些更大的内部限制。
这次重构需要做出一个妥协即原始队列试图避免的 —— 事件批次不再是内存中的单个连续序列。但作为交换我们得到了巨大的好处
示例一中的内存问题已经消失。一旦输出确认了一批事件已经被处理队列就可以释放它的内存不管它相对于其他事件批次的位置如何。示例二中的延迟问题已经消失。如果队列有足够的事件它将返回它们。它们在事件序列中的位置已经不重要了。示例三中的批处理大小问题已经消失。由于事件不再需要来自一个连续的缓冲区我们不需要根据内部内存边界来分割批次。
flush.min_events 现在是一个遗留参数为了向后兼容性它指定了事件批次大小的全局最大值。如果你使用的是性能预设performance preset则可以完全忽略此参数但现在建议自定义队列配置将其设置为一个大值并使用 bulk_max_size 来控制批次大小。只要 flush.min_events 足够大再也没有改变它的性能优势了。 结果
在我们的内部基准测试中我们发现对于所有预设presets都实现了显著的内存节省这些差异是通过使用 Filebeat 在结构化 JSON 事件上进行文件流输入进行测量的
PresetMemory savingsbalanced17%throughput18%scale18%latency24%
所有预设还显示出每个事件的 CPU 成本减少了3%。 性能预设的回报
通过为常见的性能目标定义内置预设我们大大减少了配置 Elastic Agent 和 Beats 时的猜测工作。现在我们正在看到后续的好处因为这为我们的优化工作提供了一组常见的配置目标。期望这些改进将在 8.14 版本及以后继续
Elastic 8.13 中还有什么新功能请查看 8.13 版本的发布公告以了解更多信息 本文中描述的任何功能或功能的发布和时间安排仍然完全由 Elastic 自行决定。当前尚不可用的任何功能或功能可能无法按时或根本无法交付。 原文Improving the event queue in Elastic Agent and Beats | Elastic Blog