本文へスキップ
mcpd
デーモンなし

リレーとリージョン

エージェントの隣にコレクターを置き、リージョン間の区間は再試行付きで渡ります。

リレーとは

mcpd relay は、同じバイナリを、自分では何も保存しない コレクターとして動かします。デーモンが受け付ける HTTP の取り込み リクエストをすべて受け付け、リクエストをディスク上のスプールに書き、 送信元に応答してから、--upstream が示すデーモンへその リクエストを送ります。ストアは開きません。

エージェントが動く各リージョンに 1 つずつ置いてください。送信元は数ミリ秒 先のコレクターと話すことになり、リージョン間の区間は、各エージェントが それぞれ渡るのではなく、リレーが再試行付きで渡ります。

上流が 2 つあるエッジのリレー

mcpd relay \ --ingest-key $INGEST_KEY \ --upstream http://mcpd.eu.internal:4317 \ --upstream http://mcpd.us.internal:4317
リレー
$ MCPD_UPSTREAMS=http://mcpd.eu.internal:4317,http://mcpd.us.internal:4317 mcpd --data /data/mcpd.db config | grep ^relayrelay           2 upstream(s) in order, http://mcpd.eu.internal:4317, http://mcpd.us.internal:4317; each sender's key passed on; spool at /data/mcpd.spool/relay, 1024 MiB$ curl -s -D - -o /dev/null localhost:4317/v1/ingest -H "content-type: application/json" -d @batch.json | grep -e ^HTTP -e mcpd-relayHTTP/1.1 202 Acceptedmcpd-relay: spooled$ curl -s localhost:4317/v1/ingest -H "content-type: application/json" -d @batch.json{"accepted":0,"duplicate":0,"rejected":0}

何を応答するか

プローブ以外のパスなら、どのパスへの POST も受け付けます。OTLP のパス /v1/traces、/v1/logs、/v1/metrics は、OTLP の partialSuccess とともに 200 を返します。 OpenTelemetry のエクスポーターが期待する応答です。それ以外のパスは、 ヘッダー mcpd-relay: spooled と本文 {"accepted":0,"duplicate":0,"rejected":0} とともに 202 を返します。リクエストは預かられ、届けられます。本当の件数はまだ それを見ていない上流のものです。どの SDK も、2xx はすべて成功として読みます。

リレーは何かを書く前に --ingest-key を自分で確かめ、 --max-body-bytes と --request-timeout-seconds を デーモンと同じように適用します。応答を送る前に、リクエストはスプール <spool-dir>/relay に入っています。

配送とフェイルオーバー

4 つのワーカーがスプールを送ります。各リクエストは、--upstream の順で、待機中でない最初の上流に送られます。再試行できる失敗があると、 その上流はバックオフとジッターで、または Retry-After が示す あいだ待機に入り、リクエストはすぐに次の上流へ送られます。待機が終わると 再び第一の上流が先に試されるので、トラフィックはひとりでにそこへ戻ります。

400 のような最終的な拒否は、次の上流には送られません。次の上流も同じ バイト列を拒否するからです。リクエストはスプールディレクトリーの dead/ に移され、数えられます。

二重に数えない

配送は少なくとも 1 回で、再送は 1 回だけ保存されます。どのリクエストも Idempotency-Key ヘッダーを持ちます。送信元が送ったならその キー、そうでなければ relay- の後にパス、コンテンツエンコー ディング、本文のダイジェストを続けたものです。デーモンの取り込み口は どれもこのヘッダーを尊重し、ネイティブのバッチ本文にあるキーはヘッダーより 優先されます。タイムアウトの後にリレーが再送したリクエストや、第一の上流が 受け取ったのに応答が失われ、第二の上流へ送ったリクエストは、重複として 認識され、そう報告されます。

キー

--upstream-key があれば、リレーはそのキーを Bearer トークン として、すべての上流に提示します。なければ、送信元の Authorization または x-mcpd-key ヘッダーが、 リレーのユーザーだけが読めるファイルに、スプールしたリクエストとともに 保たれ、そのまま渡されます。後者の形なら、各送信元のプロジェクトと スコープが、上流からもそのまま見えます。

背圧と準備状態

