サンプリング
Jaeger ライブラリは、一貫性のある前段(またはヘッドベース)サンプリングを実装しています。たとえば、サービス A がサービス B を呼び出し、B がサービス C を呼び出す単純なコールグラフがあるとします。A -> B -> C
。サービス A がトレーシング情報を含まないリクエストを受け取った場合、Jaeger トレースは新しいトレースを開始し、ランダムなトレース ID を割り当て、現在インストールされているサンプリング戦略に基づいてサンプリングの判断を行います。サンプリングの決定は、B へのリクエストと C へのリクエストに伝達されます。つまり、これらのサービスは再度サンプリングの決定を行うのではなく、最上位のサービス A の決定に従います。このアプローチにより、トレースがサンプリングされた場合、そのすべてのスパンがバックエンドに記録されます。各サービスが独自のサンプリングの決定を行っていた場合、バックエンドで完全なトレースを取得することはほとんど不可能です。
クライアントサンプリングの設定
構成オブジェクトを使用してトレーサーをインスタンス化する場合、サンプリングのタイプは sampler.type
と sampler.param
プロパティを介して選択できます。Jaeger ライブラリは、次のサンプラーをサポートしています。
- 定数(
sampler.type=const
)サンプラーは、すべてのトレースに対して常に同じ判断を下します。すべてのトレースをサンプリングするか(sampler.param=1
)、まったくサンプリングしないか(sampler.param=0
)です。 - 確率的(
sampler.type=probabilistic
)サンプラーは、サンプリングする確率がsampler.param
プロパティの値に等しいランダムなサンプリングの判断を行います。たとえば、sampler.param=0.1
の場合、10 個のトレースのうち約 1 個がサンプリングされます。 - レート制限(
sampler.type=ratelimiting
)サンプラーは、リーキーバケットレイトリミッターを使用して、一定のレートでトレースがサンプリングされることを確認します。たとえば、sampler.param=2.0
の場合、毎秒2トレースのレートでリクエストがサンプリングされます。 - リモート(
sampler.type=remote
、これもデフォルトです)サンプラーは、現在のサービスで使用する適切なサンプリング戦略についてjaeger-agentに問い合わせます。これにより、Jaegerバックエンドの中央構成(リモートサンプリングを参照)または動的(適応サンプリングを参照)からもサンプリング戦略をサービスで制御できます。
リモートサンプリング
クライアントSDKがリモートサンプリング構成を使用するように構成されている場合(リモートサンプリングAPIを参照)、サンプリングレートはjaeger-collectorから一元的に制御できます。このセットアップでは、エンドポイントとそのサンプリング確率を記述するサンプリング戦略構成がクライアントSDKに提供されます。この構成は、jaeger-collectorで、ファイルから定期的にロードされるか、トラフィックに基づいて動的に計算されるの2つの方法で生成できます。生成方法は、SAMPLING_CONFIG_TYPE
環境変数を制御によって行われ、file
(デフォルト)またはadaptive
のいずれかに設定できます。
ファイルベースのサンプリング構成
jaeger-collectorは、Jaegerクライアントに提供されるサンプリング戦略を含むファイルへのポイント--sampling.strategies-file
オプションを使用してインスタンス化できます。このオプションの値には、内容が変更された場合に自動的に再ロードされるJSONファイルへのパス、またはファイルが定期的に取得されるHTTP URLを含めることができ、再ロードの頻度は--sampling.strategies-reload-interval
オプションで制御されます。
設定が行われない場合、jaeger-collectorはすべてのサービスに対して確率0.001(0.1%)のデフォルトの確率サンプリングポリシーを返します。
サンプルstrategies.json
{
"service_strategies": [
{
"service": "foo",
"type": "probabilistic",
"param": 0.8,
"operation_strategies": [
{
"operation": "op1",
"type": "probabilistic",
"param": 0.2
},
{
"operation": "op2",
"type": "probabilistic",
"param": 0.4
}
]
},
{
"service": "bar",
"type": "ratelimiting",
"param": 5
}
],
"default_strategy": {
"type": "probabilistic",
"param": 0.5,
"operation_strategies": [
{
"operation": "/health",
"type": "probabilistic",
"param": 0.0
},
{
"operation": "/metrics",
"type": "probabilistic",
"param": 0.0
}
]
}
}
service_strategies
要素はサービス固有のサンプリング戦略を定義し、operation_strategies
は操作固有のサンプリング戦略を定義します。可能な戦略にはprobabilistic
とratelimiting
の2種類があり、上で説明されています(注:ratelimiting
はoperation_strategies
ではサポートされていません)。default_strategy
はservice_strategies
に含まれていないサービスに適用される包括的なサンプリング戦略を定義します。
上記の例では
- サービス
foo
のすべての操作は確率0.8でサンプリングされ、操作op1
とop2
はそれぞれ確率0.2と0.4で確率サンプリングされます。 - サービス
bar
のすべての操作は秒あたり5トレースでレート制限されています。 - 他のすべてのサービスは
default_strategy
で定義された確率0.5でサンプリングされます。 default_strategy
には、操作ごとの共有戦略も含まれています。この例では、確率0を使用してすべてのサービスの/health
エンドポイントと/metrics
エンドポイントでトレースを無効にします。これらの操作ごとの戦略は、設定にリストされていない新しいサービスと、fooサービスとbarサービスに適用され、これらの2つの操作に独自の戦略を定義していない場合。この例では、確率0を使用してすべてのサービスの/health
エンドポイントと/metrics
エンドポイントでトレースを無効にします。
適応サンプリング
Jaeger v1.27以降。
適応サンプリングはサービスから受信したスパンを観察し、収集されたトレースのボリュームが--sampling.target-samples-per-second
に一致するように、各サービス/エンドポイントの組み合わせのサンプリング確率を再計算することによってjaeger-collectorで機能します。新しいサービスまたはエンドポイントが検出された場合、エンドポイントを通過するトラフィックに適したレートを計算するために十分なデータが収集されるまで、最初は--sampling.initial-sampling-probability
を使用してサンプリングされます。
適応サンプリングでは、観測されたトラフィックデータと計算された確率を格納するためにストレージバックエンドが必要です。現時点では、memory
(オールインワン展開用)、cassandra
、badger
、elasticsearch
、opensearch
がサンプリングストレージバックエンドとしてサポートされています。
既定では、アダプティブサンプリングは、SPAN_STORAGE_TYPE
で指定されたバックエンドを使用してデータを格納しようとします。ただし、SAMPLING_STORAGE_TYPE
を使用して、2 番目のタイプのバックエンドを指定することもできます。たとえば、SPAN_STORAGE_TYPE=elasticsearch SAMPLING_STORAGE_TYPE=cassandra ./jaeger-collector
は、設定された elasticsearch クラスターにスパンデータを格納し、設定された cassandra クラスターにアダプティブサンプリングデータを格納しようとします。つまり、単一のタイプの2つの異なるバックエンドにスパンとアダプティブサンプリングデータを格納することはできません。
このブログ投稿 を読み、アダプティブサンプリングエンジンについて詳しく学びましょう。