はじめまして。CLのバックエンド開発をしている古谷です。
前回「CLライブキャスト配信におけるリアルタイム字幕機能の紹介」に引き続き、今回はリアルタイム性を実現するバックエンドの仕組みについて紹介したいと思います。
目次
Chat Serviceについて
CLのバックエンドは、マイクロサービスアーキテクチャを採用し、Kubernetesクラスタ上に構築されています。
今回は、リアルタイム字幕機能のリアルタイム通信の役割を担っているChat Serviceの仕組みについて説明します。
CLのライブキャスト配信におけるコメントと字幕はいずれもリアルタイム性を重視した設計になっています。
配信者と視聴者の円滑なコミュニケーションを実現するために、リアルタイム通信を活用しライブ配信と同期したコメント機能が開発されました。
その後、字幕機能ではライブ配信と字幕の同期時に、翻訳した字幕データを映像より早く視聴者へ送るためにリアルタイム通信が活用されています。
Chat Serviceが提供するリアルタイム通信の特徴は、視聴者がルーム1番 ~ ルームN番(UI上ではAREAと呼ぶ)に振り分けられるという点にあります。
視聴者からのコメントを間引くことなく適度な流量で配信者へ届けるための仕組みであり、多くの視聴者の接続を分散するための機構でもあります。
CLではリアルタイム通信に、iOS, Android端末からはgRPC Bidirectional streaming RPC、ブラウザからはServer-Sent Eventsを採用しています。
端末からの接続は、GCP Cloud Load Balancingを経由し、Chat Proxyにてルーム識別子をハッシュキーとしてenvoyのRing Hash方式によりChat Gatewayへ分散されます。
これにより、同じルームに接続している端末の処理をできるだけ同じサーバ上で処理しつつ、分散処理を実現しています。
異なるサーバへ分散接続された端末へメッセージを伝搬するためのポンプとして複数台のRedisを利用しています。
RedisはPub/Subの用途が主となるため、Cluster構成は利用せずに複数台並べルーム識別子による分散をしています。
ルームの機構により、視聴者が増加した場合でもルームを増やすことでルーム単位での処理性能を維持しつつ、多くの視聴者の接続を処理しています。
負荷対策
ライブ配信時には、瞬間的な大量接続が発生するため以下の対策を講じています。
接続数に応じたPodのスケールアウト
CLでは、モニタリングのためにDatadogを採用しており、各種リソースのメトリクスを集約しています。
Chat Serviceの接続数をメトリクスとしてDatadogで収集し、HPAで利用することで接続数に応じたPodのスケール調整を実現しています。
Nodeのスケールアウト遅延を回避
Chat Serviceのスケールアウト時、新たなNodeの起動に時間がかかると瞬間的な大量接続に対応できません。
CLでは、Pod Priority and Preemptionを利用し、Pod Priorityの低いPodを余分に起動することにより、事前にNodeの準備をしています。
Chat ServiceのPodがスケールアウトした際、Pod Priorityの低いPodを追い出すことで起動中のNodeへChat ServiceのPodを割り込ませることができるため、Nodeの起動遅延の影響を最小限に抑え、瞬間的な大量接続に対応しています。
Podの接続数制御
Kubernetesクラスタ上にChat Serviceを構築する際の最大の課題は、Podに対する接続数の制御でした。
Podへの接続が偏ってしまうと、一部のPodに負荷がかかり安定した性能を発揮できなくなります。
CLでは、Podに対する接続を均等にするため、接続数を超過したPodをシステム上から一時的に切り離す方式をとっています。
KubernetesのLiveness ProbeとReadiness Probe、およびGCLBからのヘルスチェックを接続数に応じたステータスで制御することで、接続数を超過したPodへ新たなトラフィックを制限しつつ、既存の接続を維持することを実現しています。
最後に
CLでは、配信者と視聴者の双方向のメッセージをリアルタイムに継なげ、臨場感のあるコミュニケーションの場を提供します。
今後も、CLは高品質なエンタテインメントコンテンツと共に、配信者・視聴者のコミュニケーションを体験できるデジタルコミュニケーションサービスとして進化し続けていきます。
最後まで読んでいただきありがとうございました。