2 预处理细节

概述

本节提供监控项值预处理详细信息。 监控项值预处理允许为接收到的监控项值定义和执行转换规则

预处理由预处理管理进程管理,该进程在Zabbix 3.4中添加,用于执行预处理步骤。 所有来自不同数据收集器的值(无论是否经过预处理)都会在添加到历史缓存之前通过预处理管理器。 基于套接字的 IPC 通信作用于数据收集器(轮询器、捕获器等)和预处理进程之间。 Zabbix server或 Zabbix proxy(由代理监控的监控项)负责执行预处理步骤。

监控项值预处理

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

2 预处理细节 - 图1

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

  • 数据收集从数据源的原始数据开始。 此时数据只包含ID、时间戳和值(也可以是多个值)
  • 无论使用哪种类型的数据收集器,对于主动或被动检查、陷阱监控项等的想法都是相同的,因为它只更改数据格式和通信启动器(任何一个数据收集器都在等待连接和数据 ,或数据收集器发起通信并请求数据)。 验证原始数据,从配置缓存中检索监控项配置(使用配置数据丰富数据)。
  • 基于套接字的 IPC 机制用于将数据从数据收集器传递到预处理管理器。 此时数据收集器继续收集数据,无需等待预处理管理器的响应。
  • 执行数据预处理。 这包括执行预处理步骤和依赖项处理。

如果任何预处理步骤失败,则在执行预处理时,监控项可以将其状态更改为不支持。

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

如果数据规范化失败(例如,当文本值无法转换为数字时),监控项可以将其状态更改为不支持。

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

监控项值预处理

为了可视化数据预处理过程,我们使用下面的简化图来展示:

2 预处理细节 - 图2

上图仅以简化形式显示了与监控项值预处理相关的流程、对象和主要操作。 该图没有显示有条件的方向变化、错误处理或循环。 这张图只显示了一个预处理进程(在现实生活中可以使用多个预处理进程),只处理一个监控项值,我们假设该监控项需要执行至少一个预处理步骤。 此图的目的是展示监控项值预处理管道背后的理念。

  • 使用基于套接字的 IPC 机制将监控项数据和监控项值传递给预处理管理器。
  • 监控项被放置在预处理队列中。

监控项可以放在预处理队列的末尾或开头。 Zabbix 内部监控项总是放在预处理队列的开头,而其他监控项类型在最后排队。

  • 此时数据流停止,直到至少有一个未占用(即不执行任何任务)预处理进程。
  • 当预处理进程可用时,将向它发送预处理任务。
  • 预处理完成后(预处理步骤执行失败或成功),预处理值被传递回预处理管理器。
  • 预处理管理器将结果转换为所需格式(由监控项值类型定义)并将结果放入预处理队列。 如果当前监控项有依赖项,则依赖项也将添加到预处理队列中。 依赖项在主要监控项之后的预处理队列中排队,但仅适用于有值设置且不处于不支持状态的主要监控项。
监控项值处理流水线

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

  • 依赖项可以接收值,而主要监控项不能。 这可以通过使用以下用例来实现:
    • 主要监控项具有值类型UINT,(可以使用陷阱监控项),依赖项具有值类型TEXT
    • 主要监控项和依赖项都不需要预处理步骤。
    • 文本值(如“abc”)应传递给主要监控项。
    • 由于没有要执行的预处理步骤,预处理管理器检查主项是否处于不支持状态以及是否设置了值(两者都为真)并将具有与主要监控项相同的值的依赖项排入队列(因为没有预处理步骤 )。
    • 当主要监控项和依赖项都达到历史同步阶段时,主要监控项变为不支持,因为值转换错误(文本数据无法转换为无符号整数)。

因此,依赖项收到一个值,而主要监控项状态将变为不支持。

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

预处理队列

预处理队列是一种 FIFO 数据结构,它存储值,保留值由预处理管理器检索的顺序。 FIFO 逻辑有多个例外:

  • 内部监控项在队列的开头排队
  • 依赖项始终排在主要监控项之后

我们使用下面的简化图来可视化展示预处理队列的逻辑:

2 预处理细节 - 图3

预处理队列中的值从队列的开头刷新到第一个未处理的值。 因此,例如,预处理管理器将刷新值1、2和3,但不会刷新值 5,因为值4尚未处理:

2 预处理细节 - 图4

刷新后队列中只剩下两个值(4 和 5),将值添加到预处理管理器的本地数据缓存中,然后将值从本地缓存传输到历史缓存。 预处理管理器可以在单项模式或批量模式下从本地数据缓存中刷新值(用于依赖项和批量接收的值)。

Preprocessing caching

Preprocessing caching was introduced to improve the preprocessing performance for multiple dependent items having similar preprocessing steps (which is a common LLD outcome).

Caching is done by preprocessing one dependent item and reusing some of the internal preprocessing data for the rest of the dependent items. The preprocessing cache is supported only for the first preprocessing step of the following types:

  • Prometheus pattern (indexes input by metrics)
  • JSONPath (parses the data into object tree and indexes the first expression [?(@.path == "value")])

预处理进程

Zabbix server 配置文件允许用户设置预处理工作进程的数量。StartPreprocessors配置参数应用于设置预处理进程的预分配实例数。 预处理进程的最佳数量可以由许多因素决定,包括“可预处理”监控项(需要执行任何预处理步骤的监控项)的数量、数据收集过程的数量、监控项预处理的平均步骤数等。

但是假设没有像解析大型 XML/JSON 块这样的繁重的预处理操作,预处理进程的数量可以匹配数据收集器的总数。 这样,大多数情况下(除了来自收集器的数据大量进入的情况)至少有一个空闲的预处理进程来处理收集的数据。

太多的数据收集进程(轮询器、无法访问的轮询器、ODBC 轮询器、HTTP 轮询器、Java 轮询器、pingers、陷阱器、代理轮询器)连同 IPMI 管理器、SNMP 陷阱器和预处理进程可能会耗尽预处理管理器的每个进程的文件描述符限制。 这将导致 Zabbix server停止(通常在启动后不久,但有时可能需要更多时间)。 应修改配置文件或提高限制以避免出现这种情况。