序章

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

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

しきい値トリガー

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

Figure 1
図1

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

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

ポイント3を見てみましょう。 その時点で、イベントの負荷は低下しますが、しきい値を超えていないため、管理者には通知されませんでした。 トリガーがアクティブになりませんでした。

この単純なケースは、しきい値を設定しようとするといくつかの問題があることを示しています。 誤検知エラーまたは誤検知エラーをトリガーせずにパフォーマンスの問題をキャッチするためにしきい値を調整することは困難です。

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

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

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

ホライゾンエージェント

HorizonAgentはデータの収集を担当します。 着信データをリッスンするリスナーがあります。

pickle (TCP)と MessagePack (UDP)の2つの形式でデータを受け入れます。 着信メトリックを読み取り、Workersが読み取った共有キューに入れます。 ワーカーはデータをMessagepackにエンコードし、Redisデータベースに追加します。 Horizon Agentは、 Roombas を使用して、古いメトリックを定期的にトリミングおよびクリーンアップします。 これが行われない場合、すべての空きメモリはすぐに使い果たされます。

アナライザーエージェント

アナライザーエージェントは、データの分析を担当します。 Redisからメトリックのリストを受け取り、いくつかのプロセスを実行し、それぞれにメトリックを割り当てます。 各プロセスは、いくつかのアルゴリズムを使用してデータを分析します。 各アルゴリズムは、データが異常であるかどうかにかかわらず、結果を報告します。 アルゴリズムの大部分が現在のメトリックに異常があることを報告する場合、データは異常と見なされます。

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

アナライザーは、電子メール、HipChat、またはPagerDutyなどの通知を送信することもできます。 電子メール通知は、この記事の後半で構成されます。

Webapp

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

Redisデータベース

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

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

図2は、Skylineのコンポーネントの相互作用の図を示しています。

Figure 2
図2

前提条件

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

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

Skylineをインストールするには、最初に、Python関連のツールやApacheWebサーバーなどの必要なアプリケーションをインストールします。

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

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

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

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

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

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

  1. sudo pip install numpy
  2. sudo pip install scipy
  3. sudo pip install pandas
  4. sudo pip install patsy
  5. sudo pip install statsmodels
  6. sudo pip install msgpack-python

一部のパッケージのインストールには時間がかかる場合がありますので、しばらくお待ちください。

それらのほとんどは、科学的および技術的なコンピューティングに使用されるオープンソースのPythonライブラリです。 msgpack-pythonパッケージは、MessagePackデータの読み取りと書き込みに必要です。

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

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

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

  1. sudo mkdir /var/log/skyline
  2. sudo mkdir /var/run/skyline
  3. sudo mkdir /var/log/redis
  4. sudo mkdir /var/dump/

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

  1. sudo yum install redis

Redisの詳細については、チュートリアルRedisのインストールと使用方法を参照してください。

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

  1. cd /opt/skyline/bin
  2. sudo redis-server redis.conf
  3. sudo ./horizon.d start
  4. sudo ./analyzer.d start
  5. sudo ./webapp.d start

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

  1. python /opt/skyline/utils/seed_data.py

次の出力が表示されます。

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

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

ステップ2—データをスカイラインに取り込む

前述のように、Skylineは、 pickle (TCP)と MessagePack (UDP)の2つの形式のデータを受け入れます。

独自のスクリプトまたはモジュールをお気に入りの監視エージェントに記述し、MessagePackを使用してデータをエンコードして、分析のためにSkylineに送信することができます。 Skylineは、UDPを介してMessagePackでエンコードされた文字列の形式でメトリックを受け入れます。 MessagePackは、JSONのようなオブジェクトのシリアル化仕様です。 形式は[<metric name>, [<timestamp>, <value>]]です。 MessagePackには、ほとんどのプログラミング言語用のAPIがあります。 詳細とAPIの例は、MessagePack公式サイトにあります。

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

グラファイトからのデータの取得

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

Figure 3
図3

図3に、データフローの概略図を示します。 外部監視エージェント( collectd diamond statsd など)またはシステム( Nagaos Icinga )からのデータ、 Sensu など)がGraphiteに転送されます。 次に、カーボンリレーがデータをSkylineに転送します。 カーボンリレー、カーボンキャッシュ、およびSkylineは、単一のホストまたは個別のホストのいずれかで実行できます。

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

relay-rules.conf を以前にカーボンリレー構成ファイルの適切な場所にコピーしなかった場合は、ここでコピーする必要があります。

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

relay-rules.conf構成ファイルを開いて編集してみましょう。

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

Skylineホストを宛先のリストに追加します。ここで、YOUR_SKYLINE_HOSTはSkylineホストのIPアドレスです。

