7 予測トリガー関数
概要
時には、問題が発生する予兆があることがあります。これらの兆候を発見することで、事前に対策を講じ、問題の影響を防ぐ、
または少なくとも最小限に抑えることができます。
Zabbix は history データに基づいて監視システムの将来の挙動を予測するツールを備えています。
これらのツールは予兆トリガー機能で実現されます。
関数
トリガーを設定する前に、問題状態とは何か、また対応を取るためにどれだけの時間が必要かを定義する必要があります。次に、望ましくない状況が発生する可能性を通知するトリガーを設定する方法は2つあります。1つ目は、「対応までの時間」が経過した時点でシステムが問題状態にあると予想される場合に、トリガーが発生するようにする方法です。2つ目は、システムが「対応までの時間」未満で問題状態に到達すると予想される場合に、トリガーが発生するようにする方法です。対応するトリガー関数は forecast と timeleft です。なお、基礎となる統計分析は、基本的に両方の関数で同一です。ほぼ同様の結果が得られるため、好みに応じてどちらの方法でもトリガーを設定できます。
パラメータ
両方の関数は、ほぼ同じパラメータセットを使用します。参照用に サポートされている関数 の一覧を使用してください。
時間間隔
まず最初に、予測を行うためにZabbixが分析すべき履歴期間を指定する必要があります。これは、time period パラメータと任意のタイムシフトを使用して、avg、count、delta、max、min、sum 関数の場合と同様の、使い慣れた方法で行います。
予測期間
(forecast のみ)
パラメータ time は、履歴データ内で見つかった依存関係を Zabbix が将来のどこまで外挿するかを指定します。time_shift を使用するかどうかにかかわらず、time は常に現在の時点から数えられます。
到達すべきしきい値
(timeleft のみ)
パラメータ threshold は、解析対象のアイテムが到達しなければならない値を指定します。上側から到達するか下側から到達するかは問いません。f(t) を決定したら
(下記参照)、方程式 f(t) = threshold を解き、現在時刻に最も近く、かつ現在時刻より右側にある根を返す必要があります。そのような根が存在しない場合は
1.7976931348623158E+308 を返します。
アイテムの値がしきい値に近づいた後にそれを横切る場合、
timeleft はその交点はすでに過去にあるとみなし、
存在する場合は threshold レベルとの次の交点に切り替えます。
ベストプラクティスとして、予測は通常の障害診断の代替ではなく、
補完として使用することを推奨します。1
近似関数
デフォルトの fit は linear 関数です。ただし、監視対象のシステムが
より複雑な場合は、選択できるオプションがさらにあります。
fit |
x = f(t) |
|---|---|
| linear | x = a + b*t |
| polynomialN2 | x = a~0~ + a~1~*t + a~2~*t2 + ... + a~n~*tn |
| exponential | x = a*exp(b*t) |
| logarithmic | x = a + b*log(t) |
| power | x = a*tb |
モード
(forecast のみ)
トリガー関数が評価されるたびに、指定された履歴期間のデータを取得し、そのデータに指定された関数を当てはめます。したがって、データがわずかに異なれば、当てはめられる関数もわずかに異なります。指定した将来時点における当てはめ関数の値を単純に計算するだけでは、現在からその将来時点までの間に、分析対象のアイテムがどのように振る舞うと予想されるかは分かりません。fit の一部のオプション(polynomial など)では、将来の単純な値は誤解を招く可能性があります。
mode |
forecast の結果 |
|---|---|
| value | f(now + time) |
| max | max~now\ <=\ t\ <=\ now\ +\ time~ f(t) |
| min | min~now\ <=\ t\ <=\ now\ +\ time~ f(t) |
| delta | max - min |
| avg | 定義に従った f(t) の平均値(now <= t <= now + time) |
詳細
非常に大きな数での計算を避けるため、指定期間内の最初の値のタイムスタンプに 1 ns を加えたものを、新しいゼロ時刻とみなします(現在のエポック時刻は 109 のオーダー、エポック時刻の二乗は 1018、倍精度は約 10-16 です)。1 ns を加えるのは、log(t) の計算を含む logarithmic および power 近似において、すべての時刻の値を正の値にするためです。時刻のシフトは、linear、polynomial、exponential には影響しません(計算がより容易かつ高精度になる点を除く)が、logarithmic および power 関数の形状は変化します。
想定されるエラー
このような場合、関数は -1 を返します。
- 指定した評価期間にデータが存在しない場合。
- 数学演算の結果が定義されていない場合3。
- 数値計算上の問題が発生した場合(残念ながら、入力データの一部の組み合わせでは、倍精度浮動小数点形式の範囲と精度では不十分になることがあります)4。
選択した近似が提供されたデータを十分に表現していない場合や、正確な予測を行うにはデータが少なすぎる場合でも、警告やエラーは表示されません。
例とエラーへの対処
ホストの空きディスク容量が不足しそうなときに警告を出すには、次のようなトリガー条件式を使用できます。
timeleft(/host/vfs.fs.size[/,free],1h,0)}<1h
ただし、エラーコード -1 が影響し、トリガーが障害状態になる場合があります。一般的には、これは予測が正しく機能しておらず、その原因を詳しく調べる必要があるという警告になるため、望ましい動作です。しかし場合によっては、-1 は単に直近1時間にホストの空きディスク容量に関するデータが取得されなかったことを意味するだけであり、望ましくないこともあります。誤検知アラートが多すぎる場合は、より複雑なトリガー条件式の使用を検討してください 5:
timeleft(/host/vfs.fs.size[/,free],1h,0)<1h and timeleft(/host/vfs.fs.size[/,free],1h,0)<>-1
forecast の場合は、状況が少し複雑になります。まず、forecast(/host/item,(...))<... のような条件式か、forecast(/host/item,(...))>... のような条件式かによって、-1 がトリガーを障害状態にする場合としない場合があります。
さらに、アイテム値が負になることが通常である場合、-1 は有効な予測値である可能性があります。ただし、実際の運用環境でこのような状況が発生する可能性はごくわずかです(演算子 = の動作については こちら を参照してください)。したがって、-1 を障害として扱いたい場合は ... or forecast(/host/item,(...))=-1 を、障害として扱いたくない場合は ... and forecast(/host/item,(...))<>-1 を追加してください。
脚注
1 例えば、単純なトリガー
timeleft(/host/item,1h,X) < 1h は、アイテム値が X に近づいたときに障害状態になり、その後 X に達すると突然復旧する場合があります。問題がアイテム値が X 未満であることであれば、次を使用してください:
last(/host/item) < X or timeleft(/host/item,1h,X) < 1h 問題がアイテム値が X を超えることであれば、次を使用してください:
last(/host/item) > X or timeleft(/host/item,1h,X) < 1h
2 多項式の次数は 1 から 6 まで指定でき、polynomial1 は linear と同等です。ただし、高次の多項式は 注意して 使用してください。評価期間に多項式係数を決定するのに必要な点数より少ないデータ点しか含まれていない場合、多項式の次数は下げられます(例えば polynomial5 が要求されても、点が 4 つしかない場合は polynomial3 が当てはめられます)。
3 例えば、exponential や power 関数の当てはめでは、アイテム値の log() を計算します。データに 0 や負の数が含まれている場合、log() は正の値に対してのみ定義されているため、エラーになります。
4 linear、exponential、logarithmic、power の当てはめでは、必要な計算はすべて明示的に記述できます。polynomial では、追加の手順なしで計算できるのは value のみです。avg の計算では、多項式の原始関数を(解析的に)求める必要があります。max、min、delta の計算では、多項式の導関数を(解析的に)求め、その根を(数値的に)見つける必要があります。f(t) = 0 を解くには、多項式の根を(数値的に)求める必要があります。
5 ただしこの場合、-1 によってトリガーが障害状態から復旧してしまう可能性があります。完全に防ぐには、次を使用してください:
timeleft(/host/vfs.fs.size[/,free],1h,0)<1h and ({TRIGGER.VALUE}=0 and timeleft(/host/vfs.fs.size[/,free],1h,0)<>-1 or {TRIGGER.VALUE}=1)