DMM.comの、一番深くておもしろいトコロ。

もしもに備えた動画配信基盤のDRシステム

もしもに備えた動画配信基盤のDRシステム

  • このエントリーをはてなブックマークに追加

はじめに

動画配信事業部 配信基盤チームの小田です。 この記事は「進化する動画配信基盤」についての連載第10回目です。 今回はVOD動画におけるディザスタリカバリについてご紹介していきます。

目次記事はこちらです。 inside.dmm.com

第6回第7回で紹介されていたように、古くから弊社の動画配信基盤を支えていたエンコーダーがJIROという名前のエンコーダーに刷新されました。JIROへの刷新に伴って運用部門の手間が大幅に減ったり、エンコード速度がかなり上がったりなど、様々なメリットが生まれ、バックアップファイルもクラウドに保存されるようになりました。

そして、クラウドに保存されるようになったことで、「もしかして、ディザスタリカバリできるのではないか」という話が挙がっていたので、実装してみました。 以下に詳しく説明していきたいと思います。

DRについて

知っている人も多いと思いますが、改めて解説しますと、ディザスタリカバリ(Disaster Recovery)とは、文字どおりシステムの「災害復旧」のことです。 大地震や火災などで壊滅的なシステム障害が発生した場合でも、ユーザにサービスを提供できるように復旧・修復するような仕組みや、そのための一連の取り組みを指します。

DRでよく語られる概念にRTO・RPOというものがあります。 RTO(Recovery Time Objective)は目標復旧時間のことを指し、復旧にどのくらいの時間をかけるか、という指標です。 例えば、復旧に5時間かかったとして、RTOの設定が8時間なら許容の範囲内と言えます。

RPO(Recovery Point Objective)は、目標復旧時点のことで、サービスのどの地点まで遡って復旧するか、という指標です。 こちらも例えると、復旧が完了して障害発生前の3時間分のデータが失われてしまったとしても、RPOが5時間なら許容の範囲内といえます。

また上記2つに加えてRLOという概念もあります。Recovery Level Objectiveの略で、どの程度の品質まで落として復旧するかという指標のことです。動画サービスの文脈で言うと、どのビットレートまで落とすのか、と言った話がRLOに該当するかと思います。

DMM動画のバックアップ

第7回の記事 などでも述べられているように、動画のエンコーダスタックをJIROという自前のシステムに刷新しました。JIROは賢い分散エンコーダーで、エンコードの速度・手間が今までより大幅に改善されたわけですが、このJIROの導入と同時にバックアップ動画がAWS S3に自動保存されるようになりました。ちなみにストレージクラスは、比較的料金が安めな Glacier Deep Archive で保存しています。

このGlacier Deep Archiveクラスは、普段はコールドスタンバイでストレージに保存されていて、ダウンロードするためには「復元」作業が必要です。この復元操作には最大で48時間かかりますが、これはRTOの指標を立てるうえで重要なポイントになってきます。

蛇足ですが、エンコーダスタックをJIROに刷新する前は、実は全て手動でHDDにバックアップを取っていました。昔から日々膨大な量の動画コンテンツが納品されてきたわけですが、今回のJIROエンコーダーへの刷新によって、ヒューマンエラーやバックアップの煩わしい手間から解放されたという副次効果もあったわけです。

DMM動画の規模

DMMでは多種多様なサービスを提供していますが、そのなかでも動画サービスは屈指の売り上げを誇ります。トラフィックも膨大で、最近は瞬間で350Gbpsを突破した時間帯もありました。そんな弊社の心臓とも呼べる動画サービスですが、もしも事故や災害でデータセンターが吹っ飛んだら大変なことになります。そこで、バックアップがクラウドS3に保存されるようになったことで「ディザスタリカバリできるかも」という話になり、AWSを使ったディザスタリカバリを開発していくことになったわけです。

AWSによるDRスタックの構築

いよいよDRなシステムのアーキテクチャをご紹介します。ちなみに、私が入社する前は弊チームの @_tinoji さんが途中まで作ってくれていたものがあり、主にキーサーバの実装をはじめ、手が付いてなかった部分を私自身が入社してから担当しました。

f:id:yanoshi:20200331124722j:plain
アーキテクチャ

ざっくり流れを説明すると、バックアップ動画をレストアして、レストアが終わったらエンコードして、最後にDRMをかけてパッケージングした段階で配信準備が完了、というフローになっています。 AWSのリージョンは、もし日本の主要リージョンが滅亡しても大丈夫なようにアメリカのバージニア北部(us-east-1)を選んでいます。 それではどのような流れでDRが進行するのか、順を追って見ていきみましょう。

1. DR Adminからレストア開始

DRシステムを操作するために、Elastic Beanstalk上にAdmin画面を作成しました。 レストアの開始操作、エンコードのキャンセル・一時停止・再開操作ができるようになっていて、最低限のことはAdminでできるようになっています。

2. レストア

レストア処理では、最近登場した S3 Batch Operations という機能を活用しました。S3 Batch Operationsでは、事前にS3のオブジェクトリストがまとまった「Inventory」というファイルを作成し、そのリストに対して一括で任意の操作を実行できます。バックアップファイルはほぼ毎日増えていくので、デイリーでInventoryファイルが生成されるようにしつつ、ライフサイクルの設定で一定日数経過したInventoryは自動で消えるようにしました。

レストアをどのように開始するかという話ですが、専用の管理画面で「レストアの開始」ボタンをポチッとするとS3 Batch Operationsのジョブを発行し、全コンテンツ分のレストアが走るようになっています。 ちなみに Glacier Deep Archiveには取り出しに最大48時間かかる「一括取り出しモード」と最大12時間かかる「標準取り出しモード」がありますが、今回は前者の一括取り出しモードでレストアするようになっています。

3. エンコード

レストアが完了したら、完了イベントをフックにLambdaでElemental MediaConvertのエンコードジョブを発行します。RTO的な観点でABR配信はせず、ビットレート2Mbpsの単一ストリームでHLSに変換します。

4. DRM・パッケージングの開始

エンコードが完了したら、Elemental MediaPackageで動画をパッケージングします。 この際、AWS Media Servicesが持つAWS SPEKEというインタフェースを踏襲したキーサーバを使って、PlayReady、Widevine、FairPlayといったDRMをかけつつHLS AES128なファイルも生成します。