/opt/graphite/conf/relay-rules.conf
[default]
default = true
destinations = 127.0.0.1:2004, YOUR_SKYLINE_HOST:2024

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

carbon.conf構成ファイルを開いて、次の変更を行います。

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

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

/opt/graphite/conf/carbon.conf
[relay]
...
DESTINATIONS = 127.0.0.1:2004, YOUR_SKYLINE_HOST:2024
...

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

  1. sudo systemctl start carbon-relay

グラファイトへのスカイラインアクセスの許可-Web

Graphite、Carbonを使用して効果的な履歴ログを保持し、CentOS 7 で収集する方法で、Graphite Webインターフェイスをパスワードで保護することを選択した場合、はパスワードなしでローカルホストからのアクセスを許可する必要がありますSkylineが機能するために。

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

  1. 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
	Order Deny,Allow
	Deny from all
	Allow from localhost
	Satisfy Any
</Location>

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

  1. sudo systemctl restart httpd

収集されたデータの取得

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

  1. sudo vi /etc/collectd.conf

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

/etc/collectd.conf
<Plugin write_graphite>
	. . .		
	Port "2013"
	. . .

次に、collectdを再起動します。

  1. sudo systemctl restart collectd.service

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

Figure 4
図4

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

  1. カーボンリレーは、ポート2013plaintext形式の着信データをリッスンします
  2. カーボンリレーはデータをpickle形式で送信します
  3. Carbon-cacheは、ポート2004pickle形式の着信データをリッスンします。
  4. Horizonエージェントは、ポート2024pickle形式の着信データをリッスンします。

注意! 同じホストでHorizonエージェントとオプションのカーボンアグリゲーターを起動する場合は、それらのポートを変更する必要があります。 デフォルトでは、両方とも同じポート2024に設定されています。

ステップ3—スカイラインの設定

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

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

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

  • GRAPHITE_HOST = 'YOUR_GRAPHITE_HOST'
  • HORIZON_IP = '0.0.0.0'
  • WEBAPP_IP = 'YOUR_SKYLINE_HOST_IP'

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

  • FULL_DURATION —このオプションは、データがRedisに保存されて分析される最大時間を指定します。 期間が長くなると分析に時間がかかりますが、ノイズを減らし、より正確な異常検出を提供するのに役立ちます。 デフォルト値は86400秒です。
  • CARBON_PORT —このオプションはカーボンポートを指定します。 デフォルト値は2003です。
  • ANALYZER_PROCESSES —このオプションは、Skylineアナライザーが生成するプロセスの数を指定します。 このパラメーターは、ホスト上のCPUの総数よりも数少ない数に設定することをお勧めします。 デフォルト値は5です。
  • WORKER_PROCESSES —このオプションは、Horizonキューから消費するワーカープロセスの数を指定します。 デフォルト値は2です。
  • PICKLE_PORT —このオプションは、GraphiteのピクルスをリッスンするTCPポートを指定します。 デフォルト値は2024です。
  • UDP_PORT —このオプションは、MessagePackでエンコードされたパケットをリッスンするUDPポートを指定します。 デフォルト値は2025です。
  • WEBAPP_PORT —このオプションは、SkylineWebアプリのポートを指定します。 デフォルト値は1500です。

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

  1. sudo /opt/skyline/bin/horizon.d restart
  2. sudo /opt/skyline/bin/analyzer.d restart
  3. sudo /opt/skyline/bin/webapp.d restart

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

Figure 5
図5

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

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

ステップ4—電子メールアラートを有効にする

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

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

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

  1. 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秒)以内に2回以上発生しないことを意味します。 この値をニーズに最も合うように変更します。

また、次のセクションを見つけて、使用する電子メールアドレスに合わせて変更します。 メールアラートは、(^)skyline-alerts @example .com(^)から(^)administrator @example .com(^)アカウントに送信されます。

/opt/syline/src/settings.py
SMTP_OPTS = {
	"sender": "(^)[email protected](^)",
	"recipients": {
		"collectd": ["(^)[email protected](^)"],
	},
}

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

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

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

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

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

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

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

Figure 6
図6

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

Figure 7
図7

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

従来の監視システムとは異なり、Skylineは逸脱をすばやく見つけて通知することができます。

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

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

  • 平均絶対偏差
  • グラブスのテスト
  • 最初の1時間の平均
  • 平均からの標準偏差
  • 移動平均からの標準偏差
  • 最小二乗
  • ヒストグラムビン
  • コルモゴロフ-スミルノフ検定

それらのほとんどは、管理図(シューハート管理図とも呼ばれます)と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 > 6:
        return True                                                       

データの性質に応じて、しきい値を6から別の値(457など)に変更する必要がある場合があります。

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が必要になります。