スプールの大きさは --spool-max-bytes で制限され、設定しな ければリレーは 1 GiB です。いっぱいになると、リクエストは 503 と Retry-After: 5 で拒否されます。どの SDK も OpenTelemetry の エクスポーターもこれを再試行するので、リレーがデータを捨てるのではなく、 送信元がデータを持ち続けます。

/healthz は常に 200 を返します。/readyz の 応答は次のとおりです。

  • 上流に届くあいだは 200 ok。
  • 直近 30 秒に、どの上流も /readyz に応答せず、配送も受け 取っていなければ、detail 付きの 200 degraded。 上流は 5 秒ごとに確かめられます。
  • スプールがいっぱいのとき、またはどの上流にも届かずスプールが 80% 以上 埋まっているときは 503。

そのため、ロードバランサーはバッファーしているリレーには送り続け、もう 受け取れないリレーからはトラフィックを移します。

リレーのメトリクス

メトリクス種類意味
mcpd_relay_accepted_totalcounterスプールに書かれたリクエスト
mcpd_relay_refused_full_totalcounterスプールがいっぱいで、503 で拒否されたリクエスト
mcpd_relay_failovers_totalcounter最初以外の上流に届けられたリクエスト
mcpd_relay_dead_letter_totalcounter上流が最終的に拒否し、dead/ に移されたリクエスト
mcpd_relay_spool_entriesgaugeスプールで待っているリクエスト
mcpd_relay_spool_bytesgaugeスプールが持っているバイト数
mcpd_relay_spool_oldest_secondsgauge待っている最も古いリクエストの経過時間、なければ 0
mcpd_relay_delivered_totalcounter上流が受け付けたリクエスト。ラベルは upstream と order
mcpd_relay_failed_attempts_totalcounter上流が受け付けなかった試行。ラベルは同じです
mcpd_relay_upstream_upgauge上流が直近 30 秒に応答していれば 1、そうでなければ 0
mcpd_uptime_secondsgaugeこのプロセスが起動してからの秒数

mcpd_relay_failovers_total が増えているなら、第一の上流が 失敗していて、第二の上流がそのトラフィックを運んでいます。 mcpd_relay_spool_oldest_seconds は、配送がどれだけ遅れて いるかを示します。

複数のリージョン

1 つまたは複数のリージョンで、複数のデーモンのレプリカを 1 つの Postgres か ClickHouse のストアに向けて動かします。実行は Postgres に置く (--runs-data postgres://...)か、オフにします。組み込みの実行 ストアは 1 つのプロセスに属するからです。各レプリカの /readyz は、ストアに届くかどうかをすでに反映しています。各 リージョンでその前にリレーを置き、--upstream には最も近い デーモンを最初に、別のリージョンのデーモンを 2 番目に並べてください。

レプリカが 2 つ以上になると、4 つの設定のふるまいが変わります。

  • 冪等性キーは共有ストアに置かれるので、別のレプリカに届いた再送も認識 されます。Postgres は、バッチと同じトランザクションでキーを記録します。
  • 1 分あたりのクォータの上限は、レプリカごとに数えられます。望む上限を レプリカの数で割ってください。
  • ライブ採点、テールサンプリング、モニターのアラートは、一度に 1 つの レプリカで動きます。レプリカは共有ストアのリースで交代します。持ち主は 処理のたびにリースを更新し、停止するときに手放します。持ち主が止まれば、 3 回の処理のうちに別のレプリカが引き継ぎます。どのレプリカも自分の モニターと目標を評価するので、どれもモニター API に答えますが、webhook を 送るのは持ち主だけです。すべてのレプリカで同じように設定してください。
  • 観点の分析は、それを設定したすべてのレプリカで動きます。1 つのレプリカに 設定してください。

デプロイの例

deploy/docker/docker-compose.multi-region.yml は、1 台の マシンで Postgres、2 つのデーモン、1 つのリレーを起動します。構成全体を 試せる形にしたものです。

Helm チャートは mode: relay を受け付けます。 deploy/helm/examples/ にある 3 つの values ファイルは、それぞれ 1 つのリージョンを表します。region-core.yaml、 region-standby.yaml、region-edge-relay.yaml で、 最後のものはリレーだけを動かすリージョン用です。

次に

  • データを他のベンダーへ複製する: 転送。
  • プローブ、メトリクス、ストア: 運用。
  • すべてのフラグ: 設定。