Compute で動画のキャッシュをプリフェッチ
楽しみにしていた番組がやっと視聴できるようになったものの、遅延を経験することほど残念なことはありません。ユーザーの視聴体験を最高なものにするため、パブリッシャーは動画のプリフェッチを行うことを検討することをお勧めします。
キャッシュを事前にウォームアップする理由
しばらく再生されていなかった動画コンテンツや新しい動画コンテンツの場合、プレイヤーはリクエストをオリジンに送信して動画のすべてのコンテンツを取得する必要があるため、最初の1バイトが到着するまでの時間 (TTFB) が非常に長くなる可能性があります。特定の時間に多数の視聴者が動画を視聴するとパブリッシャーがある程度予想できる場合は、各地域に迅速に動画を配信できるよう、すべての動画オブジェクトをエッジでキャッシュしておくことが理想的です。
HBO の人気ドラマ『ゲーム・オブ・スローンズ』の最終回を例に挙げます。同番組は絶大な人気を誇るテレビドラマで、何百万人ものファンが土曜夜8時に視聴可能になるのを待ちわびていました。従って、地理的に分散した大勢の視聴者が午後8時ちょうどに一斉に「再生」ボタンを押すことになるのは明らかでした。しかし、新しい動画であるため、キャッシュミスが生じて視聴者のリクエストがすべてオリジンに送られ、そのために動画の再生が開始するまでに長い時間がかかり、パフォーマンスや顧客満足度が低下する恐れがありました。
この問題を回避するため、HBO はすべての動画オブジェクト、あるいは動画の最初の数秒分のオブジェクトをプリフェッチすることで、動画をすぐに再生できるようにしました。
事前ウォームアップを行う問題点
従来、キャッシュの事前ウォームアップは、各キャッシュノードにログインしてスクリプトを実行し、すべての動画オブジェクトを取得するか、VPN を使用して各地域のクライアントを起動し、クライアント側から動画オブジェクトをリクエストすることによって行われていました。しかし、この方法には以下のような問題があります。
時間がかかり、管理が困難 : 使用する CDN について、多くの内部ネットワーク情報を把握する必要があります。加えて、各 POP にアクセスする方法や、クライアントからリクエストする場合は、それぞれの地域から各 POP にどのようにルーティングされるかを理解しなければなりません。
貴重な CDN キャッシュの空き容量を視聴されないコンテンツに費やす可能性がある : 例えば、世界中のすべての POP をウォームアップしたにもかかわらず、北米でしかコンテンツが視聴されなかった場合、その他の地域の POP にはクライアントに配信されない動画オブジェクトが保存されることになります。
Compute を使用した事前ウォームアップ
Compute の登場以前は、リクエストに対してできることは限られていました。VCL にはリクエストボディやレスポンスボディを読み込んだり操作したりする機能はなく、非同期リクエストに対してできることにも制限がありました。
Compute はそのような制限を取り払い、効率的なプリフェッチやキャッシュのウォームアップなど、動画配信に役立つ機能を提供します。
事前のマニフェストリクエスト
まず、動画ストリーミング配信の基本について簡単にご説明します。
動画は小さなチャンク単位で段階的に配信されます。クライアント側のプレイヤーは「マニフェスト」と呼ばれるファイルをリクエストします。マニフェストはバッファリングとプレイバックの両方に必要なファイルで、プレイヤーがリクエストを開始する他の動画オブジェクトへの URL が含まれています。
以下は、720p バージョンの『Big Buck Bunny』のプレイリストマニフェストの一部で、最初の3つの相対 URL を示しています (拡張子は .ts)。
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:13
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:12.500000,
buck_720p_0000.ts
#EXTINF:7.666667,
buck_720p_0001.ts
#EXTINF:11.466667,
buck_720p_0002.ts
#EXTINF:12.300000,
buck_720p_0003.ts
プレイヤーはメディアセグメントを1つずつリクエストします。通常は、プリフェッチなしでキャッシュがコールドな場合、各セグメントのリクエストはオリジンに送信されます。しかし、もっと良い方法があります。
前述の通り、Compute にはリクエストボディを読み込む機能があります。これにより、エッジで実行できるシンプルなアプリケーションを記述して、キャッシュを事前にウォームアップすることができます。プレイヤーがマニフェストをリクエストすると、そのリクエストをオリジンに渡しますが、レスポンスが返ってくると、プレイヤーはマニフェストを解析し、メディアオブジェクトを参照する、最初の N URL を見つけ、それからマニフェストをクライアントに渡します。以下のコードスニペットはそのプロセスを表しています。
match m3u8_rs::parse_playlist_res(new_resp.take_body_bytes().as_slice()) {
Ok(Playlist::MasterPlaylist(_pl)) => println!("Master playlist"),
Ok(Playlist::MediaPlaylist(pl)) => {
println!("Media Playlist. Path = {}", path_str);
send_media_segments_requests_async(&pl, req_url)?;
}
Err(_e) => fastly::error::bail!("Invalid manifest"),
}
// I got what I needed so return the beresp in a Result
Ok(beresp)
}
プレイヤーは最初の N メディアセグメントを見つけ、レスポンスを無視して非同期でリクエストを送信します。これは非常にすばやく実行されるため、レイテンシを増大させることなくマニフェストをプレイヤーに渡すことができます。ここでは、CDN キャッシュにメディアセグメントを保存することが目的なので、メディアセグメントのリクエストに対するレスポンスは関係ありません。プレイヤーがメディアセグメントのリクエストを開始する頃には、メディアセグメントはすでにキャッシュされています。
CMCD-NOR
全米民生技術協会 (CTA) が策定を試みている基準の1つに、Common Media Client Data (CMCD)があります。CMCD は、ストリーミングコンテンツ配信の分析、モニタリング、最適化に役立つ付加情報を定義するオープンな仕様であり、QoS の可視性を高め、配信パフォーマンスを向上させます。CMCD については、今後のブログ記事で詳しく取り上げる予定です。
CMCD の一要素として、Next Object Request (NOR) があります。これはクエリパラメーターとして、またはヘッダーに含めて渡すことが可能な文字列で、次にリクエストすべきオブジェクトの相対 URL を表します。この Compute アプリケーションは上記のアプリケーションと同様に機能しますが、マニフェスト内で次のオブジェクトを探す代わりに、クエリまたはヘッダー内を検索します。
match req.get_header("cmcd-request") {
Some(cmcd) => {
let cmcd = cmcd.to_str().unwrap().to_string();
send_nor_request(cmcd, &req);
}
None => {
// We looked for a cmcd-request header and it wasn't there so let's see if it's in the
// query parameters.
if let Ok(q) = req.get_query() {
let qs_map: HashMap<String, String> = q;
if qs_map.contains_key("CMCD") {
let cmd = qs_map.get("CMCD").unwrap();
send_nor_request(cmd.to_string(), &req);
}
};
}
}
ここでは、ヘッダー内で NOR リクエストを探し、ヘッダーにない場合は、クエリパラメーターをチェックします。ヘッダーかクエリのいずれかで見つかった NOR リクエストは、NOR URL を解析する send_nor_request 関数に送信され、その後、非同期で送信されます。
次世代のインテリジェンス
従来のワークフローは非常に分かりやすく、本番環境に導入するのも簡単です。しかし、さまざまな機能を豊富に備えたパワフルな Compute では、さらに多くのことが可能になります。以下は、Compute を活かして実現できるアイディアの一例です。
エンドロールのプリフェッチを回避 : 動画の最後になると視聴率も下がり、エンドロールを見る人はそう多くはありません。そのため、エンドロールをプリフェッチする意味がありません。タイムスタンプやタグなどのメタデータを手掛かりにエンドロールの始まりを検知し、その時点でプリフェッチを停止することでアプリケーションを強化することができます。
利用パターンに応じたインテリジェントなプリフェッチ : プリフェッチに AI や機械学習を適用し、エクスペリエンスを最適化することができます。例えば、AI を使用して動画の視聴率が最も高くなる時間を判別し、その間だけプリフェッチを実行することもできます。
まとめ
Compute を使用してキャッシュを事前にウォームアップすると、パワフルでグローバルな分散型ネットワークを活用できるだけでなく、従来のプリフェッチに関連する問題を解決することができます。