改进 Elastic Agent 和 Beats 中的事件队列

作者: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 savings
balanced17%
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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/817450.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K8S节点kubectl命令报错x509: certificate signed by unknown authority

K8S节点上执行kubectl get node命令报错证书问题,查看kubelet日志如下 [localhost10 ~]$ journalctl -xeu kubelet --since "2024-04-09" --no-pager 4月 09 00:06:22 10.10.44.23-v7-prod-cams-08 kubelet[2142]: I0409 00:06:22.150535 2142 csi_pl…

Gson

1.简介 Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库。可以将一个 JSON 字符串转成一个 Java 对象(反序列化),或者反过来(序列化)。 在bulid.gradle中添加依赖 implementation com.goo…

LinkedList用法详解(Java)

LinkedList LinkedList 是 Java 中的一个常用类&#xff0c;它实现了 List 接口&#xff0c;采用双向链表数据结构。 1. 创建 LinkedList 对象 import java.util.LinkedList;LinkedList<String> linkedList new LinkedList<>();2. 添加元素 linkedList.add(&q…

单调栈和单调队列所学的一些问题

单调栈和单调队列所学的一些问题 单调栈 单调栈中的元素要求从栈底到栈顶单调递增 遍历数组&#xff0c;如果元素入栈后符合单调要求则顺利入栈不符合要求则弹出栈顶元素&#xff0c;元素出栈时得出结果 右侧结果:待入栈元素 左侧结果:出栈后的栈顶元素 单调栈主要用来求每一…

OpenHarmony实战开发-如何使用Web预渲染实现功能介绍。

介绍 为了便于大家在使用本案例集时能够更详细的了解各个案例&#xff0c;本案例基于Web预渲染实现了案例介绍功能&#xff0c;即应用右下角的问号icon。 效果图预览 使用说明 因为直接加载的线上README&#xff0c;因此本功能需联网使用点击icon&#xff0c;即会弹出对应案…

爬虫的目的是做什么

通过网站域名获取HTML数据解析数据&#xff0c;获取想要的信息存储爬取的信息如果有必要&#xff0c;移动到另一个网页重复过程 这本书上的代码的网址是 &#xff1a; GitHub - REMitchell/python-scraping: Code samples from the book Web Scraping with Python http://shop.…

.NET使用Refit

学习笔记&#xff1a; Refit 是一个 .NET Standard 库,它可以自动生成用于调用 REST API 的强类型客户端。根据 REST API 的定义,自动生成用于调用 API 的客户端类和方法&#xff0c;支持 GET、POST、PUT、DELETE 等常见的 HTTP 方法&#xff0c;且自动处理 HTTP 请求和响应,包…

风力发电场集中监控系统解决方案

风力发电场集中监控系统解决方案 作为清洁能源之一&#xff0c;风力发电场近几年装机容量快速增长。8月17日&#xff0c;国家能源局发布1-7月份全国电力工业统计数据。截至7月底&#xff0c;全国累计发电装机容量约27.4亿千瓦&#xff0c;同比增长11.5%。其中&#xff0c;太阳能…

火绒安全的用法

火绒安全软件是一款综合性的电脑安全防护工具&#xff0c;提供了病毒查杀、系统防护、网络安全等多种功能&#xff0c;以帮助用户保护电脑免受恶意软件和网络威胁的侵害。以下是火绒安全软件的一些主要用法&#xff1a; 病毒查杀&#xff1a;火绒安全软件提供全盘查杀、快速查杀…

[STM32+HAL]DengFOC移植之闭环位置控制

一、源码来源 DengFOC官方文档 二、HAL库配置 1、开启硬件IIC低速模式 低速更稳定 2、PWM波开启 三、keil填写代码 1、AS5600读取编码器数值 #include "AS5600.h" #include "math.h"float angle_prev0; int full_rotations0; // full rotation trac…

hive窗口函数数据范围

window的内包括&#xff1a; (ROWS | RANGE) BETWEEN (UNBOUNDED | [num]) PRECEDING AND ([num] PRECEDING | CURRENT ROW | (UNBOUNDED | [num]) FOLLOWING) (ROWS | RANGE) BETWEEN CURRENT ROW AND (CURRENT ROW | (UNBOUNDED | [num]) FOLLOWING) (ROWS | RANGE) BETWEEN…

前端面试题(小整理)

vue中的生命周期钩子有哪些 beforeCreate&#xff1a; 在实例初始化之后&#xff0c;数据观测 (data observer) 和事件配置 (event/watcher setup) 之前被调用。 在此阶段&#xff0c;实例的属性和方法还未初始化。 created&#xff1a; 在实例创建完成后被立即调用。 可以访问…

文心一言VSchatGPT4

文心一言和GPT-4各有优势&#xff0c;具体表现在不同的测试场景下。 在某些测试场景中心一言的表现优于GPT-4&#xff0c;例如在故事的完整度和情节吸引力方面&#xff0c;文心一言表现得更加符合指令&#xff0c;情节更吸引人。这可能得益于其模型在训练时对中文语境的深入理…

选择电源自动化测试系统,要考虑哪些因素?

随着科技的发展以及市场需求的变化&#xff0c;手动测试以及传统自动化测试不足日益明显&#xff0c;已无法满足当前的电源测试需求&#xff0c;因此&#xff0c;选择全新的自动化测试系统成为必然趋势。那么&#xff0c;要如何选择可靠、高效的电源自动化测试系统呢&#xff1…

计算机网络——网络地址转换(NAT)技术

目录 前言 前篇 引言 SNAT&#xff08;Source Network Address Translation&#xff09;源网络地址转换 SNAT流程 确定性标记 DNAT&#xff08;Destination Network Address Translation&#xff0c;目标网络地址转换&#xff09; NAT技术重要性 前言 本博客是博主用于…

15 Python进阶: random和pyecharts

Python random 模块主要用于生成随机数。 random 模块实现了各种分布的伪随机数生成器。 要使用 random 函数必须先导入&#xff1a; import randompython random 模块的一般用法 Python中的random模块提供了生成伪随机数的功能&#xff0c;可以用于模拟、游戏开发、密码学…

【Spring Boot 源码学习】SpringApplication 的 run 方法核心流程介绍

《Spring Boot 源码学习系列》 SpringApplication 的 run 方法核心流程介绍 一、引言二、往期内容三、主要内容3.1 run 方法源码初识3.2 引导上下文 BootstrapContext3.3 系统属性【java.awt.headless】3.4 早期启动阶段3.5 准备和配置应用环境3.6 打印 Banner 信息3.7 新建应用…

TCP 粘包

从应用层到 TCP 传输层的多个数 据包是一连串的字节流是没有边界的&#xff0c;而且 TCP 首部并没有记录数据包的长度&#xff0c;所以 TCP 传输数据的时候可能会发送粘包和拆包的问题&#xff1b;而 UDP 是基于数据报传输数据的&#xff0c;UDP 首部也记录了数据报的长度&…

Blender表面细分的操作

在使用Blender的过程中,刚开始创建的模型,都会比较少面,这样操作起来比较流畅,减少电脑的计算量,当设计快要完成时,就会增加表面细分,这样更加圆滑,看起来更加顺眼。 比如创建一个猴头,它会默认显示如下: 从上图可以看到,有一些表面会比较大,棱角很多。 这时候你…

java声明一个日期类MyDate

声明一个日期类MyDate&#xff0c;包含如下方法&#xff1a; * - boolean isLeapYear()&#xff1a;判断是否是闰年 * - String monthName()&#xff1a;根据月份值&#xff0c;返回对应的英语单词 * - int totalDaysOfMonth()&#xff1a;返回这个月的总天数 * - int totalDay…