Prometheusは、オープンソースの監視システムおよび時系列データベースです。 Prometheusの最も重要な側面の1つは、その多次元データモデルとそれに付随するクエリ言語です。このクエリ言語を使用すると、次元データをスライスおよびダイシングして、一時的な方法で運用上の質問に回答したり、ダッシュボードに傾向を表示したり、システム障害に関するアラートを生成したりできます。
このチュートリアルでは、Prometheus1.3.1にクエリを実行する方法を学習します。適切なサンプルデータを使用するために、さまざまな合成メトリックを導出するための3つの同一のデモンストレーションサービスインスタンスを設定します。次に、これらのメトリックをクロールして保存するようにPrometheusサーバーをセットアップします。メトリックの例を使用して、Prometheusにクエリを実行する方法を学習します。簡単なクエリから始めて、より高度なクエリに進みます。
このチュートリアルの後、ディメンションに基づいて時系列を選択およびフィルタリングする方法、時系列を集約および変換する方法、および異なるインジケーター間で算術演算を実行する方法を学習します。以降のチュートリアルでは、このチュートリアルの知識に基づいて、より高度なクエリの使用例を紹介します。
このチュートリアルに従うには、次のものが必要です。
このステップでは、Prometheusサーバーをダウンロード、構成、および実行して、3つの(まだ実行されていない)デモサービスインスタンスをスクレイプします。
まず、Prometheusをダウンロードします。
wget https://github.com/prometheus/prometheus/releases/download/v1.3.1/prometheus-1.3.1.linux-amd64.tar.gz
ターボールを抽出します。
tar xvfz prometheus-1.3.1.linux-amd64.tar.gz
〜/ prometheus.yml
のホストファイルシステムに最小限のPrometheus構成ファイルを作成します。
nano ~/prometheus.yml
以下をファイルに追加します。
# Scrape the three demo service instances every 5 seconds.
global:
scrape_interval: 5s
scrape_configs:- job_name:'demo'
static_configs:- targets:-'localhost:8080'-'localhost:8081'-'localhost:8082'
nanoを保存して終了します。
このサンプル構成により、Prometheusはデモインスタンスをスクレイプしました。 Prometheusはプルモデルを使用します。そのため、メトリックが抽出されるエンドポイントを理解するように構成する必要があります。デモインスタンスはまだ実行されていませんが、後でポート 8080
、 8081
、および 8082
で実行されます。
nohup
を使用し、バックグラウンドプロセスとしてPrometheusを開始します。
nohup ./prometheus-1.3.1.linux-amd64/prometheus -storage.local.memory-chunks=10000&
コマンドの先頭にある nohup
の出力を、 stdout
ではなくファイル 〜/ nohup.out
に送信します。コマンドの最後で、 &
はプロセスをバックグラウンドで実行し続け、他のコマンドプロンプトを表示します。プロセスをフォアグラウンド(つまり、端末の実行中のプロセス)に戻すには、同じ端末で fg
コマンドを使用します。
すべてがうまくいけば、 〜/ nohup.out
ファイルに、次のような出力が表示されます。
time="2016-11-23T03:10:33Z" level=info msg="Starting prometheus (version=1.3.1, branch=master, revision=be476954e80349cb7ec3ba6a3247cd712189dfcb)" source="main.go:75"
time="2016-11-23T03:10:33Z" level=info msg="Build context (go=go1.7.3, user=root@37f0aa346b26, date=20161104-20:24:03)" source="main.go:76"
time="2016-11-23T03:10:33Z" level=info msg="Loading configuration file prometheus.yml" source="main.go:247"
time="2016-11-23T03:10:33Z" level=info msg="Loading series map and head chunks..." source="storage.go:354"
time="2016-11-23T03:10:33Z" level=info msg="0 series loaded." source="storage.go:359"
time="2016-11-23T03:10:33Z" level=warning msg="No AlertManagers configured, not dispatching any alerts" source="notifier.go:176"
time="2016-11-23T03:10:33Z" level=info msg="Starting target manager..." source="targetmanager.go:76"
time="2016-11-23T03:10:33Z" level=info msg="Listening on :9090" source="web.go:240"
別の端末では、 tail -f〜 / nohup.out
コマンドを使用してこのファイルの内容を監視できます。内容がファイルに書き込まれると、端末に表示されます。
デフォルトでは、Prometheusはその構成を prometheus.yml
(先ほど作成したもの)からロードし、その測定データを現在の作業ディレクトリの。/ data
に保存します。
- storage.local.memory-chunks
フラグは、Prometheusのメモリ使用量を、ホストシステムの非常に少量のRAM(512MBのみ)と、このチュートリアルに保存されている少量の時系列に調整します。
これで、 http:// your_server_ip:9090 /
にあるPrometheusサーバーにアクセスできるようになります。 「** Target」セクションの「http:// your_server_ip:9090 / status」をポイントし、「demo」ジョブの3つのターゲットエンドポイントを見つけて、3つのデモインスタンスからメトリックを収集するように構成されていることを確認します。デモインスタンスが開始されていないため、3つのターゲットすべての State 列に、ターゲットのステータスが DOWN **と表示されているはずです。そのため、削除できません。
このセクションでは、3つのデモサービスインスタンスをインストールして実行します。
デモサービスのダウンロード:
wget https://github.com/juliusv/prometheus_demo_service/releases/download/0.0.4/prometheus_demo_service-0.0.4.linux-amd64.tar.gz
それを抽出します:
tar xvfz prometheus_demo_service-0.0.4.linux-amd64.tar.gz
異なるポートでデモサービスを3回実行します。
. /prometheus_demo_service -listen-address=:8080&./prometheus_demo_service -listen-address=:8081&./prometheus_demo_service -listen-address=:8082&
&
はバックグラウンドでデモサービスを開始します。何もログに記録されませんが、それぞれのポートの / metrics
HTTPエンドポイントでPrometheusメトリックを公開します。
これらのデモンストレーションサービスは、いくつかのアナログサブシステムに関する包括的な指標をエクスポートします。これらは:
各インジケータは、次のセクションのクエリ例で紹介されています。
これで、Prometheusサーバーが3つのデモインスタンスのクロールを自動的に開始するはずです。 Prometheusサーバー http:// your_server_ip:9090 / status`` demo
のステータスページに移動し、ジョブのターゲットが** UP **ステータスとして表示されていることを確認します。
このステップでは、Prometheusの組み込みクエリとグラフィカルWebインターフェイスについて理解します。このインターフェイスは、一時的なデータの探索やPrometheusクエリ言語の学習には非常に適していますが、永続的なダッシュボードの構築には適しておらず、高度な視覚化機能をサポートしていません。
Prometheusサーバー http:// your_server_ip:9090 / graph
に移動します。次のようになります。
ご覧のとおり、グラフとコンソールの2つのタブがあります。 Prometheusでは、2つの異なるモードでデータをクエリできます。
Prometheusは数百万の時系列に拡張できるため、非常に高価なクエリを作成することができます(SQLデータベースの大きなテーブルからすべての行を選択するのと同じように考えてください)。サーバーがタイムアウトしたり過負荷になったりするクエリを回避するには、クエリをすぐに描画するのではなく、コンソールビューでクエリの調査と作成を開始することをお勧めします。ある時点で潜在的にコストのかかるクエリを評価すると、一定期間にわたって同じクエリをプロットしようとするよりもはるかに少ないリソースしかありません。
クエリの範囲を十分に絞り込んだら(ロードすることを選択したシリーズ、実行する必要のある計算の数、および出力時系列の数に応じて)、[グラフ]タブに切り替えて、時間の経過に伴う計算式を表示できます。クエリの価格がいつ十分に安いかを知ることは正確な科学ではありません。それはデータ、待ち時間の要件、およびPrometheusサーバーを実行しているマシンの機能に依存します。時間が経つにつれて、あなたはこのように感じるでしょう。
テスト用のPrometheusサーバーは大量のデータを取得しないため、このチュートリアルでは実際にコストのかかるクエリを作成することはできません。サンプルクエリは、リスクなしで「**グラフ」**および「**コンソール」**ビューで表示できます。
グラフの時間範囲を縮小または拡大するには、**-または + ボタンをクリックします。グラフの終了時刻を移動するには、 << または >> **ボタンを押します。 ** Stack **チェックボックスをアクティブにすると、グラフィックをスタックできます。最後に、**解像度。 (S)**入力により、カスタムクエリ解像度を指定できます(このチュートリアルでは必要ありません)。
クエリを開始する前に、Prometheusデータモデルと用語を簡単に確認しましょう。 Prometheusは基本的に、すべてのデータを時系列として保存します。各時系列は、Prometheusが* label *と呼ぶメトリック名とキーと値のペアのセットによって識別されます。メトリック名は、測定されるシステムの全体的な側面を示します(たとえば、プロセスが「http_requests_total」を開始してから処理されたHTTP要求の数)。ラベルは、HTTPメソッド(例: method =" POST "
)やパス(例: path =" / api / foo "
)など、メジャーのサブディメンションを区別するために使用されます。最後に、一連のサンプルが一連の実際のデータを形成します。各サンプルは、タイムスタンプと値で構成されます。タイムスタンプの精度はミリ秒で、値は常に64ビットの浮動小数点値です。
作成できる最も単純なクエリは、指定されたメトリック名を持つすべてのシリーズを返します。たとえば、デモサービスは、仮想サービスによって処理された合成APIHTTPリクエストの数を表すメトリック demo_api_request_duration_seconds_count
をエクスポートします。メトリック名に文字列 duration_seconds
が含まれているのはなぜか疑問に思われるかもしれません。これは、このカウンターがより大きなヒストグラムメトリックの一部であるためです。メトリック demo_api_request_duration_seconds
は、主に要求期間の分布を追跡しますが、追跡要求の総数(ここでは接尾辞 _count
)も開示します。有用な副産物。
[コンソールクエリ]タブが選択されていることを確認し、ページ上部のテキストフィールドに次のクエリを入力してから、[**実行] **ボタンをクリックしてクエリを実行します。
demo_api_request_duration_seconds_count
Prometheusは3つのサービスインスタンスを監視しているため、追跡サービスインスタンス、パス、HTTPメソッド、およびHTTPステータスコードごとに1つずつ、このメトリック名で27の結果時系列を含む表形式の出力が表示されます。サービスインスタンス自体(「メソッド」、「パス」、「ステータス」のラベルを設定)に加えて、シリーズには、異なるサービスインスタンスを互いに区別するために、「ジョブ」と「インスタンス」に適切なラベルが付けられます。削られたターゲットの時系列を保存するとき、Prometheusはこれらのタグを自動的に添付します。出力は次のようになります。
右側の列に表示されている値は、各時系列の現在の値です。出力グラフを自由に描画して([**グラフ] **タブをクリックし、もう一度[**実行]をクリック)、このクエリと後続のクエリを取得して、値が時間の経過とともにどのように変化するかを確認できます。
タグマッチャーを追加して、タグに基づいて返されるシリーズを制限できるようになりました。タグマッチャーは、中括弧で囲まれたメトリック名の直後に続きます。最も単純な形式では、指定されたラベルの正確な値でシリーズをフィルタリングします。たとえば、このクエリは、 GET
リクエストのリクエスト数のみを表示します。
demo_api_request_duration_seconds_count{method="GET"}
マッチャーはコンマの組み合わせを使用できます。たとえば、インスタンス localhost:8080
とジョブ demo
からのみメトリックをフィルタリングすることもできます。
demo_api_request_duration_seconds_count{instance="localhost:8080",method="GET",job="demo"}
結果は次のようになります。
複数のマッチャーを組み合わせる場合、シリーズを選択するには、すべてのマッチャーを一致させる必要があります。上記の式は、ポート8080で実行されているサービスインスタンスのAPI要求数とHTTPメソッド GET
の場所のみを返します。また、「デモ」の位置に属するインジケーターのみを選択するようにしてください。
注:時系列を選択するときは、常にラベル「job」を指定することをお勧めします。これにより、異なるジョブから同じ名前のインジケーターを誤って選択することがなくなります(もちろん、これが実際に目標でない限り)。このチュートリアルでは1つのジョブのみを監視していますが、この演習の重要性を強調するために、以下のほとんどの例ではジョブ名で選択します。
Prometheusは、等しいマッチングに加えて、等しくないマッチング( !=
)、正規式マッチング( = 〜
)、および負の正規式マッチング(!〜
)もサポートしています。メトリック名を完全に省略して、クエリにタグマッチャーのみを使用することもできます。たとえば、 path
タグが / api
で始まるすべてのシリーズ(メトリック名またはジョブに関係なく)を一覧表示するには、次のクエリを実行できます。
{ path=~"/api.*"}
。*
で終わる正規式は、常にPrometheusの完全な文字列と一致するため、上記の正規式は終了する必要があります。
結果の時系列は、異なるメトリック名を持つ系列の混合になります。
これで、メトリック名とラベル値の組み合わせに基づいて時系列を選択する方法がわかりました。
このセクションでは、メトリックのレートまたは増分を計算する方法を学習します。
Prometheusで使用する最も一般的な関数の1つは、 rate()
です。 Prometheusでは、インストルメント化されたサービスで直接イベントレートを計算する代わりに、通常、元のカウンターを使用してイベントを追跡し、クエリ時間中にPrometheusサーバーに一時的にレートを計算させます(これには、レートのピークを失わないなど、多くの利点があります。時間、およびクエリ中に動的平均ウィンドウを選択する機能)。カウンタは、監視対象のサービスが開始されると「0」から始まり、サービスプロセスのライフサイクルの間増加し続けます。監視対象のプロセスが再起動すると、そのカウンターが「0」にリセットされ、そこから再び上昇し始める場合があります。生のカウンターをプロットすることは、行の増加のみが表示され、場合によってはリセットされるため、通常はあまり役に立ちません。デモサービスのAPIリクエスト数をプロットすることで表示できます。
demo_api_request_duration_seconds_count{job="demo"}
これは少し次のようになります。
カウンターを便利にするために、 rate()
関数を使用して* 1秒あたり*の成長率を計算できます。シリーズマッチャーの後に範囲セレクター( [5m]
など)を提供することにより、平均レートの時間枠を決定するように rate()
に指示する必要があります。たとえば、上記のカウンタインジケータの1秒あたりの増分(過去5分間の平均など)を計算するには、次のクエリを描画します。
rate(demo_api_request_duration_seconds_count{job="demo"}[5m])
結果はより有用になりました:
rate()
はスマートで、カウンター値のリセットがリセットであると想定して、カウンターのリセットを自動的に調整します。
rate()
の変形はirate()
です。 rate()
は、指定された時間枠(この場合は5分)内のすべてのサンプルのレートを平均しますが、 irate()
は過去2つのサンプルしか確認できません。これら2つのサンプルの最大ルックバック時間を知るには、時間枠( [5m]
など)を指定する必要があります。 irate()
はレートの変化に対してより速く反応するため、通常はグラフに推奨されます。逆に、 rate()
はよりスムーズなレートを提供し、アラーム式に推奨されます(短期間のピークが抑制され、夜間に目覚めないため)。
irate()
を使用すると、上記のグラフは次のようになり、リクエストレートが断続的に短くなります。
rate()
とirate()
は常に* 1秒あたりのレートを計算します。ある期間にわたってカウンターが増加した合計量*を知りたい場合がありますが、それでもカウンターのリセットを修正できます。この目的のために increase()
関数を使用できます。たとえば、過去1時間に処理されたリクエストの総数を計算するには、次のクエリを実行してください。
increase(demo_api_request_duration_seconds_count{job="demo"}[1h])
カウンター(増やすことしかできません)に加えて、測定インジケーターもあります。メーターは、温度や使用可能なディスク容量など、時間の経過とともに上昇または下降する可能性のある値です。メーターの経時変化を計算したい場合、 rate()
/ irate()
/ increase()
シリーズの関数を使用することはできません。これらはすべて、メトリック値の減少をカウンターリセットとして解釈し、それを補正するため、カウンター用です。代わりに、線形回帰に基づいてメーターの1秒あたりの導関数を計算する deriv()
関数を使用できます。
たとえば、過去15分間の線形回帰に基づいて、デモサービスによってエクスポートされた架空のディスクの使用量がどれだけ速く増加または減少したか(MiB /秒)を確認するには、次のクエリを実行します。
deriv(demo_disk_usage_bytes{job="demo"}[15m])
結果は次のようになります。
これで、さまざまな平均動作で1秒あたりのレートを計算する方法、レート計算でカウンターリセットを処理する方法、およびメーターの導関数を計算する方法がわかりました。
このセクションでは、単一のシリーズを集約する方法を学習します。
Prometheusは、高次元の詳細を含むデータを収集します。これにより、各メトリック名の多くのシリーズが生成される可能性があります。ただし、通常はすべてのサイズを気にする必要はなく、シリーズが多すぎて、合理的な方法で一度にすべてを描画できない場合もあります。解決策は、特定のディメンションを集約し、関心のあるディメンションのみを保持することです。たとえば、デモサービスはAPIHTTPリクエストの method
、 path
、および status
をトレースします。 Prometheusがノードエクスポーターからスクレイプされたとき、さらにディメンションが追加されました。ラベル処理を追跡するためのメトリック「インスタンス」と「ジョブ」はどこから来たのですか。ここで、すべてのディメンションの合計要求率を確認するには、 sum()
集計演算子を使用できます。
sum(rate(demo_api_request_duration_seconds_count{job="demo"}[5m]))
ただし、これによりすべてのディメンションが集約され、単一の出力系列が作成されます。
ただし、通常は、出力にいくつかのディメンションを保持する必要があります。このため、 sum()
およびその他のアグリゲーターは、集約するする without( <label names>)
句をサポート
sum without(method, status)(rate(demo_api_request_duration_seconds_count{job="demo"}[5m]))
これは次と同等です。
sum by(instance, path, job)(rate(demo_api_request_duration_seconds_count{job="demo"}[5m]))
結果は、 instance
、 path
、および job
によってグループ化されます。
注:集計を適用する前に、常に rate()
、 irate()
、または increase()
を計算してください。最初に集計を適用すると、カウンターリセットが非表示になり、これらの機能が正しく機能しなくなります。
Prometheusは、次の集計演算子をサポートしています。各演算子は、保持するディメンションを選択するための by()
または without()
句をサポートしています。
sum
:集計グループ内のすべての値を要約します。 min
:集計グループ内のすべての値の最小値を選択します。 max
:集計グループ内のすべての値の最大値を選択します。 avg
:集計グループ内のすべての値の平均(算術平均)を計算します。 stddev
:集計グループ内のすべての値の標準偏差を計算します。 stdvar
:集計グループ内のすべての値の標準差を計算します。 count
:集計グループ内のシーケンスの総数を計算します。これで、シリーズのリストを集約する方法と、関心のあるディメンションのみを保持する方法を学習しました。
このセクションでは、Prometheusで算術演算を実行する方法を学習します。
最も単純な算術の例として、Prometheusを数値計算機として使用できます。たとえば、「**コンソール」**ビューで次のクエリを実行します。
(4+7)*3
単一のスカラー出力値 33
を取得します。
スカラー値は、ラベルのない単純な数値です。これをより便利にするために、Prometheusは通常の算術演算子( +
、 -
、*
、/
、%
)を時系列ベクトル全体に適用できます。たとえば、次のクエリは、最後に実行されたバッチジョブのシミュレートされた処理バイトをMiBに変換します。
demo_batch_last_run_processed_bytes{job="demo"}/1024/1024
結果はMiBに表示されます。
優れた視覚化ツール(Grafanaなど)でも変換を処理できますが、これらのタイプの単位変換には単純なアルゴリズムがよく使用されます。
Prometheus(Prometheusが本当に輝いているところ!)の特徴は、2セットの時系列間のバイナリ演算です。 2セットのシリーズ間でバイナリ演算子を使用する場合、Prometheusは、操作の左側と右側に設定された同じラベルの要素を自動的に照合し、一致した各ペアに演算子を適用して出力シーケンスを生成します。
たとえば、 demo_api_request_duration_seconds_sum
メトリックは、HTTP要求に応答するのにかかった秒数を示し、 demo_api_request_duration_seconds_count
はHTTP要求の数を示します。 2つのインジケーターのサイズは同じです( method
、 path
、 status
、 instance
、 job
)。各ディメンションの平均リクエスト待ち時間を計算するには、リクエストに費やされた合計時間の比率をリクエストの総数で割った値を単純にクエリできます。
rate(demo_api_request_duration_seconds_sum{job="demo"}[5m])/rate(demo_api_request_duration_seconds_count{job="demo"}[5m])
また、操作の両側で rate()
関数をラップして、過去5分間に発生した要求の遅延のみを考慮することに注意してください。これにより、カウンターのリセットに抵抗する柔軟性も向上します。
結果の平均リクエストレイテンシグラフは次のようになります。
しかし、タグが両側で正確に一致しない場合はどうすればよいでしょうか。これは、操作の両側に異なるサイズの時系列セットがある場合に特に発生します。これは、一方のサイズがもう一方のサイズよりも大きいためです。たとえば、デモジョブのエクスポートでは、さまざまなモードで架空のCPU時間( idle
、 user
、 system
)が、 mode
タグのサイズのインジケーター demo_cpu_usage_seconds_total
として費やされます。また、架空のCPUの総数を demo_num_cpus
としてエクスポートします(このインジケーターには追加のディメンションはありません)。 3つのモードのそれぞれの平均CPU使用率に到達するために一方を他方で除算しようとすると、クエリは出力を生成しません。
# BAD!
# Multiply by 100 to getfrom a ratio to a percentage
rate(demo_cpu_usage_seconds_total{job="demo"}[5m])*100/
demo_num_cpus{job="demo"}
これらの1対多または多対1のマッチングでは、マッチングに使用するタグのサブセットをPrometheusに指示する必要があります。また、追加のディメンションの処理方法を指定する必要もあります。マッチングの問題を解決するためバイナリ演算子on( <label names>)
句を追加して、マッチング
この場合、正しいクエリは次のようになります。
# Multiply by 100 to getfrom a ratio to a percentage
rate(demo_cpu_usage_seconds_total{job="demo"}[5m])*100/on(job, instance)group_left(mode)
demo_num_cpus{job="demo"}
結果は次のようになります。
on(job、instance)
は、ジョブとインスタンスのラベルで左右の系列のみを照合するようにオペレーターに指示します(したがって、右側では正しくないモードラベルでは照合しません)。 Exist)であり、 group_left(mode)
句は、各モードの平均CPU使用率をファンアウトして表示するようにオペレーターに指示します。これは、多対1のマッチングの場合です。逆(1対多)マッチングを実行するには、同じ方法で group_right( <label names>)
句を使用し
これで、時系列のセット間で算術を使用する方法と、さまざまな次元を処理する方法を理解できました。
このチュートリアルでは、一連のデモサービスインスタンスを設定し、Prometheusを使用してそれらを監視します。次に、収集したデータにさまざまなクエリ手法を適用して、関心のある質問に答える方法を学びました。これで、シリーズを選択してフィルタリングする方法、サイズを集計する方法、レートや導関数を計算する方法、または算術を実行する方法をマスターしました。また、一般的なクエリの構造化方法と、Prometheusサーバーの過負荷を回避する方法についても学びました。
Prometheus関連のチュートリアルのクエリの詳細については、[Tencent Cloud + Community](https://cloud.tencent.com/developer?from=10680)にアクセスして詳細を確認してください。
参照:「Ubuntu14.04パート1でPrometheusを照会する方法」
Recommended Posts