New Relicディストリビューティッド (分散) トレーシングの仕組み

New Relicのディストリビューティッド(分散)トレーシングのしくみについての技術的な詳細は次のとおりです:

ディストリビューティッド(分散)トレーシングの設定の概要については、概要: ディストリビューティッド(分散)トレーシングを有効にするをご覧ください。

トレースサンプリングのしくみ

当社は、次のタイプのサンプリングを提供しています:

Headベースのサンプリング(標準のディストリビューティッド(分散)トレーシング)

ディストリビューティッド(分散)トレーシングでは、大量のデータをレポートし処理する必要があります。そのため、データのレポートに限界を定めており、サンプリングを使用して抽出した活動の代表サンプルを把握します。サンプリングされたデータが大きなデータセットの特徴を表し、トラブルシューティングに必要な詳細が分かることが理想的です。

標準のディストリビューティッド(分散)トレーシングでは、トレースのすべてのスパンの到着前に、個別のスパンにフィルタを適用します。これはheadベースのサンプリングと呼ばれます。つまり、スパンを受け入れるかどうかの決定は、フィルタリングプロセスの最初(開始時)に行われます。

標準のディストリビューティッド(分散)トレーシングでのheadベースのサンプリングの詳細は次のとおりです:

適応サンプリングプロセス(APMエージェント)

APMエージェントはサンプリングを使用して、システム活動の代表的なサンプルを把握します。適応サンプリングのしくみは次のとおりです。(AWS Lambda監視は別のサンプリングプロセスを使用します。)

ディストリビューティッド(分散)トレースでの最初のサービスについては、サンプルとして10件のリクエストが選択されます。そのサービスのスループットを使用して、リクエストのサンプル取得の頻度を調整します。この点については、以下で詳細に説明します。

ディストリビューティッド(分散)トレースで最初に監視するサービスは、トレース元と呼ばれます。トレース元は、トレースが無作為になるようリクエストを選択します。この決定は、そのリクエストがタッチしたダウンストリームのサービスに伝搬されます。リクエストが完了したら、そのリクエストがタッチしたサービスにより作成されたすべてのスパンを、完全なエンドツーエンドのトレースとしてUIで使用できます。

APMエージェントでは、1分間に収集されるトランザクションの数(この数はエージェントにより異なります)と、1分間に収集されるスパンの数(エージェントインスタンス1件につき1000)が制限されています。この制限に従うため、トレース元でのトレースのデフォルト数は1分当たり10トレースとなっています。

その期間の代表的なサンプルを取得するため、APMエージェントは、1分間の10トレースの取得に広がります。正確なサンプリングレートは、前の1分間のトランザクション数により異なります。レートは、トランザクションのスループットの増減に対応します。

たとえば、前の1分間のトランザクション数が100だった場合、エージェントはトランザクション数を同様に100と推定し、トランザクション10件当たり1件を選択してトレースします。