AWS SPEKEとは、動画のパッケージャ(AWS Media Services)とDRMキープロバイダ間で、暗号化キーなどの情報を通信する際のインタフェース仕様のことです。要は、SPEKEが定めるインタフェースにのっとってDRMに必要な情報(キーやHLS AESのURL)を返すサーバを実装すると、AWS Media Services が裏側でDRMしてくれる便利ツールです。DASH IFが提供するCPIX( https://dashif.org/docs/CPIX2.2/Cpix.html )という仕様をラップしています。

AWS SPEKEは、現時点ではMediaPackageのLIVE出力チャンネルまたはVODパッケージング機能と連携して使うことができます。実際に使う際は、SPEKE準拠なAPIサーバを用意して、パッケージングの設定画面でそのURLを指定するだけで準備完了。あとはパッケージングを開始すれば自動でDRMが完了、という流れになります。

5. 再生URLの保存

MediaPackageへのパッケージングリクエストが完了したら、生成された再生URLをElastiCache(Redis)に自動で保存します。調べたところ、MediaPackageではパッケージングが終わる前に再生URLを生成することが判明したので、復旧時間を少しでも短縮するため、パッケージング処理の終了を待たずにRedisにURLを保存するようにしました。

最終的に、MediaPackageの再生URLはCloudFrontを噛まして配信します。

開発の小話

MediaConvertの性能検証

今回のように、一度に大量コンテンツをElemental MediaConvertで処理するケースはなかなか事例が少なく、さらにMedia Services関連のサービスがまだまだ枯れていない、という状況でもあったので事前に性能検証を実施しました。

まず、MediaConvertには高速トランスコードが可能になるモードがあります。これは、特にUHD画質やH.265(HEVC)などの、データサイズが大きいコンテンツのトランスコードがかなり早くなるトランスコードモードです。H.264などのコンテンツでも使うことができたので、実際に高速トランスコードでどれくらい処理が短縮されるのか検証しました。

結果は、H.264のMP4ファイルの場合、通常モード比で平均1.1〜1.2倍程度エンコード速度が上がることを確認できました。しかし、エラーでエンコードできないコンテンツも存在しました。エラーログをあさると、ある基準を満たしていないとアクセラレーションモードでエンコードできないということが分かったので、DR時は通常モードでエンコードをすることに。

ちなみに、H.264でファイルサイズ22GB程度のコンテンツだと高速トランスコードは平均10分前後で完了しました。

f:id:yanoshi:20200331124813p:plain
高速トランスコード結果

またAWSの公式ドキュメントによると、バージニア北部リージョンではMediaConvertの最大同時実行ジョブ数は200まで、と書いてあります。こちらも実際のバックアップコンテンツを使って検証してみたところ、数十ジョブ程度までしか同時実行されませんでした。テクニカルサポートによると、ある条件に合致すると同時実行ジョブ数が制限されるとのことでしたが、詳しい条件は教えてもらえませんでした。 今回は数十ジョブまで同時実行数が制限されてしまいましたが、サポートによると制限引き上げリクエストを行うことで制限後の上限も上がるとのことだったので、AWSのコンソールから引き上げリクエストをすることでこの問題を解決しました。少々力技感がありますが。

AWS SPEKEを用いたDRMの苦労

今回のケースでは、1つのコンテンツに対してWidevine・PlayReady・FairplayというDRMに対応したファイルとHLS AES128なファイルを生成するようにしています。DRMを実施するにあたって、まずはSPEKE準拠なキーサーバを構築したわけですが、ニッチな機能ということもあり、実装事例が公式ドキュメント以外ほぼどこにも載っていませんでした。とりあえず、公式のリファレンス実装を参考に、試行錯誤を重ね実装することに成功。

また実装途中で、リファレンス実装自体に問題を発見したので、issueを立ててプルリクを投げるなどしました。

DR避難訓練を実施

完成したDRシステムの検証を兼ねて、避難訓練を実施したので振り返ってみます。

まず事前に、有事を想定した動画配信システムの復旧手順書を用意してチームメンバーに共有しました。動画配信事業部では、金沢事業所に2人のメンバーがいますが、東京が大被害を受けることを想定して金沢オフィスの2人に復旧操作をしてもらうことに。 東京が壊滅状況になったケースを想定して、避難訓練当日は金沢オフィスと東京オフィスは特に通話で繋いだりはせず、事前に用意した手順書どおり黙々と進めてもらいました。

f:id:yanoshi:20200331154837p:plain

避難訓練は2つのフェーズに分けて行いました。

1フェーズ目は、バックアップコンテンツのレストア(復旧)作業です。専用の管理画面を操作して、全バックアップ動画のレストアを開始します。

f:id:yanoshi:20200331124856p:plain
DR Admin

先述したように Glacier Deep Archive ではコンテンツのレストアに最大48時間かかるので、この操作が終わったらしばらくは何もする必要がありません。また、レストアの終了イベントをフックに、自動でコンテンツのエンコード・DRM・再生URL生成の処理が走ります。最後の、再生URLを生成してRedis(Elasticache)に保存するところまで終えたら、DR配信準備が完了するというわけです。

次に2フェーズ目の、DRモードの切り替え作業に進みました。1フェーズ目である程度の数のコンテンツのレストアが確認できたら、このフェーズで動画プレイヤーのコードを書き換えて、DR動画を参照するようにしていきます。コード側の修正をしてもらい、Gitでマージしてデプロイしてもらうことで作業が完了するのですが、ここで私の事前の設定に不備があり、急遽訓練を一時停止しました。数十分後、不備を解消して金沢の2人に作業を再開してもらい、無事にデプロイが完了。

f:id:yanoshi:20200331124926p:plain
実際の環境の再生URL

再生URLを確認してみると、無事にCloud Frontのドメインで再生できています。プレイヤー側は、データセンターにファイルがあればそちらを再生し、なければAWSのDRな動画の再生URLを取得して再生するという作りになっていますが、DR対象に含めていない動画は通常どおり再生できることも確認できました。

いくつか事前準備に不備があり、一時作業を中断する事案も発生しましたが、無事にDR動画が本番同様環境で再生できることを確認できました。

DRの課題

弊社の大規模かつセキュアな動画配基盤を作りあげるうえでは、様々なシステム(API)と連携が必要であり、それらについてはまだまだ冗長性が不十分なところもあります。今回はVOD動画配信のディザスタリカバリシステムを実装したわけですが、それらの部分が落ちてしまったら元も子もなくなってしまう問題もあります。

また、DMMの動画コンテンツは毎年PB(ペタバイト)単位で増えていきます。当然、これを全てDRすると復旧コストも時間もかかってしまうので、例えば売り上げが高い順にコンテンツを一定件数抽出し、それらのみDRするなどの対応策が考えられます。

冒頭で述べたように、DRでは目標復旧時間(RTO)・目標復旧地点(RPO)・目標復旧品質(RLO)といった概念がありますが、新たにコストという観点でRCO(Recovery Cost Objective)があっても良いかなと思いました。

まとめ

課題は残るものの、ディザスタリカバリな仕組みが完成し、ドキュメントも整理しつつ準備万端! な状態まで持ってくることができました。万が一有事が発生して、オンプレの大規模ストレージと配信サーバが使い物にならなくなっても、継続して動画サービスを提供できるようにもなりました。また避難訓練も実施し、システム有用性を確かめることができたのも大きいです。

ディザスタリカバリは、実際に非常事態が起こった時にしか価値を発揮しませんが、万が一のフォールバック先があると安心しますよね。また、今回作ったシステムはディザスタリカバリに限らず、処理を流用して既存のオンプレ配信システムの冗長系システムとして使用するなど、様々なことにも応用できます。

これでまた1歩、イケてる配信システムに近づくことができたかなと思いますが、まだまだ改善の余地もあるので引き続き良い配信基盤を作り上げていきたいと思います。

以上、AWSを活用した動画配信ディザスタリカバリの紹介でした。

最後に

DRシステムを開発した副産物として、AWS SPEKEによるDRM処理な仕組みをナレッジ化できました。今回はVODのDRMでAWS SPEKEを使いましたが、ライブ配信に応用することも可能です。今回のDR開発によって、クラウドでの実装の幅が少し広がったので、さらに良い配信基盤を実現するための材料にしていきたいと思います。