Zabbixのダッシュボード表示が遅くて困った時の対処方法を検証してみた

こんにちは。技術部の髙岡です。

ZabbixのダッシュボードのProblemsがいつまで経っても表示されないことがあります。
そんな時にどうすればよいのかを検証してわかったことを書いてみたいと思います。

zabbix_dasbboard1

原因

PostgreSQLとかMariaDBのようなデータベースのeventsテーブルの件数が数百万件のようなレベルで異常に増えてしまい、Zabbixからデータベースに発行されるクエリーに時間を要していることが原因でした。

スロークエリーがログファイルに出力されるようにデータベースを設定すると、Zabbixのダッシュボードを開いた時に以下の例ようなeventsテーブルとevent_recoveryをJOINするSELECT文が、10秒前後とかそれ以上の時間で実行されていることがわかります。

SELECT DISTINCT e.eventid,e.clock,e.ns,e.objectid,e.acknowledged,er1.r_eventid 
FROM events e LEFT JOIN event_recovery er1 ON er1.eventid=e.eventid 
WHERE e.source='0' AND e.object='0' AND e.objectid='17333' AND e.eventid<='10781489' AND e.value='1' 
ORDER BY e.eventid DESC 
LIMIT 20;

eventsテーブルには、

①発生したトリガー(障害発生)の情報
②ディスカバリの情報
③自動登録の情報
④内部イベント

が記録されています。

よくあるのが、①のようなレコードが大量に書き込まれてしまったケースかと思います。
運用開始前のテストで大量にトリガーを起動させてしまったとか、運用開始後に大規模障害が発生してしまった状況で起こりうるケースです。

解決策

そもそも、トリガー(障害)が、何万件も発生していること自体が、監視システムとしては正常ではありませんので、発生する障害を減らすことが監視システムとしての本質的な解決策かと思います。

しかし、このような状況が発生してしまった後でどうすればいいのでしょうか?

上記のSELECT文の実行時間を短縮するための対処が必要です。
Zabbixのようにパッケージソフトウエアから発行されたSQL文を書き換えることができません。
したがって、以下の対策を候補として挙げることができます。

①eventsテーブルの件数を減らす。
②eventsテーブルにインデックスを追加する。
③データベースのパラメータを変更する。
④ハードウェアのリソースを増やす。

①は、ZabbixのHousekeeperの設定でトリガーデータの保存期間を一時的に一日等に短縮することで実現可能です。
尚、eventsテーブルは5つのテーブルから参照制約で参照されているので、他のテーブルのレコードとの関連性が強いテーブルです。
なので、他への影響を考慮すると、eventsテーブルを直接deleteしたり、truncateしたりすることは個人的にはやりたくないと思っています。Zabbixのハウスキーピングを活用したデータ削除が無難かと。

しかし、運用開始済みで、監視履歴を保存する期間が例えば180日等で決まっており、Housekeeperを活用して一時的にでも保管期間を減らすことが運用上できない場合は、②、③、④のような対処が有効かと思います。

細かい話は抜きにして、検証した対処方法だけを先に書きます。
PostgreSQLだけに適用できる方法です。
尚、この方法を実践することによって発生したあらゆる不具合、不都合ついては一切の責任を負いません。

eventsテーブルへのインデックスを追加する。

zabbix=# create index event_4_add on events (source,object,objectid,eventid,value);

マシンのCPU個数を増やして、パラレルクエリーのプロセス数を増やす。

/db作成ディレクトリ/postgresql.conf の変更
(CPUの個数を20に増やした例)

max_worker_processes = 20               # (change requires restart)
max_parallel_workers_per_gather = 15    # taken from max_parallel_workers
max_parallel_workers = 15               # maximum number of max_worker_processes that

SELECT文の実行計画でパラレルクエリーが適用されるようにevnetsテーブルとevent_recoveryテーブルへのparallel workersの数を設定

zabbix=# alter table events set (parallel_workers=15) ;
zabbix=# alter table event_recovery set (parallel_workers=15) ;

これで、SELECT文の実行時間を10秒前後やそれ以上の時間から3秒位に短縮できました。
ZabbixのダッシュボードのProblemsも、いつまで経っても表示されないのが、数秒で表示されるようになりました。

zabbix_dasbboard2

SELECT文の実行計画を見て、遅いフェーズを早くする手段を考えた末に選択した手段です。
実行計画の解析の詳細は、次回のブログで書きますが、Zabbixの話というよりも、もはやMariaDBとPostgreSQLのチューニングの話となってしまう予定です。

ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

1人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です