BLOG
2017 年 08 月 01 日
Zabbix 3.2以降の新機能解説(Zabbix 4.0を見据えて) その2 - Escalatorプロセスの複数起動
こんにちは、MIRACLE ZBX サポートを担当している花島タケシです。 Zabbix 3.4 で追加された機能として、Alerter プロセスが複数起動できるようになります。 本ドキュメントでは、Zabbix 3.0 において、その前段階である Escalator プロセスが既に複数起動するように修正されていますので、この点について解説を行います。
概要
Zabbix 3.4 で新しく追加された機能として、Alerter プロセスも複数起動できるようになります。
Zabbix 3.0 では、その前段階である Escalator プロセスが既に複数起動するように修正されています。
今回は Escalator プロセスが複数起動できるようになった点について解説を行います。
なぜ Escalator プロセスが複数起動できるようになった ( した ) のか?
Zabbix で監視を行っていて問題となることに、監視対象のログに一時的に大量の出力されることがあります。これが発生した場合、Zabbix エージェントは、そのログを読み込み送信を行いますが、大変な負荷がかかることにあります。
同様に、Zabbix サーバも負荷も大変なことになります。Zabbix サーバ側の処理としては、Trapper プロセスがデータを受け取り、キャッシュへ保存します。
DB Syncer プロセスがキャッシュから DB への書き出しを行い、その過程においてトリガー評価等も行います。Trapper, DB Syncer は既に複数起動できるようになっており、並列化を行うことができます。
Escalator プロセスは何をしている?
Escalator プロセスは、escalations テーブルに書き込まれたデータを検知し、それぞれにデータに対してメッセージを整形した後に、alerts テーブルへアラート送信のためのデータを加えることになります。
この「データ」は、「実行内容のタイプ」が「メッセージの送信」であろうと、「リモートコマンド」であろうと変わらず ( 当然データの中身は変わりますが )、Escalator プロセス自体がアラートメールの送信やコマンド実行をすることはありません。
各プロセスの連携については次回で説明します。
並列化された実装を見ていこう!
並列化については下記にて行われています。
https://support.zabbix.com/browse/ZBXNEXT-2844
並列度を指定する StartEscalators パラメータが zabbix_server.conf に追加されています。
また、Escalator プロセスに関するソースコードは、src/zabbix_server/escalator/escalator.c となります。
この機能追加で主だった修正は以下の通りです。
@@ -1426,10 +1432,44 @@
zbx_vector_uint64_create(&escalationids);
sql = zbx_malloc(sql, sql_alloc);
+ switch (escalation_source)
+ {
+ case ZBX_ESCALATION_SOURCE_TRIGGER:
+ zbx_strcpy_alloc(&filter, &filter_alloc, &filter_offset, "triggerid is not null");
+ if (1 < CONFIG_ESCALATOR_FORKS)
+ {
+ zbx_snprintf_alloc(&filter, &filter_alloc, &filter_offset,
+ " and " ZBX_SQL_MOD(triggerid, %d) "=%d",
+ CONFIG_ESCALATOR_FORKS, process_num - 1);
+ }
+ break;
+ case ZBX_ESCALATION_SOURCE_ITEM:
+ zbx_strcpy_alloc(&filter, &filter_alloc, &filter_offset, "itemid is not null");
+ if (1 < CONFIG_ESCALATOR_FORKS)
+ {
+ zbx_snprintf_alloc(&filter, &filter_alloc, &filter_offset,
+ " and " ZBX_SQL_MOD(itemid, %d) "=%d",
+ CONFIG_ESCALATOR_FORKS, process_num - 1);
+ }
+ break;
+ case ZBX_ESCALATION_SOURCE_DEFAULT:
+ zbx_strcpy_alloc(&filter, &filter_alloc, &filter_offset,
+ "triggerid is null and itemid is null");
+ if (1 < CONFIG_ESCALATOR_FORKS)
+ {
+ zbx_snprintf_alloc(&filter, &filter_alloc, &filter_offset,
+ " and " ZBX_SQL_MOD(escalationid, %d) "=%d",
+ CONFIG_ESCALATOR_FORKS, process_num - 1);
+ }
+ break;
+ }
+
result = DBselect(
"select escalationid,actionid,triggerid,eventid,r_eventid,nextcheck,esc_step,status,itemid"
" from escalations"
- " order by actionid,triggerid,itemid,escalationid");
+ " where %s"
+ " order by actionid,triggerid,itemid,escalationid",
+ filter);
*nextcheck = now + CONFIG_ESCALATOR_FREQUENCY;
memset(&escalation, 0, sizeof(escalation));
@@ -1648,12 +1689,16 @@
...
sec = zbx_time();
- escalations_count += process_escalations(time(NULL), &nextcheck);
+ escalations_count += process_escalations(time(NULL), &nextcheck, ZBX_ESCALATION_SOURCE_TRIGGER);
+ escalations_count += process_escalations(time(NULL), &nextcheck, ZBX_ESCALATION_SOURCE_ITEM);
+ escalations_count += process_escalations(time(NULL), &nextcheck, ZBX_ESCALATION_SOURCE_DEFAULT);
+
total_sec += zbx_time() - sec;
sleeptime = calculate_sleeptime(nextcheck, CONFIG_ESCALATOR_FREQUENCY);
二番目の修正は、Escalator プロセスのメインの関数内のループ内に記述されています。
( こういったデーモンでは、無限ループが存在し処理を繰り返す実装になっています。)
今まではシングルプロセスで処理していたため process_escalations() を対象を明確にせずにコールしていましたが、マルチプロセス対応にするために対象を、トリガー、アイテム、その他と明確にしてコールするように変更されていることがわかります。
一番目の修正が、上述の process_escalations() への修正となります。マルチプロセス対応となったにも関わらず、変更が大変少ないことが分かります。実際は関数定義も変更されていますが、そこは割愛します。
呼び出元で対象を明示していましたが、ここではその対象ごとの処理が加わっています。
処理対象となるデータを escalations テーブルから抽出するのですが、対象ごとに条件を加えています。特に Escalator プロセスの数を複数にした場合、
mod(triggerid, Escalator プロセスの総数 )=(Escalator プロセスの番号 -1)
というような条件を付与しています。(Escalator プロセスの番号は 1 から始まります。)
この剰余を用いた割り振りにより、簡素に処理の並列化を実現しています。
escalators テーブルに先に挿入されたデータを優先的に処理を行うといった機構の場合、一回に処理を行う最大量、escalators テーブルへ新しいカラムの追加、ロックの新設といった設計の追加が必要となりますが、必要なくなっています。
ただし、同じ triggerid からのエスカレーションが急激に増えた場合、若しくは特定の triggerid からのエスカレーション頻度が高い場合にバランシングが行えません。
上述のことと矛盾しますが、監視対象のログに急激に出力がされた場合 ( さらに、こういった場合、同じ出力が継続します。)、その出力に関するトリガーは同一のものです。
しかしながら、以前のようにシングルプロセスである場合、他のアラートが全く処理されなくなるのでましとは言えますが。
以上、今回は Escalator プロセスの並列化を説明しました。
次回は Alerter プロセスについて解説を行う予定です。
関連記事
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 1
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 2
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 3
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 4
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 5
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 6
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 7
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 8
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 9
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 10
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 11
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 12
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 13
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 14
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 15
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 16
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 17
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 18
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 19
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 20
Zabbix 3.2 以降の新機能解説(Zabbix 4.0 を見据えて) その 21