3.0.0の公開から約3年ぶりにメジャーバージョンが上がりました。(公式サイト)
今回も非常に多岐に渡る変更があるのですが、前回とはまた少し毛色が違います。
大きな変更点について見て行きましょう。
ストリームのフルサポート
3.0の時もストリームはサポートしていたのですが、4.0になってより強化されました。
初回コネクション | 同時接続してきたコネクション | |
---|---|---|
3.0 | ストリームされる | 初回コネクションが完了するまでロックされ、その後一気に転送 |
4.0 | ストリームされる | 既に初回コネクションでストリーム済みのデータを一気に転送してその後ストリーム |
イマイチイメージが掴みづらいかもと思ったのでgifアニメを作ってみました。
やってる内容は、1秒ごとにaを出力するphpに対して開始時間を数秒ずらして3並列で取得していっています。
初回のアクセスが終わった後は何回かアクセスしてみてキャッシュされていることを確認しています。
window配置
初回のクライアント | 3秒遅れのクライアント | 5秒遅れのクライアント |
apacheログ | ||
varnishncsa |
検証コード
■slow.php
<?php header('Cache-Control: max-age=20'); ob_end_flush(); ob_start('mb_output_handler'); for($i=0;$i<10;$i++){ echo "a\n"; ob_flush(); flush(); sleep(1); }
■vcl@3.0.5
sub vcl_fetch{ set beresp.do_stream = true; set beresp.ttl = 1w; }
■vcl@4.0.0
sub vcl_backend_response{ set beresp.do_stream = true; set beresp.ttl = 1w; }
3.0.5は最初のアクセス以外はブロックされていますが4.0.0はブロックされていない上に既に転送されているものは最初に一気に転送されているのがわかります。
比較的大きなコンテンツを配信する場合は非常に有用な機能といえます。
オブジェクトがexpireした際にgrace期間が残っている場合は、古いオブジェクトを返しつつバックグラウンドでオブジェクトを更新します
オブジェクトがexpireした時の動作も強化されました。
初回expire後のコネクション | 同時接続してきたコネクション | フェッチ終了後 | |
---|---|---|---|
3.0 | fetchを行い新オブジェクトを転送する、fetchの間は通常どおり待機させられる | 古いオブジェクトを転送 | 新オブジェクトを転送 |
4.0 | バックグラウンドでfetchを行い、自コネクションは古いオブジェクトを転送 | 古いオブジェクトを転送 | 新オブジェクトを転送 |
今回もgifを撮ってみました。
取得に3秒かかるコードでTTLは10秒です。expire時の動きを見てみてください。
検証コード
■date.php
<?php header('Cache-Control: max-age=20'); echo date("Y/m/d H:i:s")."\n"; sleep(3);
■vcl@3.0.5
sub vcl_fetch{ set beresp.do_stream = true; set beresp.ttl = 10s; set beresp.grace = 10m; }
■vcl@4.0.0
sub vcl_backend_response{ set beresp.do_stream = true; set beresp.ttl = 10s; set beresp.grace = 10m; }
3.0ではexpire時にsleepが効いているのが分かります。
4.0ではそれがありません。
varnishlogをグルーピング出力したりqueryで絞り込むことが可能に
これは非常に大きな機能なので別記事で取り上げますが
簡単に言うとリクエストがどのESIにサブリクエストを使っているかなどがグルーピングできたり
携帯端末で1秒以上レスポンスにかかったログの抽出が出来たりします。
directorがvmodになりました
これも別記事で取り上げます。
独自のdirectorが作りやすくなったのと他にも利点があります。
vmodがrequest bodyを見ることが可能になりました
今までも超トリッキーな事をすれば見ることは可能だったのですが正式にサポートされました。
POSTリクエストの中身を見て何かしらの処理を行うようなvmodを作るのが簡単になります。
インラインCがデフォルト無効になりました
これは廃止されるというわけではなくセキュリティ対策としてデフォルト無効になっているだけです。
vcc_allow_inline_cというパラメータで復活可能です。
VCLが大幅に変わった
恒例行事です。別記事で書きます。
公式のアップグレード方法は以下です
Upgrading to Varnish 4
varnishapi周りが刷新
当然ですが3.0向けのvmodは移行が必要です。
バグ修正多数
今までバグ修正はされていたもののリリースには含まれていなかった様々なバグ修正が今回のタイミングで取り込まれています。
たとえば
syntheticでASCIIコード以外を出力しようとした場合に文字化けするバグ修正が取り込まれていたり
vclをdiscardしてもヘルスチェックが止まらないバグなどが直っています
varnishstatの表示改善
これは実際に触ってみたほうが早いですが、カウンタの説明が出るようになっています。
パラメータの変更
これも別途記事で書きます。
まとめ
他にも取り上げては居ませんがかなりの変更点があります。
さて、ここまでわざとぼかして書いていたのですが
今回の一番大きな変更はクライアントとバックエンドのスレッドを分離したことです。
これにより、ストリームやgrace時の動作改善などが可能となりました。
また現versionでは残念ながら実装されていませんが、パラレルフェッチESIも可能となるはずです。(予定には入っているようです)
また、これはコード上の話ですが3.0まではHTTPを処理する箇所がvarnishのコードと結構くっついていたのですが
4.0では分離されており拡張が容易な構造にリファクタリングされています。
これはHTTP2.0を見据えた変更です。
最初に2.1から3.0の変更とは毛色が違うといったのは、構造を大幅にリファクタリングしたということです。
また、検証をしている段階では比較的安定しており、最近趣味で手伝っているPVもそれなりに多いサイトに週末にでも投入して動作検証も行う予定です。
その結果も記事などにできればなぁと考えています。
あと今回もリリースパーティーやるみたいなので
誰かやらないかなとチラチラと・・・