2 保存前処理の詳細
概要
このセクションでは、アイテム値の前処理の詳細について説明します。アイテム値の前処理では、受信したアイテム値に対して変換ルールを定義し、実行できます。
前処理は、前処理ステップを実行する前処理ワーカーとともに、preprocessing managerプロセスによって管理されます。 前処理が設定されたすべての値(Zabbix 7.4.1より前では、すべての値)は、さまざまなデータ収集プロセスから受信された後、履歴キャッシュに追加される前にpreprocessing managerを通過します。データ収集プロセス(poller、trapperなど)と前処理プロセスの間では、ソケットベースのIPC通信が使用されます。前処理ステップは、Zabbixサーバー、またはZabbixプロキシ(プロキシによって監視されるアイテムの場合)のいずれかによって実行されます。
アイテム値の処理
データソースからZabbixデータベースまでのデータフローを視覚化するために、以下の簡略化した図を使用できます。

上の図は、アイテム値の処理に関連するプロセス、オブジェクト、およびアクションのみを簡略化した形で示しています。この図には、条件による方向の変化、エラー処理、ループは示されていません。また、前処理マネージャーのローカルデータキャッシュも、データフローに直接影響しないため示されていません。この図の目的は、アイテム値の処理に関与するプロセスと、それらがどのように相互作用するかを示すことです。
- データ収集は、データソースからの生データから始まります。この時点では、データにはID、タイムスタンプ、および値のみが含まれます(複数の値を含む場合もあります)。
- どの種類のデータ収集プロセスを使用する場合でも、アクティブチェック、パッシブチェック、trapperアイテムなどに対する考え方は同じです。変わるのはデータ形式と通信の開始側だけです(データ収集プロセスが接続とデータを待機するか、またはデータ収集プロセスが通信を開始してデータを要求するかのいずれかです)。生データは検証され、アイテム設定が設定キャッシュから取得されます(データに設定情報が付加されます)。
- ソケットベースのIPCメカニズムを使用して、データ収集プロセスから前処理マネージャーへデータが渡されます。この時点で、データ収集プロセスは前処理マネージャーからの応答を待たずにデータ収集を継続します。
- データの前処理が実行されます。これには、前処理ステップの実行と依存アイテムの処理が含まれます。
いずれかの前処理ステップが失敗した場合、前処理の実行中にアイテムの状態がNOT SUPPORTEDに変わることがあります。
- 前処理マネージャーのローカルデータキャッシュにある履歴データは、履歴キャッシュにフラッシュされます。
- この時点で、履歴キャッシュの次回同期までデータフローは停止します(履歴同期プロセスがデータ同期を実行する時点)。
- 同期プロセスは、データをZabbixデータベースに保存する前のデータ正規化から始まります。データ正規化では、目的のアイテム型(アイテム設定で定義された型)への変換が実行されます。これには、それらの型で許可される定義済みサイズに基づくテキストデータの切り詰めも含まれます(string ではHISTORY_STR_VALUE_LEN、text ではHISTORY_TEXT_VALUE_LEN、log値ではHISTORY_LOG_VALUE_LEN)。正規化が完了すると、データはZabbixデータベースに送信されます。
データ正規化に失敗した場合、アイテムの状態がNOT SUPPORTEDに変わることがあります (たとえば、テキスト値を数値に変換できない場合)。
- 収集されたデータが処理されます。トリガーがチェックされ、アイテムがNOT SUPPORTEDになった場合はアイテム設定が更新されるなどの処理が行われます。
- これは、アイテム値の処理という観点では、データフローの終点と見なされます。
アイテム値の前処理
データの前処理は、次の手順で実行されます。
- アイテムに前処理も依存アイテムも設定されていない場合、その値は履歴キャッシュに追加されるか、LLDマネージャーに送信されます。それ以外の場合、アイテム値は UNIX ソケットベースの IPC メカニズムを使用して前処理マネージャーに渡されます(Zabbix 7.4.1 より前では、すべての値が履歴キャッシュに追加されるか LLD マネージャーに送信される前に、前処理マネージャーを経由します)。
- 前処理タスクが作成され、キューに追加されます。その後、新しいタスクについて前処理ワーカーに通知されます。
- この時点で、少なくとも 1 つの未使用(つまり、どのタスクも実行していない)前処理ワーカーが存在するまで、データフローは停止します。
- 前処理ワーカーが利用可能になると、キューから次のタスクを取得します。
- 前処理が完了すると(前処理ステップの実行が失敗した場合も成功した場合も)、前処理済みの値が完了済みタスクキューに追加され、マネージャーに新しい完了済みタスクが通知されます。
- 前処理マネージャーは結果を目的の形式(アイテムの値の型で定義)に変換し、それを履歴キャッシュに追加するか、LLD マネージャーに送信します。
- 処理対象のアイテムに依存アイテムがある場合、前処理済みのマスターアイテム値とともに依存アイテムが前処理キューに追加されます。依存アイテムは通常の値前処理リクエストをバイパスしてキューに入れられますが、これは値が設定されており、かつ NOT SUPPORTED 状態ではないマスターアイテムに対してのみ行われます。