スパンの制限とサンプリング(APMエージェント

headベースのサンプリングを使用するAPMエージェントのインスタンスには、1分当たり1000スパンの制限があります。エージェントは、ディストリビューティッド(分散)トレースの一環としてサンプリングされるものとして印の付いたすべてのスパンを保存しようとします。

多くの分散型システムで、平均的なマイクロサービスはリクエスト1件当たり10~20のスパンを生成します。この場合、エージェントスパンの限度は選択したすべてのスパンに対応し、そのサービスにはトレースの詳細が付けられます。

ただし、サービスへのリクエストで多くのスパンが生成され、エージェントスパンの限度に達する場合があります。よって、そのサービスについてトレースに詳細がない場合があります。この点についての1つの解決策が、エージェントをカスタムインストゥルメントし、レポートするアクティビティを減らしてレポートするスパンを減らすというものです。

ブラウザスパンのレポート

Browserはすべてのスパンをレポートしますが、APM はスパンの比率のサンプリングを行います。つまり、バックエンドスパンよりブラウザスパンの方が多い可能性が高く、それによりバックエンドスパンからブラウザスパンの接続が解除される場合があります。フロントエンドスパンとバックエンドスパンを含むトレースのクエリに関するヒントについては、ブラウザスパンデータを検索をご覧ください。

トレースレートの制限

上記のサンプリング方法でもまだトレースデータの量が多すぎる場合は、受信後にトレースのサンプリングを行うことによって流入データを制限することができます。この決定をトレースレベルで行うことによって、トレースのフラグメント化(トレースの一部のみを受け取る)を避けることができます。

このプロセスは適応サンプリングと同様に機能します。1分間に受け取った合計スパンが集計されます。受け取ったスパンが多すぎる場合は、次の1分間に受け取るスパンを少なくして、フローティング平均スループットレートを達成することができます。

Tailベースのサンプリング(Infinite Tracing)

Tailベースのサンプリングは、ディストリビューティッド(分散)トレーシングで使用できる追加オプション製品であるInfinite Tracingで使用できます。Infinite Tracingではtailベースのサンプリングを使用して、スパンデータの100%を受け入れ分析します。

Tailベースのサンプリングでは、フィルタリングの決定は、トレースのすべてのスパンの到着後の処理の最終時点で行われます。エラーや異常なレイテンシなどの最も実行可能なデータを含むトレースのみが、UIで表示するために転送されます。

アーキテクチャ

Infinite Tracingについては、エージェントまたはインテグレーションは、すべてのインストゥルメントされたスパンをTrace Observerに送信します。トレースオブザーバーは、New Relic Edgeと呼ばれるAWS上のサービスのクラスタに存在するディストリビューティッド(分散)トレーシングサービスです。

お客様のスパンのみがトレースオブザーバーに移動します - メトリックスやカスタムイベント、トランザクショントレースなどのその他すべてのデータは通常のルートでNew Relicに送信され、ローカルサンプリングの対象となります。

データの送信先のAWSリージョンの一意のトレースオブザーバーのエンドポイントを設定します。AWSリージョン1つにつき、複数のエンドポイントをリクエストできます。エンドポイントは、特定のワークロードのトレースオブザーバーを表します。たとえば、単一のトレース(リクエスト)からのすべてのスパンは、そのエンドポイントに移動する必要があります。

次の2つのアーキテクチャ図をご覧ください:1つは、APMエージェントを使用する場合の、またもう1つはOpenTelemetryエクスポーターのようなNew Relicインテグレーションを使用する場合のデータの流れを示します。

データの流れを示す、次の2つの図をご覧ください:1つはエージェントについて、もう1つはInfinity Tracingのあるインテグレーションについてのものです。

トレースオブザーバーは、そのトレースのスパンが到着している間、トレースをオープンのままにします。トレースの最初のスパンが到着すると、セッションは10秒間オープン状態となります。そのトレースの新規スパンが到着するたびに、有効期間は10秒にリセットされます。直近10秒以内に到着していないと思われるトレースは、自動的に期限切れとなります。

Tailベースのサンプリングのアルゴリズム

デフォルトでは、各トレースオブザーバーは3つのサンプラーにトレースを提供します。1つは期間の外れ値を探し、もう1つはエラーのあるトレースを探し、最後の1つはすべてのトレースタイプでランダムにサンプリングを試みます。各サンプラーは、基準に一致するトレースのターゲットパーセンテージを保持します。

各サンプラーの詳細は次のとおりです。

サンプラー 一致する基準 ターゲットのパーセント
期間

2つのアルゴリズムを使用して、期間の外れ値でトレースします。

  • ガウス(正規分布と99パーセンタイルの閾値を想定)
  • 離心率(分布がなく、クラスターに基づく閾値があると仮定)
100%
エラー エラーのあるスパンを少なくとも1つ含むトレース 100%
無作為 すべてのトレース 1%

一致基準がトレースと一致する場合、各サンプラーはトレースの形状を調べます。各トレース形状は、ルートスパンのエンティティ名とスパン名の一意の組み合わせ。これは、リクエストのエントリポイントを使用してトレースを分離する簡単な方法です。

形状が決定されると、サンプラーはターゲットのサンプリング パーセントに基づいてトレースを保持するか拒否するかを決定します。100% の場合、トレースは自動的に保持されます。それより少ない場合、サンプラーが特定のトレースを保持する確率は、ターゲットのパーセントによって決まります。たとえば、ランダム トレースのターゲット パーセントは 1 であるため、これらのトレースの 1% が保持されます。

Trace Observer はスループットのパーセンテージを使用するため、選択されるトレースの数はそのスループットによって異なります。

トレースデータの構成

ディストリビューティッド(分散)トレースの構造を理解すると以下のようなことに役立ちます。

ディストリビューティッド(分散)トレースには樹状構造があり、一つの「親」スパンを参照する「子」スパンをともないます。この図ではトレースの重要なスパン関係をいくつか示しています。

New Relicディストリビューティッド(分散)トレース構造図
この図では、ディストリビューティッド(分散)トレースのスパンが相互にどのように関連しているかを示しています。

この図では、以下のような重要な概念を示しています。

  • トレースのルート。 トレースにおける最初のサービスまたはプロセスは、ルートサービスまたはプロセスと呼ばれます。
  • プロセスの境界。プロセスはコードの論理的項目の実行を表します。プロセスの例にはバックエンドサービスまたはLambda関数などがあります。プロセス内のスパンは以下のどれかに分類されます。
    • 開始スパン:プロセスの最初のスパン。
    • 終了スパン:スパンが a)開始スパンの親である場合、あるいは b)http.またはdb.属性を有し、そのため外部呼び出しを表す場合、終了スパンと見なされます。
    • インプロセススパン:インターナルメソッド呼び出しまたは関数を表し、終了または開始スパンでないスパン。
  • クライアントスパン。クライアントスパンとは、別のエンティティまたは外部依存関係への呼び出しを意味します。現在、2つのクライアントスパンタイプがあります。
    • データストア。クライアントスパンにdb. (例:db.statement)の属性プレフィックスがあれば、データストアスパンに分類されます。
    • 外部。クライアントスパンにhttp. (例:http.url) の属性プレフィックスがあるか、別のプロセスで子スパンがあれば、外部スパンに分類されます。これはデータストアクエリではない外部呼び出しに対する一般的な分類です。
  • トレース持続時間。トレースの合計持続時間は、最初のスパンの開始から最後のスパンの終了までの時間の長さで決まります。

https://api.newrelic.com/graphiqlNerdGraph GraphiQLエクスプローラーを使用して、スパン関係データのクエリを行えます。

トレースデータの保存法

トレースデータの保存方法を理解するとご自分のトレースデータをクエリするのに役立ちます。

トレースデータは次のように保存します:

  • Spanスパンはディストリビューティッド(分散)トレースの一部であるオペレーションを表します。スパンが表すオペレーションにはブラウザ側のインタラクション、データストアクエリ、他のサービスの呼び出し、メソッドレベルのタイミング、Lambda関数が含まれます。一例として、HTTPサービスでは、HTTPリクエストの初めにスパンは作られ、HTTPサーバーがレスポンスを返した時に終了します。スパンの属性には、トレースの関係の詳細(traceId、GUIDなど)を含め、オペレーションに関する重要な情報(持続時間、ホストデータなど)が含まれています。スパン関連のデータについては、スパン属性を参照してください。
  • Transaction:トレース中のエンティティをエージェントが監視する場合、そのエンティティへのリクエストにより、単一のTransactionイベントが生成されます。トランザクションでは他のNew Relic機能と結びついたトレースデータを利用できます。トランザクション関連データについてはトランザクション属性をご覧ください。
  • コンテキスト連動メタデータ。トレースとスパン間の関係についての計算を表示するメタデータを保存します。このデータのクエリを行うには、NerdGraph GraphiQLエクスプローラー を使用します。

アプリケーション間でトレースコンテキストを渡す方法

当社はW3Cトレースコンテキスト基準をサポートしているので、ネットワークやサービス全体でトランザクションのトレースを簡単に行えます。ディストリビューティッド(分散)トレーシングが有効な場合、New Relicエージェントは、サービスの外部送信リクエストにHTTPヘッダーを追加します。HTTPヘッダは、海外旅行でのパスポートのように機能します:さまざまなネットワークやプロセス、セキュリティシステムを移動する際にソフトウェアのトレースを識別し、重要な情報を運びます。

ヘッダーには、後でスパンをリンクするのに役立つ次の情報も含まれます。トレースIDやスパンのID、New RelicアカウントのID、サンプリング情報などのメタデータ。このヘッダー情報は、ヘッダーの書式を認識しないミドルウェアやエージェントなどにより進捗が停止している場合を除き、トレースの各スパンとともに渡されます(図1を参照)。

プロプライエタリヘッダーで失敗したトレースの図。
図1

ヘッダー伝搬の問題に対処するため、当社は、2つの標準化されたヘッダーを必要とするW3Cトレースコンテキスト仕様をサポートしています。当社の最新のW3C New Relicエージェントは、この2つの必要なヘッダーの送受信を行い、デフォルトで以前のNew Relicエージェントのヘッダーの送受信も行います:

  • W3C(traceparent): トレース全体(トレースID)と呼び出しサービス(スパンID)を識別するプライマリヘッダー。
  • W3C(tracestate): ベンダー固有の情報を伝達し、トレースが行われた場所を追跡する必須ヘッダー。
  • New Relic(newrelic): 以前のNew Relicエージェントとの下位互換性を保つために送信される、元のプロプライエタリヘッダー。

3つのヘッダーを組み合わせることで、これらのタイプのエージェントでインストゥルメントされたサービス全体にトレースを伝搬できるようになります。

  • W3C New Relicエージェント
  • W3C以外のNew Relicエージェント
  • W3Cトレースコンテクスト対応エージェント

リクエストがW3Cトレースコンテクスト対応エージェントにのみタッチする場合、New Relicヘッダーをオフにすることを選択できます。newrelicヘッダをオフにする詳細については、エージェント設定ドキュメントをご覧ください。

以下のシナリオには、さまざまな種類の適切なヘッダ伝搬が示されています。

シナリオ1:3つのエージェントのタイプにタッチしてトレース

ここでは、リクエストが3つの異なるエージェントのタイプにタッチする際のヘッダのフローが示されています:

さまざまなコンポーネント間のトランザクションのトリップを示す図。
シナリオ2:W3C New Relicとミドルウェアでトレース

ここでは、W3C New Relicエージェントにより一部のミドルウェアに送信されたヘッダの組み合わせが示されています。

W3C準拠ミドルウェアでの適切なトレースを示す図。
シナリオ3:W3C準拠エージェントとNew Relicエージェントでトレース。

ここでは、W3C New Relicエージェントで認められた別のベンダーからの、2つの必要なW3Cヘッダが示されています。

W3C準拠ベンダーでの適切なトレースを示す図。

その他のヘルプ

さらに支援が必要な場合は、これらのサポートと学習リソースを確認してください: