前書き

監視システム(ZabbixやNagiosなど)を使用している場合、監視の仕組みがわかります。 簡単に言うと、次のように説明できます。監視システムは、さまざまなメトリック(CPU /メモリ使用量、ネットワーク使用率など)を受け取ります。 メトリックの1つの値が所定のしきい値を超えるとすぐに、対応するトリガーがアクティブになり、監視システムはメトリックの1つが通常の制限を超えていることを通知します。 通常、各メトリックのしきい値は手動で設定されますが、必ずしも便利ではありません。

このチュートリアルでは、リアルタイムの異常検出システムであるhttps://github.com/etsy/skyline[Skyline]をインストールおよび構成する方法を学習します。 各しきい値を設定または調整することなく、一連のメトリックをリアルタイムで分析できます。 常時監視が必要な多数の時系列(数十万)がある場所で使用するように設計されています。

しきい値トリガー

手動でしきい値を設定する監視システムの例を見てみましょう。 次の図は、CPU負荷のグラフを示しています。 破線はトリガーのしきい値を示します。

image:https://assets.digitalocean.com/articles/skyline_centos7/pic1.png [図1] + *図1 *

図1のポイント1でプロセスが開始され、CPU負荷が大幅に増加しました。 トリガーがアクティブ化され、管理者はそれに気付きます。 管理者は、正常な値の範囲内であると判断し、トリガーのしきい値を上の破線として示されているものに変更します。

しばらくすると、図1のポイント2でトリガーが再び起動されます。 管理者は、2番目のサービスが定期的にバックアップを作成し、負荷が増加していることを発見しました。 次に、問題が発生します。しきい値を高くするか、そのままにしてアラームを無視しますか?

ポイント3を見てみましょう。 その瞬間、イベントの負荷は下がりますが、しきい値を超えていないため、管理者に通知されませんでした。 トリガーが作動しませんでした。

この単純なケースは、しきい値を設定しようとするといくつかの困難があることを示しています。 偽陽性エラーまたは偽陰性エラーを引き起こさずにパフォーマンスの問題をキャッチするためにしきい値を調整することは困難です。

これらの問題を解決するために、* Skyline *が作成されました。 一連のノンパラメトリックアルゴリズムを使用して、異常なメトリックを分類しています。

スカイラインコンポーネント

Skylineは、Horizo​​n Agent、Analyzer Agent、およびWebappのコンポーネントで構成されています。

Horizo​​n Agent

Horizo​​n Agentはデータの収集を担当します。 着信データをリッスンする* Listeners *があります。

pickle(TCP)とhttp://msgpack.org/[MessagePack](UDP)の2つの形式のデータを受け入れます。 着信メトリックを読み取り、それらを* Workers が読み取った共有キューに入れます。 ワーカーはデータをMessagepackにエンコードし、Redisデータベースに追加します。 Horizo​​n Agentは、 Roombas *を使用して古いメトリックを定期的にトリミングおよび削除します。 これを行わないと、すべての空きメモリがすぐに使い果たされます。

分析エージェント

Analyzer Agentは、データの分析を担当します。 Redisからメトリックのリストを受け取り、いくつかのプロセスを実行し、それぞれにメトリックを割り当てます。 各プロセスは、いくつかのアルゴリズムを使用してデータを分析します。 各アルゴリズムは結果を報告します-データが異常であるかどうか。 大半のアルゴリズムが現在のメトリックに異常があると報告した場合、データは「異常」とみなされます。

異常なメトリックはすべてファイルに書き込まれます。 このファイルに基づいて、画像が作成され、Webアプリケーションに表示されます。

Analyzerは、通知を送信することもできます:電子メール、HipChat、またはPagerDuty。 電子メール通知は、この記事の後半で構成されます。

Webapp

Skylineは、異常なメトリックを表示する小さなWebアプリケーションを提供します。 Flaskフレームワークを備えたPythonで書かれたシンプルなウェブアプリです。 上部には、過去1時間と過去1日の2つのグラフが表示されます。 グラフの下には、すべての異常なメトリックのリストがあります。

Redisデータベース

Redisは、オープンソースのキーと値のキャッシュおよびストアデータベースです。

