障害ノードが一時的に正常と認識されることがあります

Forumにはいつもお世話になっております。

CentOS5.3上のZABBIX1.4.6-1で、シンプルチェック:icmpを使用して監視しているノードがあります。
{ノード:icmpping.count(320,0)}>4&{ノード:icmpping.last(0)}=0 というトリガーにて、障害を判定しています。

この判定で障害状態となっているノードが、一時的に正常と認識される場合が有ります。
ZABBIXサーバーの再起動後と、ある程度障害状態が継続した場合です。

countに関して1.4JPのマニュアルには、下記のように記載されています。
「期間内(秒単位)に正常に値を取得した回数を返します。
 例) count(600,12)はヒストリに保存されている値のうち「12」の出現回数を返します。」

これから考えると、ZABBIXサーバーを停止や再起動をしている時間中はデータを収集できないため、起動後にcount(320,0)でチェックすると障害状態が少ないため正常と判断される、ということでしょうか?

ある程度障害状態が継続した場合に関しては、ステータスが障害のまま数日(長い時は百数十日)経過後に正常となり、6分超で再度障害となります。
正常から障害になるのは、トリガーは正常に稼動しているからと考えます。

最新データからグラフを確認しても、その期間はicmp応答が無い状態だけしか有りません。
障害状態のノードは複数あるのですが、同時に障害から正常になっています。

この現象が発生するのは02:03頃ですが、毎日02:00からmysqldumpを実行しています。
ZABBIXサーバーの負荷はかなりのものですが、トリガーが正常になるのは毎日ではないため関係性は少ないと考えます。

何が原因でステータスが障害から正常に移行しているのでしょうか?

何か情報がありましたら教えていただけますか。

宜しく御願致します。

コメント表示オプション

お好みのコメント表示方法を選び「設定の保存」をクリックすると変更が反映されます。
ユーザー KAZ の写真

mikoさん

れから考えると、ZABBIXサーバーを停止や再起動をしている時間中はデータを収集できないため、起動後にcount(320,0)でチェックすると障害状態が少ないため正常と判断される、ということでしょうか?

指摘通りかと。

起動してから48回0を計測しないと正常に流れるはずです。
毎日同じ時間に発生すると言うことなので、逃げかも知れませんがtime()を使うと言う手もあります。

下記なら2時00分〜2時10分の間は最新が0だったら障害のまんまかと。
<code>
(({ノード:icmpping.count(320,0).time(0)}<020000)|
{ノード:icmpping.count(320,0).time(0)}>021000))&
{ノード:icmpping.count(320,0)}>4)&
{ノード:icmpping.last(0)}=0
</code>

ユーザー miko の写真

御回答頂き有難うございました。

KAZさんは書きました:
mikoさん

れから考えると、ZABBIXサーバーを停止や再起動をしている時間中はデータを収集できないため、起動後にcount(320,0)でチェックすると障害状態が少ないため正常と判断される、ということでしょうか?

指摘通りかと。

起動してから48回0を計測しないと正常に流れるはずです。

この48回というのは、ZABBIXサーバーが起動した以前の48回分のチェックが0で無い場合に正常になるということでしょうか?
60秒間隔なのチェックなので、判断時間320秒を引いた42分以内にZABBIXサーバーの再起動が完了すれば障害のまま、ということでしょうか?

それとも、ZABBIIXサーバーが起動してからシンプルチェックを48回行ってということでしょうか?
その場合は、相手と通信が出来ないので通常通りトリガーで障害状態を保つはずです。

毎日同じ時間に発生すると言うことなので、逃げかも知れませんがtime()を使うと言う手もあります。

下記なら2時00分〜2時10分の間は最新が0だったら障害のまんまかと。

(({ノード:icmpping.count(320,0).time(0)}<020000)|
{ノード:icmpping.count(320,0).time(0)}>021000))&
{ノード:icmpping.count(320,0)}>4)&
{ノード:icmpping.last(0)}=0

なるほど、時間を条件に組み込むわけですか。

ただこのテンプレートは複数のノードで使用しているため、正常に通信が出来ているノードで1回だけ通信が出来なかった場合、多くの障害検知をしてしまうのが問題となります。
比率としては、1対100ぐらいなので、影響が大きいです。

テンプレートを分ければというのも有りますが、この対象となる長期障害ノードが変るため、手間が大きいと思います。

毎日発生していればmysqldumpなど負荷によるものと思うのですが、そうでないのが気になるところです。

宜しく御願致します。

ユーザー kodai の写真

こんにちは。

{host:icmpping.count(320,0)}>4を設定されているので、「ヒストリに保存されている過去320秒以内」に5回以上Ping監視が失敗した場合、ということになります。

Zabbixサーバを再起動したときにトリガーが正常になってしまうのはKAZさんの回答の通りだと思います。[監視データ] -> [最新データ]の画面からヒストリを表示して、過去320秒以内にいくつデータがあるかを見ていただければ確認できると思います。

もうひとつの現象ですが、監視が滞りなく行われているのであれば、60秒間隔で監視を行われているので直近320秒以内には5回監視が行われるということになりますが、MySQLの負荷が高くて監視に時間がかかったり、データの保存に時間がかかったりして監視に遅延が発生すると監視データが5個に満たなくて正常と判断されてしまうのではないかと思います。

count関数をcount(320,0)と秒数指定で設定するのではなく、count(#5,0)とデータの個数指定にすると問題を回避できないでしょうか。

ユーザー miko の写真

御回答頂き有難うございました。

kodaiさんは書きました:
こんにちは。

{host:icmpping.count(320,0)}>4を設定されているので、「ヒストリに保存されている過去320秒以内」に5回以上Ping監視が失敗した場合、ということになります。

Zabbixサーバを再起動したときにトリガーが正常になってしまうのはKAZさんの回答の通りだと思います。[監視データ] -> [最新データ]の画面からヒストリを表示して、過去320秒以内にいくつデータがあるかを見ていただければ確認できると思います。

トリガー条件を工夫して、起動後一定時間内は別条件で判定することで対応できないか、考えてみました。

ZABBIXサーバーuptime {ZABBIX Server:system.uptime.last(0)}と{TRIGGER.VALUE}で、起動後障害状態ならそのまま障害判定する方法です。
ただし、ZABBIXサーバー起動時の{TRIGGER.VALUE}は、ZABBIXサーバー停止時の状態を保持しているかどうかです。
起動時は全て正常状態であれば、この方法が使えません。

もう一つ考えたのは、{ZABBIX Server:system.uptime.last(0)}がシンプルチェック5回未満の時間中は、複数回のチェックでなく1回のチェックで障害判定をすることです。
条件式の容易さはこちらが上なので、こちらのほうがいいのではと考えています。
({ZABBIX Server:system.uptime.last(0)}<400&{ノード:icmpping.last(0)}=0) | ({ノード:icmpping.count(320,0)}>4&{ノード:icmpping.last(0)}=0) 

もうひとつの現象ですが、監視が滞りなく行われているのであれば、60秒間隔で監視を行われているので直近320秒以内には5回監視が行われるということになりますが、MySQLの負荷が高くて監視に時間がかかったり、データの保存に時間がかかったりして監視に遅延が発生すると監視データが5個に満たなくて正常と判断されてしまうのではないかと思います。

count関数をcount(320,0)と秒数指定で設定するのではなく、count(#5,0)とデータの個数指定にすると問題を回避できないでしょうか。

なるほど、countを秒数でなく個数で指定できるのですか。それならば、負荷による遅延が発生しても対応できますね。

ただマニュアルを見たところ、1.4では使えず1.6からの機能のため、バージョンアップが必要ですので検討してみます。

1.6のシステムも運用しているため、こちらは変更して動作を見てみます。

宜しくお願いします。

ユーザー miko の写真

ZABBIXサーバーのuptimeを使用した条件を検証してみました。

もう一つ考えたのは、{ZABBIX Server:system.uptime.last(0)}がシンプルチェック5回未満の時間中は、複数回のチェックでなく1回のチェックで障害判定をすることです。
条件式の容易さはこちらが上なので、こちらのほうがいいのではと考えています。
({ZABBIX Server:system.uptime.last(0)}<400&{ノード:icmpping.last(0)}=0) | ({ノード:icmpping.count(320,0)}>4&{ノード:icmpping.last(0)}=0) 

この条件だと、右側がuptimeに関わらず有効になってしまうので、こちらにもuptime条件をつけました。
({ZABBIX Server:system.uptime.last(0)}<400&{Template_Standalone_icmp:icmpping.last(0)}=0) | ({ZABBIX Server:system.uptime.last(0)}>400&{Template_Standalone_icmp:icmpping.count(320,0)}>4&{Template_Standalone_icmp:icmpping.last(0)}=0)

登録しようとしたところ、1.4でも1.6でも次のエラーとなりました。
Incorrect trigger expression. You can't use template hosts in mixed expressions.

ホストとテンプレートが含まれているとだめなのかと思い、次のようにしましたが、同じエラーとなりました。
({Template_Linux:system.uptime.last(0)}<400&{Template_Standalone_icmp:icmpping.last(0)}=0) | ({Template_Linux:system.uptime.last(0)}>400&{Template_Standalone_icmp:icmpping.count(320,0)}>4&{Template_Standalone_icmp:icmpping.last(0)}=0)

テンプレートでなくホストに対して登録したところ、問題なく登録できました。
({ZABBIX Server:system.uptime.last(0)}<400&{ノード:icmpping.last(0)}=0) | ({ZABBIX Server:system.uptime.last(0)}>400&{ノード:icmpping.count(320,0)}>4&{ノード:icmpping.last(0)}=0)

ただ対象ホストが多いため、テンプレートで設定できないとなると手間が大きすぎるので、別の方法を考える必要が有ります。

ユーザー miko の写真

別の方法で検証をしてみました。

マニュアルを見ると、count関数は時間内に取得できたデータ数を返します。
今まで使用していたのは、そのうちの特定データの数でした。

時間内に取得できたデータ総数を条件に加えることで、総数が少ない場合はicmppingの最新値を、総数が増えた場合はicmppingの特定データの数と最新値を、と分けることが出来ました。

({Template_Standalone_icmp:icmpping.count(320)}<5&{Template_Standalone_icmp:icmpping.last(0)}=0) | ({Template_Standalone_icmp:icmpping.count(320)}>4&{Template_Standalone_icmp:icmpping.count(320,0)}>4&{Template_Standalone_icmp:icmpping.last(0)}=0)

設定は問題なく行えたので、これで再起動などを行ってテストをしてみましたが、以前のトリガーでは不明・正常・障害となりましたが、このトリガーの場合は不明・障害となり、正常・障害のアクションが実行されなくてすむようになりました。