2.2 データフローとプロセス
Zabbix内部でのデータ収集から処理、通知までの流れ
データフロー概要
Zabbixでは、監視データが複数の段階を経て処理されます。データ収集から最終的な通知配信まで、各プロセスが協調動作して効率的な監視システムを実現しています。
全体的なデータフロー
[監視対象] → [データ収集] → [データ処理] → [トリガー評価] → [アクション実行] → [通知配信]
データフローの主要段階
- データ収集プロセス: 監視対象からの生データ取得
- データ処理とバリデーション: 収集データの変換・検証
- データ保存: 履歴・トレンドデータの永続化
- トリガー評価サイクル: 問題検知の論理評価
- イベント生成と管理: 状態変化の記録
- アクション実行: 自動対応の発動
- 通知配信の流れ: ユーザーへの情報伝達
データ収集プロセス
収集方式の分類
Zabbixは多様なデータ収集方式をサポートし、それぞれ異なるデータフローを持ちます。
アクティブ収集(Pull型)
Zabbix Server → [要求] → 監視対象
Zabbix Server ← [データ] ← 監視対象
特徴:
- サーバーが能動的にデータを要求
- 定期間隔での収集
- ファイアウォール設定が容易
パッシブ収集(Push型)
監視対象 → [データ送信] → Zabbix Server
特徴:
- 監視対象が能動的にデータを送信
- NAT/プロキシ環境で有効
- リアルタイム性が高い
データ収集の詳細プロセス
1. Zabbix Agentによる収集
アクティブエージェント
パッシブエージェント
2. SNMPによる収集
SNMP設定例
yaml
# SNMPアイテム設定
アイテム名: インターフェース受信バイト数
タイプ: SNMPv2 agent
キー: if.in.bytes[1]
SNMP OID: 1.3.6.1.2.1.2.2.1.10.1
コミュニティ: public
更新間隔: 60秒
3. 外部チェックによる収集
bash
#!/bin/bash
# 外部チェックスクリプト例: Webサービス応答時間
URL=$1
TIMEOUT=10
start_time=$(date +%s.%N)
response=$(curl -s -w "%{http_code}" -m $TIMEOUT "$URL" -o /dev/null)
end_time=$(date +%s.%N)
if [ "$response" = "200" ]; then
response_time=$(echo "$end_time - $start_time" | bc)
echo $response_time
else
echo "0"
fi
データ収集頻度の制御
更新間隔の設定原則
監視対象 | 推奨間隔 | 理由 |
---|---|---|
CPU使用率 | 60秒 | 短期変動の把握 |
メモリ使用量 | 60秒 | リソース枯渇の早期検知 |
ディスク使用量 | 300秒 | 変化が緩やか |
ネットワークトラフィック | 60秒 | トラフィック変動の監視 |
プロセス数 | 120秒 | サービス状態の確認 |
Webサービス応答 | 30秒 | ユーザー体験の監視 |
動的間隔調整
sql
-- フレキシブル間隔設定例
UPDATE intervals:
- 1-600: 60秒間隔で収集
- 600-3600: 300秒間隔で収集
- 3600-: 600秒間隔で収集
データ処理と保存
データの前処理
**前処理(Preprocessing)**では、収集した生データを分析・表示に適した形式に変換します。
前処理ステップの種類
1. 値の変換
javascript
// 数値変換の例
入力値: "75.5%"
変換ルール: 正規表現 \d+\.?\d*
出力値: 75.5
// 単位変換の例
入力値: 1048576 (バイト)
変換ルール: 乗算 0.000001
出力値: 1.048576 (MB)
2. JSONPath抽出
json
// 入力JSON
{
"system": {
"cpu": {
"usage": 45.6,
"temperature": 65.2
}
}
}
// JSONPath: $.system.cpu.usage
// 出力: 45.6
3. 正規表現処理
bash
# ログからエラー数を抽出
入力: "[2024-01-15 14:30:25] ERROR: Database connection failed"
正規表現: ERROR
処理: カウント
出力: エラー発生の場合1、なければ0
4. 差分計算
# カウンターの差分(レート計算)
前回値: 1,250,000
現在値: 1,280,000
時間差: 60秒
レート: (1,280,000 - 1,250,000) / 60 = 500/秒
データ保存機構
履歴データ(History)
生の監視データをリアルタイムで保存
sql
-- history_uint テーブル構造
CREATE TABLE history_uint (
itemid BIGINT UNSIGNED NOT NULL,
clock INT NOT NULL,
value BIGINT UNSIGNED NOT NULL,
ns INT NOT NULL,
INDEX (itemid, clock)
);
-- データ例
INSERT INTO history_uint VALUES
(23001, 1705395025, 45, 123456789), -- CPU使用率: 45%
(23002, 1705395025, 1024, 987654321); -- メモリ使用量: 1024MB
トレンドデータ(Trends)
履歴データから計算された統計値
sql
-- trends_uint テーブル構造
CREATE TABLE trends_uint (
itemid BIGINT UNSIGNED NOT NULL,
clock INT NOT NULL,
num INT NOT NULL,
value_min BIGINT UNSIGNED NOT NULL,
value_avg BIGINT UNSIGNED NOT NULL,
value_max BIGINT UNSIGNED NOT NULL,
PRIMARY KEY (itemid, clock)
);
-- 1時間毎の統計データ例
INSERT INTO trends_uint VALUES
(23001, 1705392000, 60, 20, 45, 85); -- CPU: 最小20%, 平均45%, 最大85%
データベース最適化
パーティショニング戦略
時系列パーティショニング
sql
-- MySQL パーティショニング例
ALTER TABLE history_uint PARTITION BY RANGE (clock) (
PARTITION p2024_01 VALUES LESS THAN (UNIX_TIMESTAMP('2024-02-01 00:00:00')),
PARTITION p2024_02 VALUES LESS THAN (UNIX_TIMESTAMP('2024-03-01 00:00:00')),
PARTITION p2024_03 VALUES LESS THAN (UNIX_TIMESTAMP('2024-04-01 00:00:00'))
);
自動パーティション管理
bash
#!/bin/bash
# パーティション自動作成スクリプト
MYSQL_CMD="mysql -uzabbix -ppassword zabbix"
# 来月のパーティション作成
NEXT_MONTH=$(date -d "next month" +%Y-%m-01)
NEXT_MONTH_TIMESTAMP=$(date -d "$NEXT_MONTH" +%s)
$MYSQL_CMD -e "
ALTER TABLE history_uint ADD PARTITION (
PARTITION p$(date -d "$NEXT_MONTH" +%Y_%m)
VALUES LESS THAN ($NEXT_MONTH_TIMESTAMP)
);"
インデックス最適化
sql
-- 重要なインデックス設定
CREATE INDEX idx_history_itemid_clock ON history_uint (itemid, clock);
CREATE INDEX idx_trends_itemid_clock ON trends_uint (itemid, clock);
-- 複合インデックスの例
CREATE INDEX idx_events_source_object_clock
ON events (source, object, objectid, clock);
データ保持ポリシー
Housekeeping プロセス
Zabbixの自動データ削除機能:
sql
-- データ保持設定例
履歴データ保持期間:
- 数値データ: 30日
- 文字列データ: 7日
- ログデータ: 7日
トレンドデータ保持期間:
- 統計データ: 365日
カスタム保持ポリシー
sql
-- 重要度別保持戦略
-- 重要メトリクス: 90日保持
UPDATE items SET history='90d'
WHERE key_ IN ('system.cpu.util', 'vm.memory.util');
-- 一般メトリクス: 30日保持
UPDATE items SET history='30d'
WHERE history='90d' IS FALSE;
-- ログデータ: 7日保持
UPDATE items SET history='7d'
WHERE value_type IN (1,4); -- 文字列、ログ
トリガー評価サイクル
トリガー評価プロセス
Zabbixサーバーは継続的にトリガー条件を評価し、問題状況を判定します。
評価サイクルの流れ
トリガー評価の詳細
1. データ依存関係の解決
sql
-- アイテム23001(CPU使用率)の新しい値を受信
INSERT INTO history_uint VALUES (23001, 1705395085, 88, 0);
-- 関連するトリガーを特定
SELECT triggerid, expression
FROM triggers
WHERE expression LIKE '%23001%'
AND status = 0; -- 有効なトリガーのみ
2. トリガー式の計算
javascript
// トリガー式例: {host:item.key.func(param)} > threshold
// 実際の評価: {web-server-01:system.cpu.util.avg(5m)} > 80
// ステップ1: データ取得
last_5min_values = [75, 78, 82, 85, 88]; // 5分間の値
// ステップ2: 関数計算
avg_value = (75 + 78 + 82 + 85 + 88) / 5 = 81.6;
// ステップ3: 条件評価
result = (81.6 > 80) = true; // 問題状態
3. 状態変化の判定
sql
-- 現在のトリガー状態確認
SELECT value FROM triggers WHERE triggerid = 17001;
-- 0 = OK, 1 = PROBLEM
-- 状態変化の記録
IF (previous_state != current_state) THEN
INSERT INTO events (eventid, source, object, objectid, clock, value)
VALUES (nextval, 0, 0, 17001, 1705395085, 1);
END IF;
複雑なトリガー条件
複数条件の組み合わせ
sql
-- CPU高負荷 AND メモリ不足
{web-server-01:system.cpu.util.avg(5m)} > 80
AND
{web-server-01:vm.memory.util[available].last()} < 20
-- 評価プロセス:
-- 1. CPU平均値計算: 81.6% > 80% = true
-- 2. メモリ使用率確認: 15% < 20% = true
-- 3. 論理AND: true AND true = true (問題発生)
時間ベースの条件
sql
-- 継続的な高負荷(短期・中期両方)
{web-server-01:system.cpu.util.avg(5m)} > 90
AND
{web-server-01:system.cpu.util.avg(30m)} > 80
-- 時間窓での比較
{web-server-01:net.if.in[eth0].diff()} >
{web-server-01:net.if.in[eth0].avg(1h)} * 2
依存関係を考慮した評価
sql
-- ネットワーク依存関係
-- 親ルーターが停止している場合、子デバイスの障害は無視
UPDATE triggers SET status = 2 -- 依存状態
WHERE triggerid IN (
SELECT dependent_triggerid
FROM trigger_depends
WHERE triggerid = 15001 -- 親ルーターのトリガー
)
AND EXISTS (
SELECT 1 FROM triggers
WHERE triggerid = 15001 AND value = 1 -- 親が問題状態
);
イベント生成と管理
イベントライフサイクル
イベントは、システム内で発生する重要な出来事を記録する仕組みです。
イベントの種類
イベントタイプ | 説明 | 例 |
---|---|---|
トリガーイベント | 問題の発生・解決 | CPU使用率アラート |
ディスカバリイベント | デバイス発見・消失 | 新サーバー検出 |
自動登録イベント | エージェント登録 | 新エージェント追加 |
内部イベント | システム内部状態 | アイテム無効化 |
イベント生成プロセス
sql
-- イベントテーブル構造
CREATE TABLE events (
eventid BIGINT UNSIGNED NOT NULL,
source INT NOT NULL, -- イベントソース
object INT NOT NULL, -- オブジェクトタイプ
objectid BIGINT UNSIGNED NOT NULL, -- オブジェクトID
clock INT NOT NULL, -- 発生時刻
value INT NOT NULL, -- イベント値
acknowledged INT NOT NULL DEFAULT 0, -- 確認状態
severity INT NOT NULL DEFAULT 0, -- 深刻度
PRIMARY KEY (eventid)
);
-- トリガーイベント生成例
INSERT INTO events (
eventid, source, object, objectid, clock, value, severity
) VALUES (
500001, 0, 0, 17001, 1705395085, 1, 4
);
-- CPU高負荷問題発生(深刻度:重度)
イベント確認(Acknowledgment)
確認プロセス
sql
-- イベント確認の記録
UPDATE events SET acknowledged = 1
WHERE eventid = 500001;
INSERT INTO acknowledges (
acknowledgeid, userid, eventid, clock, message, action
) VALUES (
1001, 5, 500001, 1705395200, 'CPU負荷調査中。Apache再起動予定。', 6
);
確認アクション
javascript
// 確認時の自動アクション例
確認操作 → {
"message": "調査開始",
"actions": [
"重要度変更: 軽度に下調整",
"エスカレーション停止",
"関係者通知: 対応開始"
]
}
イベント相関分析
関連イベントの特定
sql
-- 同時期の関連イベント検索
SELECT e1.objectid, t.description, e1.clock
FROM events e1
JOIN triggers t ON e1.objectid = t.triggerid
WHERE e1.clock BETWEEN 1705395000 AND 1705395300 -- 5分間
AND e1.value = 1 -- 問題イベントのみ
ORDER BY e1.clock;
-- 結果例:
-- CPU高負荷 (14:30:25)
-- メモリ不足 (14:30:45)
-- 応答時間遅延 (14:31:10)
イベント統計
sql
-- 日次イベント統計
SELECT
DATE(FROM_UNIXTIME(clock)) as date,
COUNT(*) as total_events,
SUM(CASE WHEN value = 1 THEN 1 ELSE 0 END) as problems,
SUM(CASE WHEN value = 0 THEN 1 ELSE 0 END) as recoveries
FROM events
WHERE source = 0 -- トリガーイベント
GROUP BY DATE(FROM_UNIXTIME(clock))
ORDER BY date DESC;
アクション実行
アクション評価プロセス
イベント発生時、Zabbixは定義されたアクションを評価・実行します。
アクション実行の流れ
アクション条件の評価
sql
-- アクション条件設定例
アクション名: "重要サーバー障害対応"
条件:
- ホストグループ = "本番サーバー"
- 深刻度 >= "重度"
- タグ = "critical:yes"
- 時間 = 平日 9:00-18:00
-- SQL評価クエリ
SELECT actionid FROM actions a
WHERE a.status = 0 -- 有効
AND EXISTS (
SELECT 1 FROM conditions c
WHERE c.actionid = a.actionid
AND c.conditiontype = 0 -- ホストグループ条件
AND c.value = '本番サーバー'
)
AND eventid = 500001;
通知システム
通知メディアタイプ
1. 電子メール
php
// メール設定例
SMTP サーバー: smtp.company.com
ポート: 587
セキュリティ: STARTTLS
認証: 有効
ユーザー名: monitoring@company.com
パスワード: ********
// メッセージテンプレート
件名: 【{EVENT.SEVERITY}】{EVENT.NAME}
本文:
発生時刻: {EVENT.DATE} {EVENT.TIME}
ホスト: {HOST.NAME}
問題: {EVENT.NAME}
現在値: {ITEM.LASTVALUE}
詳細: {EVENT.URL}
2. SMS通知
yaml
プロバイダー: Twilio
設定:
account_sid: ACxxxxxxxxxxxx
auth_token: xxxxxxxxxx
from_number: +81-90-1234-5678
メッセージ例:
"【重度】web-server-01でCPU高負荷発生 85% at 14:30"
3. Webhook統合
json
// Slack Webhook例
{
"url": "https://hooks.slack.com/services/xxx/yyy/zzz",
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"body": {
"channel": "#alerts",
"username": "Zabbix",
"text": "🚨 *{EVENT.SEVERITY}*: {EVENT.NAME}",
"attachments": [{
"color": "danger",
"fields": [{
"title": "Host",
"value": "{HOST.NAME}",
"short": true
}, {
"title": "Time",
"value": "{EVENT.DATE} {EVENT.TIME}",
"short": true
}]
}]
}
}
エスカレーション管理
sql
-- エスカレーション設定例
CREATE TABLE escalations (
escalationid BIGINT UNSIGNED NOT NULL,
actionid BIGINT UNSIGNED NOT NULL,
eventid BIGINT UNSIGNED NOT NULL,
r_eventid BIGINT UNSIGNED NULL,
nextcheck INT NOT NULL,
esc_step INT NOT NULL,
status INT NOT NULL DEFAULT 0,
PRIMARY KEY (escalationid)
);
-- エスカレーション実行例
ステップ0 (即座): 担当者にメール
ステップ1 (15分後): 担当者にSMS + 上司にメール
ステップ2 (30分後): チーム全体にSlack通知
ステップ3 (60分後): 管理職にSMS + 電話
リモートコマンド実行
セキュアなコマンド実行
bash
# エージェント側設定(zabbix_agentd.conf)
EnableRemoteCommands=1
AllowedUsers=zabbix,root
LogRemoteCommands=1
# ユーザーパラメータ定義
UserParameter=service.restart[*],sudo systemctl restart $1
UserParameter=log.collect[*],sudo tar czf /tmp/logs_$(date +%Y%m%d_%H%M%S).tar.gz $1
コマンド実行例
sql
-- アクションでのコマンド設定
操作タイプ: リモートコマンド
対象: 現在のホスト
コマンド: systemctl restart httpd
実行方法: SSH
ユーザー名: zabbix
認証方式: パスワード/キー
bash
# 実行ログ例
[2024-01-15 14:35:00] リモートコマンド実行開始
[2024-01-15 14:35:00] ホスト: web-server-01
[2024-01-15 14:35:00] コマンド: systemctl restart httpd
[2024-01-15 14:35:05] 実行完了 (終了コード: 0)
[2024-01-15 14:35:05] 出力: Job for httpd.service done.
通知配信の流れ
通知プロセスの最適化
バッチ処理による効率化
sql
-- 通知キュー管理
CREATE TABLE alert_queue (
alertid BIGINT UNSIGNED NOT NULL,
actionid BIGINT UNSIGNED NOT NULL,
eventid BIGINT UNSIGNED NOT NULL,
userid BIGINT UNSIGNED NOT NULL,
message TEXT NOT NULL,
subject VARCHAR(255) NOT NULL,
sendto VARCHAR(255) NOT NULL,
status INT NOT NULL DEFAULT 0,
retries INT NOT NULL DEFAULT 0,
PRIMARY KEY (alertid)
);
-- バッチ送信処理
SELECT * FROM alert_queue
WHERE status = 0 -- 未送信
ORDER BY alertid
LIMIT 100; -- 100件ずつ処理
重複排除とグルーピング
javascript
// 通知グルーピング例
グループ化条件: {
"time_window": "5分",
"group_by": ["host", "severity"],
"threshold": 3
}
結果: {
"original_alerts": 15,
"grouped_message": "web-server-01で重度の問題が5分間に15件発生",
"details": ["CPU高負荷", "メモリ不足", "ディスク I/O遅延", "..."]
}
配信状態の追跡
sql
-- 配信ログ記録
INSERT INTO alerts (
alertid, actionid, eventid, userid, clock,
mediatypeid, sendto, subject, message, status
) VALUES (
10001, 3, 500001, 5, 1705395300,
1, '[email protected]', '【重度】CPU高負荷', '...', 1
);
-- 配信統計
SELECT
mediatypeid,
COUNT(*) as total_alerts,
SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) as sent,
SUM(CASE WHEN status = 0 THEN 1 ELSE 0 END) as failed,
AVG(CASE WHEN status = 1 THEN 1.0 ELSE 0.0 END) as success_rate
FROM alerts
WHERE clock > UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 24 HOUR))
GROUP BY mediatypeid;
パフォーマンス最適化
データフロー最適化のポイント
1. データ収集の最適化
conf
# zabbix_server.conf パフォーマンス設定
StartPollers=30 # ポーラープロセス数増加
StartTrappers=15 # トラッパープロセス数増加
StartPingers=5 # Pingerプロセス数調整
CacheSize=256M # キャッシュサイズ増加
HistoryCacheSize=128M # 履歴キャッシュ拡大
ValueCacheSize=512M # 値キャッシュ拡大
2. データベース最適化
sql
-- MySQL最適化設定
SET GLOBAL innodb_buffer_pool_size = 2G;
SET GLOBAL innodb_log_file_size = 256M;
SET GLOBAL innodb_flush_log_at_trx_commit = 2;
SET GLOBAL sync_binlog = 0;
-- インデックス最適化
ANALYZE TABLE history_uint;
OPTIMIZE TABLE trends_uint;
3. ネットワーク最適化
yaml
# プロキシ経由での最適化
構成:
- 本社: Zabbix Server (1台)
- 各拠点: Zabbix Proxy (各1台)
- 監視対象: 各拠点内ローカル通信
効果:
- WAN トラフィック 90% 削減
- レスポンス時間 70% 改善
- 通信断耐性の向上
まとめ
Zabbixのデータフローとプロセスは、以下の特徴により高効率な監視を実現します:
データフローの強み
- 多様な収集方式: エージェント、SNMP、外部チェックの統合
- リアルタイム処理: 効率的なトリガー評価システム
- スケーラブルな構成: プロキシによる分散処理
- 自動化された対応: アクション・通知の自動実行
運用上の考慮事項
- データ保持戦略: 効率的なストレージ利用
- パフォーマンス調整: 負荷分散と最適化
- 通知管理: 適切なエスカレーション設計
- セキュリティ: 安全なリモートコマンド実行
次のセクションでは、大規模・分散環境でのZabbix展開について、分散監視環境の詳細を説明します。
参考リンク