動画配信プラットフォーム Adobe Media Server

Adobe Coldfusion Adobe Media Server 製品に関するご質問・ご購入
HOMEコラム > HDS/HLS フェールオーバーのためのVarnish サンプルコード

HDS/HLS フェールオーバーのための
Varnish サンプルコード4/5

バックエンド調査

バックエンドは健康と見做して問題ないかどうか調査する事ができます。バックエンド健康度調査は、それぞれのバックエンドが”健康/不健康”かを判定するのに用いられます。

調査は、上の例の通り{{.probe}} メンバーをVCLのバックエンド定義に追加する事で構成される。多様なオプションと、各々の定義は:


url:
VarnishがどのURLを要求するか。


interval;
どれくらいの頻度で調査するか。


timeout:
調査のタイムアウトの定義。


window:
Varnishが調査結果のスライディング・ウィンドウを生成、保持する。ウィンドウの大きさは、バックエンドが健康か否かを判定するために考慮する最新の調査数を決定付けます。


threshold:
バックエンドが健康であると認定されるのに必要な結果が良好である最新の調査の数。上記のコードの設定は、Varnishにhttp://<IPアドレス>/ に要求を10秒毎に送信するよう促す。サーバーを利用するか否かを判断する時、送信した最新の調査結果6つの内最低5つが良好である必要です。

 

ディレクター

複数のバックエンドを、1つのバックエンド・グループとしてまとめる事もできます。こうしたグループはディレクターと呼ばれます。我々のセットアップでは、2つのディレクター(ハッシュとラウンドロビン)を用います。バックエンド・サーバーを構成した後に、次の構文をVCLに追加します。

[[[# define the hash director that is used for m3u8 (HLS) requests. 
# CUSTOMIZE this section if you have additional packagers
 
director hls hash {
        {.backend = b1; .weight = 1;}
        {.backend = b2; .weight = 1;}
}
 
 
# define the round_robin director that is used for HDS requests.
# CUSTOMIZE this section if you have additional packagers
director hds round-robin {
    {.backend = b1;}
    {.backend = b2;}
}]]]

Round-robin director:
このディレクターによって、Varnishは受信した要求をバックエンド・サーバーにラウンドロビン方式で分配します。


Hash director:
ハッシュ・ディレクターによって、VarnishはURLのハッシュ値に基いてバックエンド・サーバーを選び出す。ハッシュ・ディレクターはハッシュ・データを利用、即ち同じURLは毎回同じバックエンド・サーバーにいく事になります。

Varnishサブルーチンのカスタマイズ

一般に、VCLファイルはサブルーチンに分割されます。異なるサブルーチンは、それぞれ違う場面で実行されます。これらで最も重要な要素の2つがvcl_recvとvcl_fetchです。


vcl_recvはリクエストの最初、つまりリクエストが完全に受信され解析された後に呼び出されます(?)。要求に応答するか否かの判定、どう行うか、そして該当する場合、どのバックエンド・サーバーを使用するかを判断する目的で用いられます。


vcl_fetch は応答がバックエンド・サーバーから首尾よく受信された“後”に呼び出されます。ここでの通常のタスクは応答ヘッダを改変するか、要求が失敗した場合に代替バックエンド・サーバーを試すというものです。

vcl_recv

基本的なvcl_recvサブルーチンから始めます。


次の構文を追加します。

[[[## Called when a client request is received
sub vcl_recv {
    set req.backend = hds;
}]]]

このコードがディレクターをラウンドロビンであるHDSとして設定します。このディレクターによってVarnishは要求を受信した時、常にラウンドロビン方式でバックエンド・サーバーを選択します。


次に、M3U8要求に対してはバックエンド・サーバーをURLハッシングに基いて選択します。こうすることで、1つのストリームのM3U8は常に同じパッケージャーがサーブするようになります。この解決方法はM3U8をサーブしている間1つのパッケージャーに紐付けるものです。"req.url ~ "\.m3u8$" && req.url ~ "hls-live""というチェックは、この処置をライブ・ストリームのM3U8要求にのみ行う事を保証するものです。


サブルーチンに次の構文を追加します。

[[[## Use URL hashing direction scheme for .m3u8s in order to mitigate liveness issues on packager failure and restart
 
if (req.request == "GET" && req.url ~ "\.m3u8$" && req.url ~ "hls-live") {
    set req.backend = hls;
    if(req.restarts > 0){
        set req.url = req.url + "?restart=" + req.restarts;
    }
}]]]

バックエンド・サーバーのどちらかが要求をサーブするのに失敗した際、要求したURLにクエリ文字列を付加し、それによってハッシュ値を変更し、別のサーバーが選択されるようにします。


そして次の構文は、ロギングを補助してグレースの設定をするのに加えられます。

[[[## Add a unique header containing the client address for the purposes of logging
 
if (req.restarts == 0) {
        if (req.http.x-forwarded-for) {
            set req.http.X-Forwarded-For =
                req.http.X-Forwarded-For + ", " + client.ip;
        } else {
            set req.http.X-Forwarded-For = client.ip;
        }
}
 
# grace settings, note this is also set in vcl_fetch,
set req.grace = 80s;]]]

Varnishに於けるグレースとは、状況に応じてその他有効期限切れのオブジェクトを送信する事です。グレースは、次の場合に起こり得えます:


・特定のコンテンツに対する要求が既にペンディングとなっている場合(新しいコンテンツを取得中の間に古いコンテンツを送信する)
・健康なバックエンドが利用不可の場合


80秒に設定すると、クライアントはTTLから80秒以上は経過していないコンテンツを送られる事を意味します。
次を行う事で、ブートストラップとフラグメントが常にVarnishのキャッシュからサーブされる事が保証されます。


vcl_recvでは、次の終止文を実行する事ができます。


キャッシュをパスするとは、残りのVarnish処理を通常と同じように実行、しかしコンテンツをキャッシュから検索することもキャッシュに保存もしない事を言います。


要求をパイプするとは、Varnishにコンテンツを参照せずに接続中のクライアントと選択中のバックエンド間でデータを通過させる指示を出す事を言います。Varnishは要求に対してコンテンツをもうマップする事はない為、続けて同じキープアライブ接続上に送信された要求もパイプされて、どのログにも記録されません。


要求をキャッシュからルックアップし、もし既存でない場合はキャッシュにデータを入力します。
エラーはVarnishか統合的な応答を生成します。典型的にはエラー・メッセージ、リダイレクト・メッセージまたは負荷分散装置の健康度チェックに対する応答です。

[[[## always cache bootstraps:
if (req.request == "GET" && req.url ~ "\.(bootstrap)") {
    return(lookup);
}
 
## always cache fragments:
if (req.request == "GET" && req.url ~ "(\wSeg[0-9]*-Frag[0-9]*)") {
    return(lookup);
}
 
## do not cache these rules:
if (req.request != "GET" && req.request != "HEAD") {
    return(pipe);
}]]]

vcl_recvからルックアップを返した場合、Varnishに要求がパスされるべきであると示されるにかかわらず、キャッシュからコンテンツを送信するよう指示する事になります。