見出し画像

OPENREC.tvにおけるOpenTelemetryの活用

はじめに

サイバーエージェント新卒入社、CyberZ開発本部SREの高垣です。
普段の業務としては、OPENREC.tvのインフラ基盤であるAWS, k8sの基盤開発、動画配信基盤の開発、他プロダクトのインフラ基盤の開発を行なっています。
今回は特に分散トレーシングとOpenTelemetryに焦点を当てて、本番運用し始めて一年以上経ちましたので、当プラットフォームにおける活用事例を紹介したいと思います。

可観測性

可観測性(Observability)とは、複雑化したシステムの内部情報を人にとって理解のしやすいデータとして出力して問題発見を容易にするためのものです。
そのアプローチとしてログ、メトリクス、トレースの3つの情報を出力する事が一般的なアプローチとなっています。
クラウドネイティブなインフラ基盤上では複数のマイクロサービス、サービスごとに独立したデータベース、外部サービスとの連携などを行なって一つのサービスが実現されています。
OPENREC.tvでも例外ではなく、複数のサービスで連携を行なってサービスの提供を行なっています。

分散トレーシング

外部からのリクエストを起点(トレース)にして、各サービスで処理(スパン)にどれくらいの時間を要したかをサービス間を横断して記録する事で、マイクロサービスで構築されたシステムの可観測性を得るための技術です。

OpenTelemetry

OpenTracingとOpenCensusプロジェクトを統合したCNCFでホスティングされるプロジェクトです。テレメトリ(トレース、メトリクス、ログ)を収集して処理、出力を行うベンダー依存しないエコシステムです。

OpenTelemetry SDK

OpenTelemetry SDKとは、テレメトリを計測、生成、集約、出力するための各言語に対応したツール群です。各言語の対応状況は下記です。
https://opentelemetry.io/status/
分散トレーシングにおいては、リクエストを受け取った時のトレースIDの生成(受け取り)、データベースへのクエリ、他サービスへの呼び出しを行なったなどのスパンの生成、トレースIDのヘッダーによる伝搬、バックエンドサービスへのデータの出力を実現する事が可能です。

引用: https://opentelemetry.io/docs/concepts/otel-concepts/

コンセプト


上記のようにService AからService Bへの呼び出しが行われるリクエストがService Aに到達した場合にOpenTelemetry SDKは以下のように処理する

  1. Service Aはリクエストを元にヘッダーを確認して、親となるサービスが存在しているかによって、トレースの起点を自身とするかどうかを決定する(Propagatorの設定にもよります)

    1. 存在する場合、トレースIDを引継ぎService A及び下流サービスで行う処理を今後は引き継いだトレースIDのスパンとして記録する

    2. 存在しない場合、トレースIDを生成してService A及び下流サービスで行う処理を今後は生成したトレースIDのスパンとして記録する

  2. 処理をスパンとしてトレースIDに紐付けて記録

  3. Service BへのリクエストをスパンとしてトレースIDに紐付けて記録

  4. Service BはService Aのリクエストのスパンとしてヘッダーによって伝搬されたトレースIDに紐づけて処理を記録

  5. 各サービスでリクエストが終了したら指定しているバックエンドサービス(OpenTelemetry Collector, zipkin, jaegerなど)にトレースデータを出力する

OpenTelemetry Collector

受け取ったデータを多様なプロトコルで集約(Receiver)、データ加工(Processor)、ベンダーやOSSのバックエンドにデータを送出(Exporter)する事を可能にします。

引用: https://github.com/open-telemetry/opentelemetry-collector/blob/main/docs/design.md

OpenTelemetry Collectorはコアな機能に加えて、拡張性が非常に高いアーキテクチャとなっています。
https://github.com/open-telemetry/opentelemetry-collector-contrib

補足

Service Meshを用いて分散トレーシングを実現する方法もありますが、Proxyで計測するためサービス内部の処理単位ではなく、このサービスへのリクエストにこれだけ時間がかかったという情報しか出力できなく、またService A → Service B → Service Cみたいに3つ以上のサービス間はヘッダーが伝搬できないため、トレースできなくなってしまうのでOPENREC.tvにおけるユースケースとして候補から外しました。

X-Ray

AWSのフルマネージドの分散トレーシングのバックエンドサービス。
データを送出するだけでサマリーや分析を自動的にやってくれたりします。 当初はGrafana tempoで運用を開始しましたが、運用コストと金銭的コストを鑑みてX-Rayに切り替えました。 X-Rayをバックエンドとして使用する場合にはTraceIdのフォーマットが独自仕様になるので、その仕様に合わせる必要があります。(ALBで生成されるx-amzn-trace-idヘッダーのフォーマット)

弊社における活用事例

OPENREC.tvのバックエンドサービス

OPENREC.tvのバックエンドサービスにおける構成は以下のようになっています。

以下のように使用しているサービス一覧を一目で確認する事ができ、スループットやレイテンシ、障害の発生箇所などを迅速に確認する事が可能となっており、問題となったトレースを特定して各サービスの各処理にどのくらいの時間を要したか、その際にどのようなクエリをデータベースに発行したか、どのようなAPIサービスをコールしたか、エラーとなった場合はどのようなスタックトレースが出力されているかなどを確認する事が可能となっています。

サービスマップ
トレース
トレースの詳細

OPENREC.tvでは多くのアラートがSLOに基づいて運用されており、レイテンシーのSLO違反を検知した場合などに対象のURIパスやサービスなどから検索してボトルネックとなった箇所を早急に突き止めたり、可用性のSLO違反を検知した場合には障害発生の根本原因となるサービスや処理がどれかをサービスマップから色が変わるので、一目で確認する事ができます。また定期的に低速なAPIのパフォーマンスの改善に役立てています。

OPENREC.tvの動画配信サービス

OPENREC.tvでは動画配信サービスは完全に分離して開発やインフラの構成などが行われており、上記で説明したOPENREC.tvの構成とは異なります。
動画配信に使用する動的トランスコーダーは、1つのコンピューティングノードを複数人の配信者で共有するようになっており、CPU使用率の高騰やメモリの空き容量だったりが非常に重要となっているため監視は欠かせない要素となっています。
また多大なコンピューティングリソースを使い、いつでも高画質、低遅延で安定した配信を可能にするためスケールの効率を重視して以下のように独自のコントロールに基づいて実施しております。

動画配信基盤のスケールコントロール

そのため、配信中か停止中かどうかなどを正確に検知してモニタリングをするために、拡張性の高いOpenTelemetry Collectorの中でPrometheusとカスタマイズしたService Discoveryを動かして、サービスの状態を検知し、ビットレート、動画のメタ情報、ドロップしたフレーム、言語やミドルウェア固有のメトリクスといった項目の監視を実現しています。

動画配信基盤の監視

まとめ

  • X-Rayがサービス内容やデータ量に対して非常に安価で使い勝手がよい

  • レイテンシーや可用性のSLO違反を検知した時に原因不明だったりした事が解決したり、解決するまでの所要時間の短縮につながった

  • Microserviceで言語がばらばらだったりする場合にOpenTelemetry SDKの導入が少し大変

この記事が気に入ったらサポートをしてみませんか?