TVer のクラウド インフラチームでインフラ周りを担当しています西尾です。
前回 までは直近で行っていた施策をご紹介していましたが、今回はもっと根本的なTVer の動画配信のインフラについてどうしようとしているかについて書いていければと思っています。
現在の動画配信については今までに何度かその構成について触れましたが、主にAWS 上でALB・ECSを主軸としたサービスを利用して稼働しています。
この構成についてはこれから移行する次世代構成との説明をわかりやすく区別するために、ここからはTVer アーキ1.0と仮称します。
現在のTVer の構成(TVer1.0)
では何故今のこのTVer アーキ1.0の構成からわざわざ変えるのかというと現在の構成では幾つかの問題を抱えていました。
サービス拡大により顕在化した問題
お陰様でTVer を皆様に提供し始めて今年で10周年となりその間に視聴ユーザーも右肩上がりで増えていきました。
その中でシステム構成や運用上で幾つかの問題点が積み上がって来ました。
Prewarmingの問題(事前暖気)
急激な地上波からの流入 によるトラフィック 増(枠切れ問題)
リリース方式、カナリア リリースの簡略化
開発環境の増加による運用コスト、費用の増加問題(多面化多すぎる問題、新規環境構築の高速化)
など主に上記のような問題が出てきました。
ではこれらについては一つ一つ説明して行きます。
Prewarming(事前暖気)に関連する問題
これについては過去 に取り上げています。
今年の春にLCUの一般提供を開始したタイミングでALBのPrewarming費用が急激に増えた事が発端となりました。
それまでALBのLCUを一時的に増やすことで予見される急激なトラフィック 増に対応していました。
これに関しては事前暖気が必要で人的な運用コストの問題でなんとかしようと考えていましたが、なかなか手が付かない状態でしたが、費用問題が新しく出たことで本腰を入れて対応が必要になりました。
この発端により運用コストと費用を下げるためにNLBを選択する流れとなりました。
ここではその内容について詳しくは触れませんが、ALBをNLBとNginx Routerに移行することで事前暖気の運用を無くし、そのタイミングで必要な数のLCUでスケールが行われることで費用を抑えることを目的とした構成変更を行いました。
そしてこの取り組みは既存の構成から移行したアーキになりましたのでTVer アーキ1.5と呼ぶことにしました。
NLB構成による変更箇所(TVer1.5)
このTVer アーキ1.5構成は既存の問題に対しての段階的なリアーキとなり、その他課題になっていた問題をまとめて解決出来るものではありませんでした。
ただNginxを挟んだことで別ラインで行っていたTVer 落ちないプロジェクトをここで取り組むことが出来ました。
TVer 落ちないプロジェクト(補足)
これは事の発端が前回の話で上がりましたDBメンテナンスによりサービス断が発生するので、それに対して根本的な取り組みをしようというのがこのプロジェクトの主旨になります。
DBにアクセス出来ない場合はアプリケーション側でどうにかするのが手段としてありますが、ただ今回の場合は各アプリケーションにフォールバックの変更を入れるのでは無く、また要件として一律に対応できる部分もありましたので、このプロジェクトではDBアクセス出来ない場合は個別にアプリケーションで対応せずにインフラ側でどうにかするという選択になりました。
要件として一律に対応とありますが、これは下記のように許容出来る部分がありました。
全てのAPI エンドポイントが対象では無く、TVer の配信サービスを提供続けるために必要となるコアな機能をターゲットとする
DBに接続できない場合、その取得するレコード情報は少し前の内容を返してもOK
そのため、これを実現するためにNginx + Lua + Redis構成を取ることでDBが落ちた場合でも少し古い情報ですが返す事ができるようになったのでサービスを継続的に提供出来るようになりました。
ただこの構成はまだQAテストが十分ではないので現段階ではまだ本番運用に入っていません。
しかし来年初めには本番運用を行う事ができると思いますので、皆様により安定したサービス提供を行えるようになるのではないかと期待しています。
これまでにTVer アーキ1.0/1.5の構成について取り上げましたが、ここからは来年から順次実施されるリアーキについて話をして行きます。
これはPrewarming以外の問題点についても真剣に取り組み問題点を解決することを目指した新しいインフラ環境になりこれがTVer アーキ2.0環境と呼ばれるものになります。
TVer アーキ2.0の説明に入る前に先程の現状の問題点で取り上げていない部分について説明して行きます。
急激な地上波からの流入 によるトラフィック 増(枠切れ問題)
これはTVer のサービスでずっと課題となっていました問題になります。
地上波コンテンツの放送終了に伴い、TVer 側に一気にユーザーが来ることで急激に負荷が上がることがあります。
今年で現在までで一番インパク トがあった枠切れは、それまでの視聴ユーザーが短時間(1分以内)に15倍ぐらいまで増えたコンテンツがありました。
現在までこのような枠切れにどのように対応しているかと言いますと、人気で枠切れの可能性があるコンテンツに関してはコンテンツの配信チームから情報をインフラ側に提供してもらい、その見積もりユーザー数から事前にインフラリ ソースをスケールすることで対応してきました。
これに関しては費用もかかりますが、何よりも人的な事前のスケーリング作業を行う必要があり、運用コストがかかっていました。
*事前のスケール作業の効率化は日々取り組みとしてやっており、一から全てのリソースをぽちぽち実施するということは流石にありません。またここで増やすリソースはLBのLCU以外のコンテナサービスやDBのレプリカの追加を対象としています。
そのため、このような事前作業を無くし運用負荷を下げるための施策が求められていました。
リリース方式、カナリア リリースの簡略化
大きな修正が入ったリリースを安定的に実施したいので、カナリア リリースについては弊社でも行っていました。
ただこのカナリア リリースについてはそこまで簡略化がされていなく、しかもこのリリースはALBの機能を利用して実現していましたのでNLB移行した事で部分的に出来なくなってしまいました。
そのためカナリア リリース出来るようにNginx側で実装することで一応それらしいリリースは出来るようにしましたがこの方式には問題点もありました。
それはこの方式のカナリア リリースの割合調整を行う場合は動的に実施することができず、Nginx Routerの入れ替えが必要になり、また実際リリースを行う開発者の体験が悪くこの方式はいつまでも取り入れる方式では無いと最初から分かっていました。
開発環境の増加による運用コスト、費用の増加問題(多面化多すぎる問題、新規環境構築の高速化)
複数の開発環境があることは珍しく無いと思いますが、弊社でも開発環境は複数存在しDevXX系と呼ばれて同時進行で機能開発を進めるために必須となっています。
ただこれに関しては、丸々環境が存在するので費用もかかり、まただからと言って必要な時に必要な環境を直ぐに作れるかというとそうでもなかったりします。
インフラに関してはTVer のサービスはCDKを利用しているのでコード化はしていますが、それはあくまで一つの機能の中で個別に定義している形となります。
そしてTVer のサービスに関しては複数のコンポーネント が協調して動いていますが、ただそれらはコードのレポジトリやCDKのスタックも違ったりして1箇所で集権的に管理されておらず、その上全てが自動的に協調してdeployできる状態にもなっていません。
そのため新規の環境構築するために自動化を一時期取り組んでいましたが、全ての自動化が難しく手作業も混在して環境構築に現状時間がかかっています。
*それでも昔は1週間とか1環境の追加にかかっていましたが、1.5日ぐらいに短縮はされています。
またTVer サービスをちゃんと動かすためには複数のコンポーネント が必要であり、それが問題を複雑化しています。
新環境の要件
上記のように複数の課題があり、それを踏まえてTVer アーキ2.0ではこれだけは譲れない解決すべき問題と目指すべきスケール目標を設定しました。
LB・コンテナのスケールの短縮(1分以内) Must
限定的なリソースの事前増強 Must
多面化環境構築の高速化 Should
選択的なリリース方式 Should
EKS周りの構成(TVer2.0)
それでは上記について一つ一つ取り上げて行きたいと思います。
LB・コンテナのスケールの短縮(1分以内)
地上波からの流入 は短時間(1分以内)にそれまでの何倍もの流入 があります。
この時間はとても重要でアクセス出来ないユーザーが発生しますと、せっかく続きをTVer で視聴しようとしたのに見れないと大きな失望を与えてしまいます。
そのため現在は事前に枠切れがわかるものに関しましては、リソースを事前に増やすことでその問題に対応しています。
しかし、全ての枠切れで大きなアクセスが来るかは不明確な部分もあり、リソースを適切に運用できているというと必ずしもそうではありません。
また枠切れ以外の急激なトラフィック 増、例えば近年ではリアルタイムでネットでバズる事で意図しない短時間のユーザー増も考えられます。
それらに対応するために、LBは短時間でスケール出来るNLBを選び、その後ろにあるサービス群(コンテナサービス)に関しても1分以内に起動からサービス提供まで行える状態になることを譲れない要件としました。
現在のTVer アーキ1.0/1.5ではECSのfargateを利用していますが、これをEKS(Auto Mode)に移行することにしました。
当初はEKSにすることで実際この要件を満たすかどうか半信半疑でしたが、POCや負荷試験 を通してバルーンPodなどと組み合わせれば1分以内に起動することが出来るということがわかり、本格採用に至りました。
ただしこの比較はあまりフェアじゃ無いものであり、ECSであれば最近出ましたECS マネージドインスタンス で比較した方がより速い起動になると思います。
ただ今回に関しては、NLB構成にしたことでNginxと協調出来るルーティング構成がよくEKSの場合Ingress controllerでその機能を補えるということで当初のままで行くことにしました。
*ただここからその後、NGINX Ingress Controller 以外の他の選択をする必要に迫られると思いませんでした。
ただ今回に関してはまだ次の移行先はまだ未定なのでNGINX Ingress Controllerのままで構成は説明して行きます。
限定的なリソースの事前増強
現在まで実施しているリソースの事前スケールが全てEKSを採用することで無くなるということは実は期待していません。
ただ事前に増やす必要がある規模は通常時のリソースの2倍にすることが最も多く、その増強運用のオペレーションが無くなるだけでかなり運用負荷が下がることを想定しています。
そのため、ものすごいアクセス増が見込まれるコンテンツに関しては心理的 な安全も確保したいので手動でリソース増強を今まで通りに実施しようと思っています(この場合通常時のリソースの4〜10倍の間)。
ただこの頻度に関しては年に数回とかに収まると想定しています。
多面化環境構築の高速化
現在開発環境はECSのクラスタ ーを含め、その開発面と同じ数のセットで倍増しています。
EKSにすることで、開発は同じEKSクラスタ ーに共有して存在しその中でサービスとして分離された状態にすることでリソースの管理をしやすく、コストも抑えるようにします。
ただしセキュリティーやリソースの分離を鑑みて、またあまりクラスタ ーが多すぎるとkubernetes の更新作業も面倒になるので下記のように環境を分けなるべく運用負荷を上げないようにしました。
環境別EKSクラスタ ー
選択的なリリース方式
カナリア リリースなどを実施する上でそれを実際に行うのは開発者側であり、開発者がいつでもリリースしやすい体験で行えるのが望ましいです。
今回のEKS環境のリソースデリバリーはArgoを採用していますので、Argo Rolloutsを利用することでカナリア リリースは実現できます。
それは現在のNginxでやっている加重方式よりはやりやすくなると期待しています。
*Argo以外の製品もありますが、Istioなどのサービスメッシュを必要とするのでまだ弊社ではそれには手を出していないので選択外となりました。
また当初はArgo Rolloutsに関してはLBなどとは連携せずに、純粋にPod数単位でユーザートラフィック を分散させようと思っています。
これは相乗りで動くことでLB Ingress とArgo Rolloutsとの対応が1対1になるか不明なのもあります。
まとめ
まだこのTVer アーキ2.0構成に関しては走り始めたばかりです。
開発環境でECSからEKSにサービスを移して機能試験や負荷試験 を実施した段階なので、まだまだやることは山積しています。
その上Ingress の移行問題も出てきたのでやることはさらに増えてはいますし、またこのリアーキに関してはコンテナオーケストレーション などの製品の選定で終わるものでもなく更に裏にあるDBなども対象に含んでいます。
ではそれでも前に進んでやるかと問われますと、増え続けるユーザーに安定的にサービスを提供し、落ちないTVer を目指すために必要な過程だと捉えています。