2 预处理详情

概述

本节提供有关监控项值预处理的详细信息。通过监控项值预处理,可以为接收到的监控项值定义并应用execute transformation rules

预处理由预处理管理器进程以及执行预处理步骤的预处理工作进程共同管理。所有带有预处理设置的值(在Zabbix 7.0.17之前,所有值)从不同的数据收集器接收后,都会经过预处理管理器,然后才被添加到history cache中。数据收集器(轮询器、trappers等)与预处理进程之间通过基于套接字的IPC通信进行交互。无论是Zabbix server还是Zabbix proxy(用于由proxy监控的监控项),都会执行预处理步骤。

监控项值处理

为了可视化数据从数据源到Zabbix数据库的流向,我们可以使用以下简化图示:

上图仅以简化形式展示了与监控项值处理相关的进程、objects和操作。该图未显示条件方向变化、错误处理或循环。预处理管理器的本地数据缓存也未显示,因为它不直接影响数据流。此图的目标是展示参与监控项值处理的进程及其交互方式。

  • 数据收集始于来自数据源的原始数据。此时,数据仅包含ID、时间戳和值(也可以是多个值)。
  • 不论使用哪种类型的数据收集器,主动检查、被动检查或trapper 监控项等的原理都相同,因为这只会改变数据格式和通信发起者(要么数据收集器等待连接和数据,要么数据收集器发起通信并请求数据)。原始数据经过验证后,将从configuration cache中检索监控项配置(数据将通过配置数据进行丰富)。
  • 使用基于套接字的IPC机制将数据从数据收集器传递到预处理管理器。此时,数据收集器将继续收集数据,而不会等待预处理管理器的响应。
  • 执行数据预处理。这包括执行预处理步骤和依赖的监控项处理。

如果任何预处理步骤失败,则监控项的状态可以在预处理期间更改为NOT SUPPORTED。

  • 预处理管理器的本地数据缓存中的历史数据将被刷新到history cache中。
  • 此时数据流停止,直到下一次history cache同步(当历史同步进程执行数据同步时)。
  • 同步过程从数据归一化开始,然后将数据存储在Zabbix数据库中。数据归一化将执行转换为所需的监控项类型(在监控项配置中定义的类型),包括根据为这些类型允许的预定义大小截断文本数据(HISTORY_STR_VALUE_LEN用于string,HISTORY_TEXT_VALUE_LEN用于文本,HISTORY_LOG_VALUE_LEN用于日志值)。归一化完成后,数据将被发送到Zabbix数据库。

如果数据归一化失败(例如,当文本值无法转换为数字时),则监控项的状态可以更改为NOT SUPPORTED。

  • 收集到的数据将被处理 - 检查触发器,如果监控项变为NOT SUPPORTED,则更新监控项配置等。
  • 从监控项值处理的角度来看,这被认为是数据流的结束。

监控项 值预处理

数据预处理按以下步骤执行:

  • 如果 监控项 既没有预处理步骤也没有依赖的 监控项,则其值将被添加到 history cache 或发送到 LLD 管理器。否则,监控项 的值将通过基于 UNIX 套接字的 IPC 机制传递给预处理管理器(在 Zabbix 7.0.17 之前,所有值在被添加到 history cache 或发送到 LLD 管理器之前都会经过预处理管理器)。
  • 创建一个预处理任务并将其添加到队列中,同时通知预处理工作进程有新任务。
  • 此时数据流暂停,直到至少有一个空闲的(即未执行任何任务的)预处理工作进程。
  • 当有可用的预处理工作进程时,它将从队列中取出下一个任务。
  • 预处理完成后(无论预处理步骤执行成功或失败),预处理后的值将被添加到已完成任务队列,并通知管理器有新的已完成任务。
  • 预处理管理器将结果转换为所需的格式(由 监控项 的值类型定义),然后将其添加到 history cache 或发送到 LLD 管理器。
  • 如果处理的 监控项 存在依赖的 监控项,则依赖的 监控项 将使用预处理后的主 监控项 值被添加到预处理队列中。依赖的 监控项 将绕过正常的值预处理请求而被入队,但仅适用于值已设置且不处于 NOT SUPPORTED 状态的主 监控项。

