Varnish4のESI(edge side includes)を使ってみる

Varnish 3 の ESI はinclude している要素を一つづつ順番に評価していく。
3要素インクルードしていたとして、1つ目の処理に2秒、2つ目の処理に2秒、3つ目の処理に2秒かかると、ページを処理するのに 2×3=6秒 かかる。

先月開催された Varnish User Day での Varnish 4 の発表資料を読んでいたら

Parallel ESI
Start all esi:include fetches ASAP
Faster responses

と書かれてあった。
もしインクルードされる要素を並列に処理できると、2秒でページの処理が完了する。

これは便利ということで 2013-12-05 にリリースされた Varnish Cache 4.0 Technology preview 1 の ESI を触ってみた。

Edge Side Includes(ESI)の概要

ESI を知らないひとは SSI と思えばだいたい OK。
ページを構成する要素のうち、パーソナライズされたコンテンツやランキングなどを部品化し、ページ生成時に各部品をインクルードしてページを組み立てる。

2001年には ESI のマークアップ言語が規格(http://www.w3.org/TR/esi-lang)としてまとめられるなど昔からあるけれども、SSI ほど広まっていない。

ESI の詳細は仕様を中心になってとりまとめた Akamai の次の URL を参照
http://www.akamai.com/html/support/esi.html

ESI の言語仕様は次の URL を参照
http://www.w3.org/TR/esi-lang
Varnish はこのサブセットしか実装してない

Varnish 3 の ESI は次の資料を参照
http://www.slideshare.net/xcir/varnishesi

Varnish 4 の ESI

Varnish 4 のインストール

Varnish 4 は今のところ RedHat や Ubuntu 向けのパッケージは提供されていないみたいなので、ソースからインストールする必要がある。

ソースコードは次の URL から取得

http://repo.varnish-cache.org/source/

今回は varnish-4.0.0-tp1.tar.gz を利用。より最新のコードを評価したいときは github から持ってくる。

https://github.com/varnish/Varnish-Cache

ドキュメント(https://www.varnish-cache.org/docs/trunk/installation/install.html)を参考に、依存するパッケージを入れたあとは configure && make && make install でインストールできた。

init スクリプトは 3 系列の Varnish のものを拝借した。

ESI 向け設定

Varnish 3 の ESI 設定

まずはおさらいとして Varnish3 の設定を確認。
default.vcl で次のように書く。

backend default{
    .host = "127.0.0.1";
    .port = "80";
}
sub vcl_fetch{
    set beresp.do_esi = true;
}

Varnish 4 の ESI 設定

続いて Varnish 4 の設定。

vcl 4.0;
 
backend default {
    .host = "127.0.0.1";
    .port = "80";
}
 
sub vcl_backend_response {
    set beresp.do_esi = true;
}

違いは2つ

V4 で VCL のシンタックスが変わったため、設定ファイルは V4 向けに書かれていることを明示的に示すために、バージョン指定が必要。
先頭で vcl 4.0; と宣言する。
https://www.varnish-cache.org/docs/trunk/whats-new/upgrading.html#version-statement

次に vcl_fetch vcl_backend_response になったので設定ファイルを書き換える。

VCL ファイルのシンタックスチェックは $ varnishd -C -f /path/to/default.vcl で行う。
正常なケースでは C のコードが流れる。

先のケースで vcl 4.0 の宣言をコメントアウトしてシンタックスチェックすると、以下の様に怒られる。

$ sudo varnishd -C -f /usr/local/etc/varnish/default.vcl
Message from VCC-compiler:
VCL version declaration missing
Update your VCL to Version 4 syntax, and add
        vcl 4.0;
on the first line the VCL files.
('input' Line 3 Pos 1)
backend default {
#######----------

Running VCC-compiler failed, exit 1

VCL compilation failed

Parallel ESIの実験

parallel 確認用ページ

処理に1秒かかるページ(1.php) と2秒かかるページ(2.php) を用意

$ tail -n +1 1.php 2.php
==> 1.php <==
<?php
echo "1.php : ";
echo date('Y/m/d H:i:s') . "->";
sleep(1);
echo date('Y/m/d H:i:s');
?>

==> 2.php <==
<?php
echo "2.php : ";
echo date('Y/m/d H:i:s') . "->";
sleep(2);
echo date('Y/m/d H:i:s');
?>

この2つを ESI インクルードするページ(esi.php)を用意。
sleepで時間稼ぎをさせる。
処理時間も確認したいため、sleepの前後に現在日時を出力させる。

$ tail -n +1 esi.php
==> esi.php <==
<div>
<esi:include src="/1.php" />
<esi:include src="/2.php" />
<esi:include src="/2.php" />
</div>

キャッシュの確認もしたいため、 2.php は2回インクルードしている。

もしパラレルにオリジンサーバにリクエストが行くのであれば、2秒で処理は完了するはず。

実験

apache 経由のアクセス

ESI を解釈しない Apache 経由でアクセス

$ curl http://localhost:80/esi.php
<div>
<esi:include src="/1.php" />
<esi:include src="/2.php" />
<esi:include src="/2.php" />
</div>

ESI タグがそのまま出力される。

Varnish 経由のアクセス

8080 ポートで動いている Varnish にアクセス

$ curl http://localhost:8080/esi.php
<div>
1.php : 2013/12/30 13:34:38->2013/12/30 13:34:39
2.php : 2013/12/30 13:34:39->2013/12/30 13:34:41
2.php : 2013/12/30 13:34:39->2013/12/30 13:34:41
</div>

2回目の 2.php のインクルードは Varnish とオリジンサーバ間でキャッシュされているため、1回目と同じ結果が返ってくる。
こちらは期待通り。

問題は 1.php の処理に1秒かかり、そのあと 2.php を処理し、さらに2秒かかっていること。
1.php と 2.php は並列に処理されておらず、意図しない結果になった。

Parallel ESI は未実装でした

改めてスライドを読み直すと What we did のブロックに VCL version marker のような tp1 で実装済みの機能が並んでおり、Parallel ESI は In front of us のブロックに含まれていた。
まだ未実装だったのを早とちりしてしまった。

もうちょっと V4 向けの新機能の実装が進んでから再評価してみよう。

補足:esi_disable_xml_checkオプション

ESI ファイルが ‘<' で始まらない場合、ファイル内の ESI マークアップは無視される。

Varnish 3 では起動オプションに -p esi_syntax=0x00000001 が必要だった。
Varnish 4 では起動オプションに -p feature=+esi_disable_xml_check が必要。

このオプションは Varnish 起動後に変更することも可能

$ sudo /usr/local/bin/varnishadm -S /usr/local/etc/varnish/secret param.show feature
feature
        Value is: none (default)
        Default is: none

        Enable/Disable various minor features.
           none                       Disable all features.

        Use +/- prefix to enable/disable individual feature:
           short_panic                Short panic message.
           wait_silo                  Wait for persistent silo.
           no_coredump                No coredumps.
           esi_ignore_https           Treat HTTPS as HTTP in
                                      ESI:includes
           esi_disable_xml_check      Don't check of body looks like
                                      XML
           esi_ignore_other_elements  Ignore non-esi XML-elements
           esi_remove_bom             Remove UTF-8 BOM


$ sudo /usr/local/bin/varnishadm -S /usr/local/etc/varnish/secret param.show feature param.set feature +esi_ignore_other_elements

$ sudo /usr/local/bin/varnishadm -S /usr/local/etc/varnish/secret param.show feature
feature
        Value is: +esi_ignore_other_elements
        Default is: none

        Enable/Disable various minor features.
           none                       Disable all features.

        Use +/- prefix to enable/disable individual feature:
           short_panic                Short panic message.
           wait_silo                  Wait for persistent silo.
           no_coredump                No coredumps.
           esi_ignore_https           Treat HTTPS as HTTP in
                                      ESI:includes
           esi_disable_xml_check      Don't check of body looks like
                                      XML
           esi_ignore_other_elements  Ignore non-esi XML-elements
           esi_remove_bom             Remove UTF-8 BOM
Advertisements
Tagged with: ,
Posted in middleware

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives

Error: Twitter did not respond. Please wait a few minutes and refresh this page.

%d bloggers like this: