Dev Study
AWSサービスの内部原理 コース

72. トレースIDはリレーのバトンである — 相関IDが分散システムに因果の鎖を通す

1本のリクエストが複数のサービスをまたいで走るとき、X-Rayがどうやって「これは全部同じリクエストだ」と束ね直すのかを、IDがヘッダで運ばれていく様子から図で追っていきます。

① なぜ「後から突き合わせる」しかないのか

1本のリクエストユーザーから届く
各自が自分のログを書く
API Gateway別プロセス
Lambda A別プロセス
Lambda B別プロセス
因果を復元したい
ログの山バラバラに書かれる
共有メモリで状態を持てない
どれが同じ?突き合わせる目印が必要
  • 各サービスは独立したプロセスとして動く。疎結合になるほど全体像が見えなくなる問題が、ログの世界でそのまま現れる。
  • プロセスが分かれている以上、後からログを突き合わせる以外に因果を復元する手段がない。

バラバラのプロセスが残すログを1本のリクエストとして再構成するには、全員が同じ目印を書き残すしかない。これが相関ID(correlation ID)というCS基礎で、X-Rayのすべての仕組みはこの1点に立っている。

② 入口でバトンが生まれる — トレースIDの割り当てと伝搬

クライアントヘッダなし/あっても信用しない
X-Amzn-Trace-Id を付与して下流へ
入口サービス最初のX-Ray対応サービス
トレースIDはここで1回だけ生成
同じヘッダで伝搬
下流サービスヘッダを読み取り付け直す
さらに下流全員が同じRootを共有
  • 公式の表現では「The first supported service that the HTTP request interacts with adds a trace ID header to the request, and propagates it downstream(最初にリクエストと接触したX-Ray対応サービスがトレースIDヘッダを追加し、下流へ伝搬する)」。
  • ヘッダ名は X-Amzn-Trace-Id。SDKがこのヘッダを読み、レスポンスにも含める。
  • ヘッダの例: X-Amzn-Trace-Id: Root=...;Parent=...;Sampled=1

トレースIDはリレーのバトンだ。入口で1本だけ生まれ、あとは各走者(サービス)がHTTPヘッダという手渡しで次へ運び続ける。バトンを運ぶ手法そのものは、API Gateway編で見た「ヘッダはメタデータの通り道」の応用にすぎない。

③ バトンの中身 — ヘッダの3フィールドとIDに埋まった時刻

トレースヘッダX-Amzn-Trace-Id
Rootをさらに分解(ハイフン区切りの3部)
RootトレースID全体
Parent呼び出し元セグメントID
Sampled記録するかの決定(1=する)
時刻部の例
バージョン常に 1
元リクエスト時刻Unixエポック秒・16進8桁
一意識別子96ビット・16進24桁
58406520(16進)= 1480615200秒 = 2016/12/1 10:00 PST
  • 公式仕様では trace_id は「ハイフンで区切られた3つの数」。(1) バージョン番号は 1、(2) 元リクエストの時刻をUnixエポック秒で16進8桁、(3) 96ビットのグローバル一意識別子を16進24桁。
  • Parent は呼び出し元セグメントのID(64ビット=16進16桁)。Sampled は 0/1 のサンプリング決定。
  • セキュリティ注記: trace_id はレスポンスヘッダで見えるため、将来のIDを攻撃者に計算されないよう「secure random algorithm」で生成すること、とドキュメントは明記する。
  • Lambda 等が Lineage=... を追記することがあるが、これは内部処理用で直接使うべきではない。

バトンには「どのリクエストか(Root)」「誰から渡されたか(Parent)」「記録に残すか(Sampled)」の3つが書かれている。RootのIDそのものに生成時刻が埋め込まれているのが巧妙な設計で、DynamoDB編で見た「キーの中に情報を持たせる」発想と同じく、IDが単なる乱数ではなく意味を運ぶ。

④ 各サービスは「セグメント」を送り、X-Rayが同じIDで束ね直す

入口の記録セグメント: host/request/response
下流の記録セグメント: 開始/終了時刻・errors
束ね直す
X-RayトレースIDでグループ化
可視化
1本のトレース同じリクエストの全セグメント
サービスマップ依存関係の地図を生成
  • 公式定義「X-Ray receives data from services as segments. X-Ray then groups segments that have a common request into traces」。
  • セグメントが記録するのは、ホスト(hostname/IP)、リクエスト(method・client address・path・user agent)、レスポンス(status・content)、作業(開始/終了時刻・サブセグメント)、発生した問題(errors/faults/exceptions、例外スタックの自動キャプチャを含む)。
  • セグメントドキュメントは最大64 kB。最小構成でも name・id・trace_id・start_time、そして end_time(処理が進行中の間は代わりに in_progress: true)が必須。

各走者はゴール後に自分の走行記録(セグメント)を提出するだけ。X-Ray側が「同じトレースIDのものは同じリクエスト」という一点で全記録を束ね直し、1本のトレースとサービスマップに再構成する。束ねる鍵がトレースIDなのは、DynamoDB編のパーティションキーが「同じキーは同じ場所」を決めたのと同じ原理だ。

⑤ セグメントの中を刻む — サブセグメントと木構造

セグメント自サービスの作業全体
サブの中にサブ(ネスト可)
AWS SDK呼び出しnamespace=aws → DynamoDB など
外部HTTP APInamespace=remote
SQLクエリ所要時間を計測
木構造親子関係からコールツリーを復元
  • サブセグメントは「downstream callsのより細かいタイミング情報と詳細」を提供し、AWSサービス呼び出し・外部HTTP API・SQLデータベースのいずれかを記録できる。
  • 任意のコードブロックを囲む独自サブセグメントも定義可能。サブセグメントはサブセグメントを含められる(ネスト)。
  • id は各サブセグメントも64ビット=16進16桁。

セグメントを内側から下流呼び出しごとに刻んだものがサブセグメント。親子でぶら下がる入れ子構造は、そのまま木構造であり、これを辿ればリクエストが呼び出したサービスのコールツリーが復元できる。「ばらばらのログ」が、時間軸を持つ1本の木に組み上がる瞬間だ。

⑥ トレースを送らない相手も地図に現れる — 推測セグメント

自サービス計装済み
呼び出し側の記録から逆算
DynamoDB自分ではセグメントを送らない
地図に反映
推測セグメントinferred segment をX-Rayが生成
ノードが出現地図にDynamoDBが描かれる
非計装の相手ではノードもエッジもサブセグメント由来
  • 公式「For services that don't send their own segments, like Amazon DynamoDB, X-Ray uses subsegments to generate inferred segments and downstream nodes on the trace map」。
  • もし下流も計装済みなら、下流が送る本物のセグメントが推測セグメントを置き換える。その場合、ノードは下流サービス自身のセグメント情報を、エッジ(2ノード間の線)は上流のサブセグメント情報を使う。
  • 上流視点は往復レイテンシ(移動時間込み)を、下流視点は正確な作業開始/終了を記録する。

トレースに対応していないサービスでさえ、呼び出した側の記録から逆算して地図に描かれる。バトンを持てない相手の区間も、渡した側の記憶から復元する——これで依存関係の地図に穴が空かない。

⑦ 検索・偽造・寿命 — 運用の3つの約束事

アノテーション索引される → filter式で検索可
1トレース50個まで
メタデータ索引されない記録用
オブジェクト/配列もOK
入口で剥がす
外部ヘッダクライアントがX-Amzn-Trace-Id付きで来る
集まったトレースの寿命は
信頼境界勝手に付けたID/サンプリング決定を除去
保持30日サービスグラフデータも30日
  • アノテーションは「filter expressionsで使うために索引されるkey-valueペア」で、X-Rayは1トレースあたり最大50個を索引する。
  • メタデータは「索引されない」key-valueで、値は任意の型(オブジェクト/配列可)。
  • セキュリティ: トレースヘッダはX-Ray SDK・AWSサービス・クライアントリクエストのいずれからでも来うるため、「Your application can remove X-Amzn-Trace-Id from incoming requests(アプリは受信リクエストからこのヘッダを除去できる)」——ユーザーが勝手にトレースIDやサンプリング決定を付けてくる問題を避けるための定石。
  • トレースデータ・サービスグラフデータともに保持は30日。

索引される検索用の目印(アノテーション、50個まで)と、索引されない記録用の付箋(メタデータ)を使い分ける。外部から来たバトンは信用せず入口で剥がし、集まったトレースは30日で消える。相関IDの仕組みは、検索性・信頼境界・保持期限という運用の現実と一緒に初めて完成する。

公式ドキュメントで詳しく ↗