10 yeas of experience of building mission critical Fintech system handling extremely high load
Walkthroughs, tutorials, guides, and tips. This story will teach you how to do something new or how to do something better.
これまで、バックエンドについて話すときは、通常、単一の大きなデータベースを持つ 1 つの大規模なアプリケーションを指し、監視にはログ記録で十分でした。現在では、 Kubernetesなどのテクノロジーのおかげで、マイクロサービスが標準となっています。アプリケーションの数は増え、分散化しているため、従来のログ記録では、アプリケーションのデバッグや問題の診断にはもはや十分ではありません。
監視を整理するための優れたソリューションは OpenTelemetry です。これは、分散システムのデバッグとパフォーマンス分析に使用できる最新のツールキットです。
この記事は、バックエンドの最適化に関する知識を広げたいと考えている IT プロフェッショナルを対象としています。以下では、OpenTelemetry とは何か、その主要な概念、そしてそれが解決する問題について詳しく説明します。OpenTelemetry によってバックエンド システムの監視とデバッグへのアプローチがどのように変わり、信頼性と効率性が向上するかに関心をお持ちの方は、ぜひお読みください。
大手テクノロジー企業が分散ログとトレースの課題に直面したのは2000年代後半のことでした。2010年にGoogleは論文を発表しました。
2014 年に Kubernetes が登場し、マイクロサービスやその他のクラウド分散システムの開発が大幅に簡素化されました。これにより、多くの企業がマイクロサービスでの分散ログとトレースの問題に直面するようになりました。分散トレースを標準化するために、CNCF と Google の OpenCensus プロジェクトによって採用された OpenTracing 標準が作成されました。
2019 年、OpenTracing プロジェクトと OpenCensus プロジェクトは、OpenTelemetry という名前で合併することを発表しました。このプラットフォームは、長年にわたって蓄積されたベスト プラクティスを組み合わせ、複雑さに関係なく、トレース、ログ、メトリックをあらゆるシステムにシームレスに統合できるようにします。
現在、OpenTelemetry は単なるプロジェクトではなく、テレメトリ データを収集および送信するための業界標準となっています。これは、Google や Microsoft などの市場をリードする企業や専門家のコミュニティによって開発およびサポートされています。このプロジェクトは進化を続け、統合と使用のプロセスを簡素化する新しい機能を獲得しています。
OpenTelemetry は、アプリケーションが外部とやり取りするために生成できる信号と、これらの信号を収集して視覚化し、アプリケーションとシステム全体の状態を監視する方法を定義する包括的なプラクティスとツールのセットです。信号には、トレース、ログ記録、およびメトリック収集の3 つの主要な種類があります。
**各コンポーネントを詳しく見てみましょう: \
OpenTelemetry では、操作コンテキストの概念が導入されています。コンテキストには主に、 `trace_id`
(現在の操作の識別子) や`span_id`
(サブリクエストの識別子。サブリクエストの再試行ごとに一意の`span_id`
が付与されます) などの属性が含まれます。
さらに、コンテキストには、アプリケーションがデプロイされているノード名や環境名 (prod/qa) などの静的情報を含めることができます。OpenTelemetry 用語ではリソースと呼ばれるこれらのフィールドは、検索を容易にするためにすべてのログ、メトリック、またはトレースに添付されます。コンテキストには、現在のエンドポイントの識別子 ( `http_path: "GET /user/:id/info"`
) などの動的データを含めることもできます。これは、ログ、メトリック、またはトレースのグループに選択的に添付できます。
OpenTelemetry コンテキストは、コンテキスト伝播プロトコルを使用して、異なるアプリケーション間で渡すことができます。これらのプロトコルは、すべての HTTP または gRPC リクエスト、またはキューのメッセージのヘッダーに追加されるヘッダー セットで構成されます。これにより、下流のアプリケーションはこれらのヘッダーから操作コンテキストを再構築できます。
コンテキスト伝播の例をいくつか示します。
B3-Propagationこれは、もともと Zipkin トレース システム用に開発されたヘッダー セット ( x-b3-*
) です。これは OpenTracing に採用され、多くのツールやライブラリで使用されています。B3-Propagation には、 trace_id
/ span_id
と、サンプリングが必要かどうかを示すフラグが含まれます。
W3C トレース コンテキストW3C ワーキング グループによって開発されたこの標準は、さまざまなコンテキスト伝播アプローチを 1 つの標準に統合し、OpenTelemetry のデフォルトになっています。これらの標準を適用する良い例としては、監視とデバッグの精度を損なうことなく、さまざまなテクノロジで実装されたマイクロサービスを通過するリクエストの実行を追跡することが挙げられます。
トレースは、複数のマイクロサービスを通るリクエストのパスのタイムラインを記録し、視覚化するプロセスです。
[画像出典: https://opentelemetry.io/docs/demo/screenshots/]
視覚化では、各バーは「スパン」と呼ばれ、一意の「span_id」を持ちます。ルート スパンは「トレース」と呼ばれ、リクエスト全体の識別子として機能する「trace_id」を持ちます。
このタイプの視覚化により、次のことが可能になります。
trace_id
とspan_id
を生成します。
一見シンプルに見えますが、ログは依然として問題を診断するための最も強力なツールの 1 つです。OpenTelemetry は、コンテキスト情報を追加することで従来のログを強化します。具体的には、アクティブなトレースが存在する場合、`trace_id` 属性と `span_id` 属性がログに自動的に追加され、トレースのタイムラインにリンクされます。さらに、ログ属性には、ノード識別子などの OpenTelemetry コンテキストからの静的情報や、現在の HTTP エンドポイント識別子 (`http_path: "GET /user/:id"`) などの動的情報を含めることができます。
`trace_id` を使用すると、現在のリクエストに関連付けられているすべてのマイクロサービスのログを見つけることができます。一方、`span_id` を使用すると、サブリクエストを区別できます。たとえば、再試行の場合、異なる試行からのログには異なる `span_id` が含まれます。これらの識別子を使用すると、システム全体の動作をリアルタイムで迅速に分析できるため、問題の診断が高速化され、安定性と信頼性が向上します。
メトリクス収集により、レイテンシ、エラー率、リソース使用量など、システム パフォーマンスに関する定量的なデータが提供されます。メトリクスをリアルタイムで監視することで、パフォーマンスの変化に迅速に対応し、障害やリソースの枯渇を防ぎ、ユーザーにとってのアプリケーションの高可用性と信頼性を確保できます。
Prometheus や Grafana などのメトリック ストレージおよび視覚化システムとの統合により、このデータの視覚化が容易になり、監視が大幅に簡素化されます。
[画像出典: https://grafana.com/blog/2021/06/22/grafana-dashboard-showcase-visualizations-for-prometheus-home-energy-usage-github-and-more/]
OpenTelemetry メトリック コレクターは Prometheus および OpenMetrics 標準と互換性があり、大きな変更を加えることなく OpenTelemetry ソリューションに簡単に移行できます。OpenTelemetry SDK を使用すると、メトリックとともに trace_id の例をエクスポートできるため、メトリックをログの例やトレースと関連付けることができます。
ログ、メトリック、トレースを組み合わせることで、システムの状態に関する包括的なビューが作成されます。
[画像出典: https://grafana.com/blog/2020/03/31/how-to-successfully-correlate-metrics-logs-and-traces-in-grafana/]
OpenTelemetry には、3 つのコア コンポーネントに加えて、サンプリング、バゲージ、操作コンテキスト管理の概念が含まれています。
高負荷システムでは、ログとトレースの量が膨大になり、インフラストラクチャとデータ ストレージにかなりのリソースが必要になります。この問題に対処するために、OpenTelemetry 標準には信号サンプリング (トレースとログの一部のみをエクスポートする機能) が含まれています。たとえば、リクエスト、長時間実行リクエスト、またはエラー リクエストのパーセンテージから詳細な信号をエクスポートできます。このアプローチにより、十分なサンプリングを行って統計を構築しながら、リソースを大幅に節約できます。
ただし、各システムが独立してどのリクエストを詳細に監視するかを決定すると、各リクエストのビューが断片化されてしまいます。一部のシステムは詳細なデータをエクスポートしますが、他のシステムは部分的にしかエクスポートしないか、まったくエクスポートしない場合があります。
この問題を解決するために、OpenTelemetry のコンテキスト伝播メカニズムは、`trace_id`/`span_id` とともにサンプリング フラグを送信します。これにより、ユーザー要求を受信した最初のサービスが要求を詳細に監視する必要があると判断した場合、他のすべてのシステムもそれに従います。それ以外の場合は、すべてのシステムがリソースを節約するために、信号を部分的にエクスポートするか、まったくエクスポートしません。このアプローチは「ヘッド サンプリング」と呼ばれ、要求処理の開始時にランダムに、またはいくつかの入力属性に基づいて決定されます。
さらに、OpenTelemetry は「テール サンプリング」をサポートしています。これは、すべてのアプリケーションが常にすべての信号を詳細にエクスポートしますが、中間バッファーが存在します。すべてのデータを収集した後、このバッファーは完全なデータを保持するか、部分的なサンプルのみを保持するかを決定します。この方法では、各リクエスト カテゴリ (成功/長時間/エラー) のより代表的なサンプルが可能になりますが、追加のインフラストラクチャ設定が必要です。
Baggage メカニズムを使用すると、任意のキーと値のペアをtrace_id
/ span_id
とともに送信し、リクエスト処理中にすべてのマイクロサービス間で自動的に渡すことができます。これは、ユーザー情報やランタイム環境設定など、リクエストパス全体で必要な追加情報を送信する場合に便利です。
W3C 標準に従って手荷物を送信するためのヘッダーの例: tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE,userId=1c30032v5
Baggage の使用例をいくつか示します。
userId
、 productId
、 deviceId
などのビジネス コンテキスト情報を渡すことは、すべてのマイクロサービスに渡すことができます。アプリケーションはこの情報を自動的にログに記録できるため、元のリクエストのユーザー コンテキストによるログ検索が可能になります。
SDK またはインフラストラクチャの特定の構成パラメータ設定。
ルーティング フラグ ロードバランサーがルーティングを決定するのに役立つフラグ。テスト中、一部のリクエストをモック バックエンドにルーティングする必要がある場合があります。荷物はすべてのサービスを通じて自動的に送信されるため、追加のプロトコルを作成する必要はありません。ロード バランサーでルールを設定するだけです。
Baggage によるパフォーマンスへの影響は最小限ですが、過度に使用するとネットワークとサービスの負荷が大幅に増加する可能性があることに注意してください。パフォーマンスの問題を回避するには、Baggage を通過させる必要があるデータを慎重に選択してください。
インフラストラクチャ レベルで OpenTelemetry を実装するには、OpenTelemetry バックエンドをアプリケーション アーキテクチャに統合し、データ集約用のインフラストラクチャを構成する必要があります。
このプロセスは次の 4 つの段階で構成されます。
アプリケーション統合最初の段階では、OpenTelemetry SDK がアプリケーションに直接統合され、メトリック、ログ、トレースを収集して、各システム コンポーネントのパフォーマンスに関するデータの継続的なフローを確保します。
エクスポータの構成収集されたデータは、アプリケーションからエクスポータを介して外部システムにルーティングされ、必要に応じて、ログ記録、監視、トレース、分析システムなどのさらなる処理が行われます。
集約と保存この段階では、データの正規化、追加情報によるデータの拡充、さまざまなソースからのデータのマージを行って、システムの状態の統一されたビューを作成する場合があります。
データの視覚化最後に、処理されたデータは Grafana (メトリックとトレース用) や Kibana (ログ用) などのシステムのダッシュボードとして表示されます。これにより、チームはシステムの健全性を迅速に評価し、問題と傾向を特定し、生成されたシグナルに基づいてアラートを設定できます。
アプリケーションと統合するには、使用しているプログラミング言語に適した OpenTelemetry SDK を接続するか、OpenTelemetry を直接サポートするライブラリとフレームワークを使用する必要があります。OpenTelemetry は、よく知られているライブラリから広く使用されているインターフェイスを実装しているため、ドロップイン置換が可能です。たとえば、Micrometer ライブラリは、Java エコシステムでのメトリック収集によく使用されます。OpenTelemetry SDK は Micrometer インターフェイスの実装を提供し、メインのアプリケーション コードを変更せずにメトリックのエクスポートを可能にします。さらに、OpenTelemetry は古い OpenTracing インターフェイスと OpenCensus インターフェイスの実装も提供しているため、OpenTelemetry へのスムーズな移行が可能です。
IT システムでは、OpenTelemetry は信頼性が高く効率的なバックエンドの未来への鍵となる可能性があります。このツールはデバッグと監視を簡素化し、アプリケーションのパフォーマンスと最適化を新しいレベルで深く理解する機会も提供します。OpenTelemetry コミュニティに参加して、バックエンド開発がよりシンプルで効果的な未来を形作りましょう。