请注意,在图中主 监控项 的预处理过程略作简化,省略了预处理缓存的步骤。

预处理队列

预处理队列的组织方式如下:

  • 待处理任务列表:
    • 按接收顺序直接从值预处理请求创建的任务
  • 立即任务列表(在待处理任务之前处理):
    • 测试任务(由前端的 监控项/预处理测试请求创建)
    • 依赖的 监控项 任务
    • 序列任务(必须按严格顺序执行的任务):
      • 包含使用最新值的预处理步骤的任务:
        • 变化
        • 节流
        • JavaScript(字节码缓存)
      • 依赖的 监控项 预处理缓存
  • 已完成任务列表

预处理缓存

预处理缓存的引入是为了提升多个具有相似预处理步骤的依赖 监控项(这通常是LLD的结果)的预处理性能。

缓存通过预处理一个依赖的 监控项,并为其余依赖的 监控项 重用部分内部预处理数据来实现。预处理缓存仅支持以下类型的第一步预处理:

  • Prometheus模式(通过指标索引输入)
  • JSONPath(将数据解析为 object 树并索引第一个表达式 [?(@.path == "value")]

预处理工作进程

Zabbix server配置file允许用户设置预处理工作线程的数量。 应使用startpreprocessors配置参数来设置预启动的预处理工作者实例数量,该数量至少应与可用CPU核心数量匹配。

如果预处理任务不是CPU密集型且涉及频繁的网络请求,则建议配置额外的工作进程。 预处理工作者的最佳数量可能由许多因素决定,包括“可预处理”监控项的数量(需要进行execute任何预处理步骤的监控项)、数据收集进程的数量、监控项预处理的平均步骤数量等。 工作者数量不足可能导致较高的memory使用率。有关解决Zabbix安装中过多memory使用率的问题,请参见Profiling excessive memory usage with tcmalloc

但假设不存在解析大型XML/JSON块等繁重的预处理操作,则预处理工作者的数量可以与数据收集器的总数匹配。这样,通常情况下(除了数据从收集器批量到达的情况),将至少有一个未被占用的预处理工作者来处理收集到的数据。

过多的数据收集进程(轮询器、不可达轮询器、ODBC轮询器、HTTP轮询器、Java轮询器、ping器、trapper、代理轮询器)与IPMI管理器、SNMP trapper和预处理工作者一起可能会耗尽预处理管理器的每个进程file描述符限制。

耗尽每个进程的file描述符限制将导致Zabbix server停止,通常在启动后不久发生,但有时可能需要更长时间。 为避免此类问题,请查看Zabbix server configuration file以优化并发检查和进程数量。 此外,如有必要,请确保通过检查和调整系统限制,将file描述符限制设置得足够高。

值处理管道

监控项 值处理由多个进程分多个步骤(或阶段)执行。这可能会导致:

  • 一个依赖的 监控项 可以接收值,而主值却不能。可以通过以下使用场景实现:
    • 主 监控项 的值类型为 UINT(可以使用 trapper 监控项), 依赖的 监控项 的值类型为 TEXT
    • 主值和依赖的 监控项 都不需要预处理步骤。
    • 应该向主 监控项 传递一个文本值(例如,"abc")。
    • 由于没有预处理步骤需要执行,预处理管理器会检查主 监控项 是否不在 NOT SUPPORTED 状态, 并且值是否已设置(两者都为真),然后将依赖的 监控项 与主 监控项 的相同值一起入队 (因为没有预处理步骤)。
    • 当主值和依赖的 监控项 都进入历史数据同步阶段时,主 监控项 会因为值转换version错误 (文本数据无法转换为无符号integer)而变为 NOT SUPPORTED 状态。

结果是,依赖的 监控项 接收到一个值,而主 监控项 改变为 NOT SUPPORTED 状态。

  • 一个依赖的 监控项 接收到的值在主 监控项 历史数据中不存在。该使用场景与前一个非常相似, 除了主 监控项 的类型不同。例如,如果主 监控项 使用 CHAR 类型, 那么主 监控项 的值将在历史数据同步阶段被截断,而依赖的 监控项 将从主 监控项 的初始值 (未截断的值)接收它们的值。