Skylineは、すべてのメトリックとエンコードされた時系列をRedisデータベースに保存します。 データポイントが届くと、Horizo​​nワーカーはスキーマ+ ‘[timestamp、value] + `のデータポイントをMessagePackでエンコードされたバイナリ文字列にパックし、この文字列を適切なメトリックキーに追加します。

_図2_は、スカイラインのコンポーネントの相互作用の図を示しています。

image:https://assets.digitalocean.com/articles/skyline_centos7/pic2.png [図2] + *図2 *

前提条件

Skylineをインストールする前に、次の前提条件をすべて満たす必要があります。

  • CentOS 7ドロップレットを展開します。

  • Initial Server Setupチュートリアルに従って、sudoユーザーを追加します。 このチュートリアルのすべてのコマンドは、この非rootユーザーとして実行する必要があります。

  • https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-centos-7 [スワップスペースの追加]をサーバーに追加します。 4 GBで十分です。

  • Graphiteをインストールし、https://www.digitalocean.com/community/tutorials/how-to-keep-effective-historical-logs-with-graphite-carbon-and-collectd-on-centos-の指示に従って収集します。 7 [グラファイト、カーボン、およびCentOS 7で収集した効果的な履歴ログを保持する方法]チュートリアル。

ステップ1-SkylineとRedisのインストール

Skylineをインストールするには、最初に、いくつかのPython関連ツールとApache Webサーバーを含む必要なアプリケーションをインストールします。

sudo yum install httpd gcc gcc-c++ git pycairo mod_wsgi python-pip python-devel blas-devel lapack-devel libffi-devel

GitHubからSkylineの最新のソースファイルを取得します。

cd /opt
sudo git clone https://github.com/etsy/skyline.git

いくつかの必要なPythonパッケージをインストールします。

cd /opt/skyline
sudo pip install -U six
sudo pip install -r requirements.txt

次のPythonパッケージをこの指定された順序でインストールします。

sudo pip install numpy
sudo pip install scipy
sudo pip install pandas
sudo pip install patsy
sudo pip install statsmodels
sudo pip install msgpack-python

それらのほとんどは、科学技術計算に使用されるオープンソースのPythonライブラリです。 MessagePackデータの読み取りと書き込みには、 `+ msgpack-python +`パッケージが必要です。

サンプルのスカイライン設定ファイルを正しいファイルの場所にコピーします。

sudo cp /opt/skyline/src/settings.py.example /opt/skyline/src/settings.py

次のディレクトリを作成します。

sudo mkdir /var/log/skyline
sudo mkdir /var/run/skyline
sudo mkdir /var/log/redis
sudo mkdir /var/dump/

前述したように、SkylineはすべてのメトリックをRedisデータベースに保存するため、同様にインストールする必要があります。

sudo yum install redis

Redisの詳細については、チュートリアルhttps://www.digitalocean.com/community/tutorials/how-to-install-and-use-redis[Redisのインストールおよび使用方法]を参照してください。

SkylineおよびRedisサービスを開始します。

cd /opt/skyline/bin
sudo redis-server redis.conf
sudo ./horizon.d start
sudo ./analyzer.d start
sudo ./webapp.d start

インストールをテストするには、付属のテストスクリプトを実行します。

python /opt/skyline/utils/seed_data.py

次のような出力が表示されるはずです。

Loading data over UDP via Horizon...
Connecting to Redis...
Congratulations! The data made it in. The Horizon pipeline seems to be working.

Skylineのインストールと基本設定が完了しました。 次に、データを送信する必要があります。

ステップ2-スカイラインへのデータの取得

前述したように、Skylineは2つの形式のデータを受け入れます:https://docs.python.org/2/library/pickle.html[pickle](TCP)およびhttp://msgpack.org/[MessagePack](UDP) 。

好みの監視エージェントに独自のスクリプトまたはモジュールを記述し、分析のためにSkylineに送信されるようにMessagePackでデータをエンコードすることができます。 Skylineは、UDPを介したMessagePackエンコード文字列の形式のメトリックを受け入れます。 MessagePackは、JSONのようなオブジェクトシリアル化仕様です。 形式は、「+ [<メトリック名>、[<タイムスタンプ>、<値>]] + `」です。 MessagePackには、ほとんどのプログラミング言語用のAPIがあります。 詳細とAPIの例は、http://msgpack.org/ [MessagePack公式サイト]にあります。

このチュートリアルでは、Graphiteから収集したデータをSkylineに送信する方法を示します。

グラファイトからデータを取得する

グラファイトはいくつかのコンポーネントで構成されており、そのうちの1つが*カーボンリレー*サービスです。 カーボンリレーは、受信メトリックを冗長性のために別のGraphiteインスタンスに転送します。 そのため、Skylineが実行されているホストにカーボンリレーサービスを向けることができます。