図では、前処理キャッシュを省略しているため、マスターアイテムの前処理はやや簡略化されていることに注意してください。
前処理キュー
前処理キューは、次のように構成されています。
-
保留中のタスクのリスト:
- 受信した順序で、値の前処理リクエストから直接作成されたタスク
-
即時タスクのリスト(保留中のタスクより先に処理されます):
- テストタスク(Webインターフェースによるアイテム/前処理のテストリクエストへの応答として作成されるタスク)
- 依存アイテムのタスク
- シーケンスタスク(厳密な順序で実行する必要があるタスク):
- 最後の値を使用する前処理ステップを持つもの:
- 変化
- スロットリング
- JavaScript(バイトコードキャッシュ)
- 依存アイテムの前処理キャッシュ
- 最後の値を使用する前処理ステップを持つもの:
-
完了したタスクのリスト
前処理キャッシュ
前処理キャッシュは、類似した前処理ステップを持つ複数の依存アイテムの前処理パフォーマンスを向上させるために導入されました(これは一般的なLLDの結果です)。
キャッシュは、1つの依存アイテムを前処理し、その内部前処理データの一部を残りの依存アイテムで再利用することで実現されます。前処理キャッシュは、以下のタイプの最初の前処理ステップでのみサポートされます。
- Prometheusパターン(メトリクスによって入力にインデックスを付ける)
- JSONPath(データをオブジェクトツリーに解析し、最初の式
[?(@.path == "value")]にインデックスを付ける)
前処理ワーカー
Zabbixサーバーの設定ファイルでは、前処理ワーカースレッド数を設定できます。 前処理ワーカーの事前起動インスタンス数を設定するには、StartPreprocessors 設定パラメータを使用します。この値は、少なくとも利用可能なCPUコア数と同じにする必要があります。
前処理タスクがCPU負荷型ではなく、頻繁なネットワークリクエストを伴う場合は、追加のワーカーを設定することを推奨します。 前処理ワーカーの最適な数は、「前処理可能な」アイテム数(何らかの前処理ステップの実行が必要なアイテム)、データ収集プロセス数、アイテム前処理の平均ステップ数など、多くの要因によって決まります。 ワーカー数が不足すると、メモリ使用量が高くなる可能性があります。Zabbix環境で過剰なメモリ使用量をトラブルシュートする方法については、tcmalloc を使用した過剰なメモリ使用量のプロファイリング を参照してください。
ただし、大きなXML/JSONチャンクの解析のような重い前処理処理がないと仮定すると、前処理ワーカー数はデータ収集プロセスの総数と同じにできます。こうすることで、通常は(収集プロセスからのデータが一括で到着する場合を除き)収集データを処理するための未使用の前処理ワーカーが少なくとも1つ存在することになります。
データ収集プロセス(poller、unreachable poller、ODBC poller、HTTP poller、Java poller、pinger、trapper、proxypoller)が多すぎる場合、さらにIPMI manager、SNMP trapper、前処理ワーカーが加わることで、前処理マネージャーに対するプロセスごとのファイルディスクリプタ上限を使い果たす可能性があります。
プロセスごとのファイルディスクリプタ上限を使い果たすと、Zabbixサーバーは停止します。通常は起動直後に発生しますが、場合によってはもう少し時間がかかることもあります。
このような問題を回避するには、Zabbixサーバー設定ファイル を見直し、同時チェック数とプロセス数を最適化してください。
また、必要に応じて、システムの上限を確認および調整し、ファイルディスクリプタ上限が十分に高く設定されていることを確認してください。
値処理パイプライン
アイテムの値処理は、複数のプロセスによって複数のステップ(またはフェーズ)で実行されます。これにより、次のようなことが発生する可能性があります。
- 依存アイテムは値を受信できる一方で、マスター値自体は受信できない場合があります。
これは、次のユースケースで実現できます。
- マスターアイテムの値の型は
UINT(トラッパーアイテムを使用可能)、依存アイテムの値の型はTEXTです。 - マスターアイテムと依存アイテムの両方で、前処理ステップは不要です。
- テキスト値(たとえば "abc")をマスターアイテムに渡します。
- 実行する前処理ステップがないため、前処理マネージャーは、マスターアイテムが NOT SUPPORTED 状態ではなく、かつ値が設定されていることを確認し(どちらも真)、マスターアイテムと同じ値で依存アイテムをキューに入れます(前処理ステップがないため)。
- マスターアイテムと依存アイテムの両方が履歴同期フェーズに到達すると、値変換エラーによりマスターアイテムは NOT SUPPORTED になります(テキストデータは符号なし整数に変換できないため)。
- マスターアイテムの値の型は
その結果、依存アイテムは値を受信しますが、マスターアイテムの状態は NOT SUPPORTED に変わります。
- 依存アイテムが、マスターアイテムの履歴に存在しない値を受信する場合があります。このユースケースは前のものと非常によく似ていますが、異なるのはマスターアイテムの型だけです。たとえば、マスターアイテムに
CHAR型を使用した場合、マスターアイテムの値は履歴同期フェーズで切り詰められますが、依存アイテムはマスターアイテムの初期値(切り詰め前の値)から値を受信します。