image:https://assets.digitalocean.com/articles/skyline_centos7/graphite_skyline.png [図3] + *図3 *

図3に、データフローの概略図を示します。 外部監視エージェントからのデータ(http://collectd.org/[collectd]、https://github.com/BrightcoveOS/Diamonds[diamond]、https://github.com/etsy/statsd[statsd]など)またはシステム(http://www.nagios.org/[Nagios]、https://www.icinga.org/[Icinga]、http://sensuapp.org/[Sensu]など)がGraphiteに転送されます。 次に、カーボンリレーはデータをSkylineに転送します。 Carbon-relay、carbon-cache、およびSkylineは、単一のホストまたは別のホストで実行できます。

このデータフローを機能させるには、Graphite、collectd、およびSkylineを構成する必要があります。

サンプルの `+ relay-rules.conf +`を以前にcarbon-relay設定ファイルの適切な場所にコピーしなかった場合、ここでそれを行う必要があります。

sudo cp /opt/graphite/conf/relay-rules.conf.example /opt/graphite/conf/relay-rules.conf

編集のために `+ relay-rules.conf +`設定ファイルを開きましょう:

sudo vi /opt/graphite/conf/relay-rules.conf

Skylineホストを宛先のリストに追加します。SkylineホストのIPアドレスは次のとおりです。

/opt/graphite/conf/relay-rules.conf

[default]
default = true
destinations = 127.0.0.1:2004, :2024

`+ relay-rules.conf `で使用されるすべての宛先は、 ` carbon.conf +`設定ファイルでも定義する必要があります。

この変更を行うには、 `+ carbon.conf +`設定ファイルを開きます:

sudo vi /opt/graphite/conf/carbon.conf

次に、「+ [relay] 」セクションを見つけて、「 DESTINATIONS +」行を編集します。

/opt/graphite/conf/carbon.conf

[relay]
...
DESTINATIONS = 127.0.0.1:2004, :2024
...

これらの変更を行ったら、カーボンリレーサービスを開始します。

sudo systemctl start carbon-relay

Graphite-Webへのスカイラインアクセスの許可

https://www.digitalocean.com/community/tutorials/how-to-keep-effective-historical-logs-with-graphite-carbon-and-collectd-on-centos-7 [効果的な履歴ログを保持する方法Graphite、Carbon、CentOS 7で収集]、Graphite Webインターフェイスをパスワードで保護することを選択した場合、Skylineを機能させるには、パスワードなしでlocalhostからのアクセスを許可する必要があります。

これを行うには、グラファイト構成ファイルを編集します。

sudo vi /etc/httpd/conf.d/graphite.conf

`+ <Location> +`ブロックに次の赤の行を追加します。

/etc/httpd/conf.d/graphite.conf

<Location "/">
 AuthType Basic
 AuthName "Private Area"
 AuthUserFile /opt/graphite/secure/.passwd
 Require user sammy




</Location>

次に、Apacheサービスを再起動します。

sudo systemctl restart httpd

収集したデータを取得する

データをSkylineに送信するようにcollectdを構成することもできます。 構成ファイルを開きます。

sudo vi /etc/collectd.conf

`+ <Plugin write_graphite> `ブロックのポート番号を ` 2013 +`に変更します。

/etc/collectd.conf

<Plugin write_graphite>
   . . .
   Port ""
   . . .

次にcollectdを再起動します。

sudo systemctl restart collectd.service

混乱を避けるために、図4は正しいポート番号を使用した簡略化されたスキームを示しています。

image:https://assets.digitalocean.com/articles/skyline_centos7/graphite_skyline_ports.png [図4] + *図4 *

正しいポート番号は次のとおりです。

  1. カーボンリレーは、ポート_2013_で_plaintext_形式の着信データをリッスンします

  2. カーボンリレーは、_pickle_形式でデータを送信します

  3. カーボンキャッシュは、ポート_2004_で_pickle_形式の着信データをリッスンします

  4. Horizo​​n Agentは、ポート_2024_で_pickle_形式の着信データをリッスンします

ステップ3-スカイラインのセットアップ

Skyline構成ファイルには多くの設定が含まれています。 ファイルを編集用に開きます。

sudo vi /opt/skyline/src/settings.py

このファイル内の各設定は、ファイル自体の有益なコメントによって文書化されます。 少なくとも、次のパラメーターを設定して、赤のテキストを自分の値に置き換える必要があります。

  • + GRAPHITE_HOST = '' +

  • + HORIZON_IP = '' +

  • + WEBAPP_IP = '' +

他のオプションはデフォルト値のままにすることができます。 それらは以下のとおりです。

  • + FULL_DURATION +-このオプションは、データをRedisに保存して分析する最大時間を指定します。 分析にかかる時間は長くなりますが、ノイズを減らし、より正確な異常検出を提供できます。 デフォルト値は「86400」秒です。

  • + CARBON_PORT +-このオプションはカーボンポートを指定します。 デフォルト値は「2003」です。

  • + ANALYZER_PROCESSES +-このオプションは、Skylineアナライザーが生成するプロセスの数を指定します。 このパラメーターは、ホスト上のCPUの合計数よりも数少ない数に設定することをお勧めします。 デフォルト値は「5」です。

  • + WORKER_PROCESSES +-このオプションは、Horizo​​nキューから消費するワーカープロセスの数を指定します。 デフォルト値は「2」です。

  • + PICKLE_PORT +-このオプションは、グラファイトのピクルスをリッスンするTCPポートを指定します。 デフォルト値は `+ 2024 +`です。

  • + UDP_PORT +-このオプションは、MessagePackでエンコードされたパケットをリッスンするUDPポートを指定します。 デフォルト値は「2025」です。

  • + WEBAPP_PORT +-このオプションは、Skyline webappのポートを指定します。 デフォルト値は「1500」です。

これらの変更を行った後、対応するアプリを再起動する必要があります。

sudo /opt/skyline/bin/horizon.d restart
sudo /opt/skyline/bin/analyzer.d restart
sudo /opt/skyline/bin/webapp.d restart

次に、リンク「+ http://:1500+」を開き、Skyline Webページを表示できます(図5)。 検出された異常なメトリックが表示されます。

image:https://assets.digitalocean.com/articles/skyline_centos7/skyline_interface.png [図5] + *図5 *

Skylineがフル稼働するためには、「+ FULL_DURATION 」秒が経過するまで待つ必要があります。 デフォルトでは、 ` FULL_DURATION `は1日( ` 86400 +`秒)に設定されています。

異常の追跡を開始するには、少なくとも1時間待つ必要があります。 これにより、Skylineに通常の負荷レベルに関する情報を蓄積する時間が与えられます。 Skylineがベースラインを確立している間、システムに余分な負荷をかけないようにしてください。

手順4-電子メールアラートの有効化

デフォルトでは、Skylineは、検出された異常がまだ発生している間、検出された異常をWebインターフェース( + http://:1500 +)に表示します。 異常が消えるとすぐに、対応するメトリックがこのインターフェースから消えます。 したがって、これらの異常を確認するにはWebページを監視する必要がありますが、これは必ずしも便利ではありません。

メールアラートを設定して、見逃さないようにすることができます。

これを行うには、Skyline構成ファイルを開きます。

sudo vi /opt/skyline/src/settings.py

アラートが有効になっていることを確認します。

/opt/syline/src/settings.py

ENABLE_ALERTS = True

次に、次のALERTSセクションを見つけて、次のスキーマを赤で追加します。

/opt/syline/src/settings.py

ALERTS = (
   (^)("collectd", "smtp", 1800)(^),
)

スキーマの最初の値は、監視するプロセスです。 この場合、それは `+ collectd。`です。スキーマの2番目の値は ` smtp `で、これは電子メールアラートを表します。 「+1800」の最後の値は秒単位です。 これは、トリガーが検出された場合でも、30分(1800秒)以内にアラートが複数回起動しないことを意味します。 この値を変更して、ニーズに最適なスイートにします。

また、次のセクションを見つけて、使用するメールアドレスに合わせて変更します。 メールアラートは、([email protected])から([email protected])アカウントに送信されます。

/opt/syline/src/settings.py

SMTP_OPTS = {
   "sender": "(^)[email protected](^)",
   "recipients": {
       "collectd": ["(^)[email protected](^)"],
   },
}

これらすべての変更を行った後、アナライザーデーモンを再起動する必要があります。

sudo /opt/skyline/bin/analyzer.d restart

ステップ5-スカイラインのテスト

Skylineをテストするには、bashコマンドでCPUスパイクを作成できます。

dd if=/dev/zero of=/dev/null

Ctrlキーを押しながらCキーを押すと、いつでもコマンドを停止できます。 異常を作成するには数分で十分です。

このコマンドの実行中にSkyline Webインターフェイスを見ると、検出された異常が表示されます。 図6に例を示します。

image:https://assets.digitalocean.com/articles/skyline_centos7/skyline_anomalies_list.png [図6] + *図6 *

CPUの負荷が高くなった結果、Skylineのコンポーネントの速度が低下したことがわかります。 検出されたすべての異常なメトリックは、Webページの下部にリストとして表示されます。 いずれかのメトリックの名前にカーソルを合わせると、上のグラフで、過去1時間と1日の対応する時系列が表示されます。 メトリックの名前をクリックして、Graphiteによって生成されたより詳細なグラフを開きます(例については図7を参照)。

image:https://assets.digitalocean.com/articles/skyline_centos7/detail_graph.png [図7] + *図7 *

この例では、CPU負荷が極端に高い値に達しておらず、しきい値を超えていません。 この場合、従来の監視システムでは偏差を見つけることができませんでした。 そのようなケースは以前に言及されました(図1、ポイント3)。

従来の監視システムとは異なり、Skylineは逸脱をすばやく見つけて、それらについて通知します。

ステップ6-アルゴリズムの調整(オプション)

前述したように、Skylineは一連のアルゴリズムを使用して異常を検出しています。 現在、次のアルゴリズムが実装されています。

  • 平均絶対偏差

  • グラブスのテスト

  • 最初の1時間の平均

  • 平均からの標準偏差

  • 移動平均からの標準偏差

  • 最小二乗

  • ヒストグラムビン

  • コルモゴロフ–スミルノフ検定

それらのほとんどは、сontrolチャート(シューハートチャートとも呼ばれます)および* 3シグマルール*に基づいています。 彼らはPythonライブラリSciPyとNumPyを計算に使用しています。

使用するアルゴリズムはどれでもカスタマイズできます。 新しいものを変更、削除、または追加することもできます。 これを行うには、構成ファイルを編集する必要があります。

sudo vi /opt/skyline/src/analyzer/algorithms.py

このファイルの各アルゴリズムには、簡単な説明が記載されています。 たとえば、次のアルゴリズムを調べてみましょう。

/opt/skyline/src/analyzer/algorithms.py

def median_absolute_deviation(timeseries):
   """
   A timeseries is anomalous if the deviation of its latest datapoint with
   respect to the median is X times larger than the median of deviations.
   """

   series = pandas.Series([x[1] for x in timeseries])
   median = series.median()
   demedianed = np.abs(series - median)
   median_deviation = demedianed.median()

   # The test statistic is infinite when the median is zero,
   # so it becomes super sensitive. We play it safe and skip when this happens.
   if median_deviation == 0:
       return False

   test_statistic = demedianed.iget(-1) / median_deviation

   # Completely arbitary...triggers if the median deviation is
   # 6 times bigger than the median
   if test_statistic > :
       return True

データの性質に基づいて、しきい値を「6」から「4 +」、「 5 」、「 7+」などの別のものに変更する必要がある場合があります。

`+ settings.py +`ファイルの設定を調整することもできます:

/opt/skyline/src/settings.py

ALGORITHMS = [
   'first_hour_average',
   'mean_subtraction_cumulation',
    'stddev_from_average',
    'stddev_from_moving_average',
    'least_squares',
    'grubbs',
    'histogram_bins',
    'median_absolute_deviation',
    'ks_test',
]

CONSENSUS = 6

`+ ALGORITHMS `オプションは、アナライザーが実行するアルゴリズムを指定します。 それらのいずれかをコメントアウトして、それらを無効にするか、新しいアルゴリズムを追加できます。 「 CONSENSUS 」オプションは、メトリックが異常として分類される前に「 True +」を返す必要があるアルゴリズムの数を指定します。 感度を上げるには、このオプションを減らすか、その逆を行います。

結論

Skylineは、複雑で動的に変化するITシステムで実証されています。 オペレーティングシステムに定期的に変更を加え、新しいソフトウェアのリリース後にシステムメトリックの異常をすばやく検出したいプログラマーにとって便利です。

主な利点は次のとおりです。

  • 大量のデータの高速分析

  • 各メトリックに個別のパラメーターを設定する必要はありません

  • 異常検出のための独自のアルゴリズムを追加する機能

また、いくつかの欠点もあります。

  • 各メトリックのデータは、重要なコンピューティングシステムリソースを必要とするいくつかのアルゴリズムによって分析されます。

  • すべてのデータはRAMに保存されるため、システムは非常に迅速に動作できます。 多数のメトリックと長期間の分析では、大量のRAMが必要になります。