url

The Operation and Installation of
the Varnish HTTP Accelerator
株式会社エンターモーション
システム開発部
重村法克
[email protected]
[email protected]
[email protected]
2009年03月13日
目的・目標
本講の目的は、HTTP アクセラレータであるVarnishの導入・設定
から運用に必要となるであろう各種項目の紹介や解説を行うもの
である。
商用サービスにおいて極めて高い導入効果が得られると考えて
いるが、マニアックな設計方針、散在するドキュメント、世代ごとの
仕様の違いによるドキュメントの有効性を都度評価しなければな
らないなど、使いこなすには大変である(日本語ドキュメントがな
いというのもあるかもしれないが…)。
本講ではバージョン2.0.2にターゲットを絞って、明日から導入を
行えるようになることを目標とする。
アジェンダ
●
アーキテクチャ
●
●
●
●
●
●
●
●
メモリ
スピード
パフォーマンス
まとめ
フィロソフィ
●
●
●
●
●
構造
言語
●
●
●
●
●
言語仕様
宣言子
関数
変数
正規表現
コマンドの使い方
●
●
●
●
インストール方法
varnishdコマンドの使い方
varnishadmコマンドの使い方
varnishhistコマンドの使い方
varnishtopコマンドの使い方
varnishstatコマンドの使い方
サービスの起動の仕方
運用
参考文献
アーキテクチャ
●
まずはVarnishの設計(Design)の前提となる特徴
的な方針について確認する。
●
詳細は参考文献を見てもらうとして:−)。
●
下記項目に基づいて解説する。
●
●
●
メモリ
スピード
パフォーマンス
□参考文献
『The Varnish Roadshow』 (BSDCan 2007)
http://www.bsdcan.org/2007/schedule/attachments/18-The_Varnish_HTTP_Accelerator_Poul-Henning
%20Kamp
アーキテクチャ(メモリ)
●
今どきのハードウェアは、CPUか
らメモリ、ハードディスクに至るま
で、多段のキャッシュ・バッファメカ
ニズムが用意されている。
L1
L1
L2
L2
L3
メインメモリ
ライトキャッシュ・バッファ
HDD
アーキテクチャ(メモリ)
●
●
●
OSはこれらハードウェアの構造を生かすための機
構が実装されている。
またその進化は、初期の単純なオーバレイ機構か
ら、ページングや更にはCPUキャッシュを意識した
仮想メモリ機構(VM)まで、現在でも改良が続けら
れている。
アプリケーションはOSの進化を意識することなく使
えていた。あるいはOSはアプリケーションに意識さ
せなかった。
アーキテクチャ(メモリ)
●
SquidはOSの存在を意識することなく、メモリ・
HDDの区別なく、全てを制御下において実装され
ている。そのため、
●
●
●
●
実装がふくらむ(オブジェクトの生存期間制御だけでな
く、オンメモリキャッシュの生存期間制御、オフメモリ時
のディスク吐き出し制御しなければならないなど)。
VMやI/Oキャッシュとの競合。
しかし、I/Oスケジューリングは最終的にカーネルに委ね
られる。
結果、2〜5倍ものディスクI/Oが発生する。
アーキテクチャ(メモリ)
●
Varnishでは全て仮想ページキャッシュ(RAMとし
て意識される)として取り扱い、オンメモリ・オフメモ
リを意識しない。頻繁にアクセスされるデータはオ
ンメモリであろうとするし、稀にしかアクセスされな
いデータはオフメモリとなる。その制御はVMによっ
て行われる。このため、
●
●
実装が小さくなる(オブジェクトの生存期間のみに専念
できる)。
ディスクI/Oの必要性やスケジュールをVMが行ってくれ
るため、余計なI/Oが発生しない。
アーキテクチャ(スピード)
●
●
●
char *p+=5;
strlen(p);
memcpy(p, q, l);
●
ロック
●
システムコール
●
コンテキストスイッチ
●
ディスクアクセス
●
ファイルシステム操作
0.00000001秒
1秒
CPU
人
間
の
感
覚↑
で
い
く
と
メモリ
プロテクション
メカニカル
0.01秒
9ヶ月余り
アーキテクチャ(スピード)
●
クラシカルなログ取りは極めて高コストである。
●
●
1回のファイルオープンと、都度のファイル出力が100万
回行われたとすると、1×0.010+1000000×0.001=16分
Varnishでは共有メモリにログ取りする。
●
1回のファイルオープン、1回のメモリマップと、都度共有
メモリ出力が100万回行われたとすると、2×0.010+
10000000×0.00001=10秒
アーキテクチャ(スピード)
●
●
Varnishの特徴的な設定ファイルはVarnish
Configuration Language(VCL)と呼ばれる専用
言語(Domain Specific)にある。
静的な、いわゆる「設定ファイル」と言われるものよ
りも、「判断」あるいは「ポリシー」を表現することに
徹している設定ファイルである。
アーキテクチャ(スピード)
●
●
Varnish自身、「いわゆる設定ファイル」に相当する
ような項目(パラメータ)が無いことはないが、それ
らは全て起動オプションで設定するか、動的に設定
する仕様(方針?)になっている。
そのため、設定ファイルと言いつつ、いわゆる「パラ
メータ」の類を持たない/設定しない/設定できない
(根性でできなくもないが…)。このあたりは微妙に
違和感があるが、開きなおることをお薦めする:−)。
アーキテクチャ(スピード)
●
●
●
Varnishは、汎用言語の持つ各種オーバーヘッドを
嫌ったため、独自の言語(VCL)仕様を有す。
言語設計や実装とのバランス、コンパイラ言語(大
前提!!)としてのポータビリティを勘案して、Varnish
ではC言語トランスレータが実装されている。
またVCLは、コンパイルされた後、Varnish本体に
動的に組み込まれる。また設定ファイルの切替えは
完全無停止で行える。「ポリシー」の切替えなので、
次のアクセスから使われるようになる。
アーキテクチャ(パフォーマンス)
●
スケーラビリティと高負荷時のパフォーマンス維持
のため、下記のフレームワークを使用している。
●
●
●
●
accept_filter(9)を使用したカーネル内前処理による、
過度のコンテキストスイッチの抑制。
kqueue(2)/kevent(2)による、ネットワークからの非同期
(イベントドリブン)で大量のI/Oに対するレスポンス。
マルチスレッドアーキテクチャの採用と1コネクション=1
スレッドで処理する、スケーラビリティと堅牢性の確保。
マルチプロセス・マルチスレッドを前提とした高並列性
を確保するための各種アルゴリズムの採用。
アーキテクチャ(まとめ)
●
●
●
以後の話は、アーキテクチャのまとめというよりは
むしろ、「設計(design)」に起因する各種よもやま
話となっている。
しかし忘れてはいけない。アーキテクチャありきで
デザインが行われているため、アーキテクチャの方
針に起因する実装上の罠が見え隠れしているとい
うだけの話である。
本末転倒の視点を見失ってはいけない:−)。それ
がphkクォリティ。
アーキテクチャ(まとめ)
●
●
●
サービスのために用意しなければならないメモリ
量(≒搭載メモリ量)の見積りは、コンテンツのアク
セス局所性に依存する。
メモリからあぶれた分はディスクに保存されるだけ
だし、それでも足りない分はバックエンドにアクセス
されるだけである。
全コンテンツをオンメモリでキャッシュすることを目
指す必要はないが、メモリが少な過ぎれば、スラッ
シングが発生して、性能劣化するので注意。
アーキテクチャ(まとめ)
●
●
大体において、全コンテンツの2割キャッシュできれ
ば8割方のアクセスはカバーできるものである:−)。
想像してみて欲しい。短時間に1GB以上もの分散
されたアクセスがある状態のサービスなんて運用
したくない:−)。
アーキテクチャ(まとめ)
●
FreeBSD/i386の制限に注意すること。サービスで
はFreeBSD/amd64で運用することを勧める。
●
●
●
メモリマネージメントがmalloc(3)ベースで行われるた
め、datasize 制限に制約される。
datasize制限のハードウェアリミット(kern.maxdsiz)は
1GB未満程度である。
1GB程度を越える場合、rtld(1)がシェアードオブジェク
ト(代表的なところでダイナミックリンクライブラリ)を読
むことができなくなるため、static linkされたバイナリ以
外起動しなくなる。これはrtld(1)のバグと認識されてい
るが、今のところ直る予定はない。
アーキテクチャ(まとめ)
●
●
●
OSのVMと考えが同じく、Varnishでは、メモリはファイ
ルのキャッシュであるという位置付けから、この制限は
ファイルサイズにも適用される。
Varnishの使用メモリ(ワーキングその他含む)が
1.5GB使われる程度が限度である。よって搭載メモリ量
は2GB程度で十分だし、それ以上の環境ではメモリが
無駄になる(他のサービスと共存する場合は別とし
て)。
これら制限に頭を悩ませたくなかったら、最初から
FreeBSD/amd64を使おう!
アーキテクチャ(まとめ)
●
●
●
しばし「デーモン」として直感的でない動きをするこ
とがある。
その最たる例はやはりログである。Varnish本体は、
ほとんどログファイルを吐かない。ログファイルを吐
く担当は別に存在する(varnishlog, varnishncs
a)。またそのログ(varnishlogによる)もバイナリロ
グである。
Varnish本体にkill -HUPは効かない。設定ファイル
を読み直させたいと思うなら、所定の手続きを取る
こと(後述)。
アーキテクチャ(まとめ)
設定ファイルの位置付けについて、簡単にまとめてみ
た。Varnishのようなとんがったソフトウェアがあると、
Sendmailの柔軟性とありがた味が見えてくる次第で
ある。
■言語のみ
■言語と設定
■設定のみ
Varnish
Sendmail
Apache
Postfix
他多数
アーキテクチャ(フィロソフィ)
Varnishの設計思想において、前提となる背景(哲学)があ
る。プログラムには随所にその哲学が見られる。
/*
* The panic string is constructed in memory, then copied to the
* shared memory.
*
* It can be extracted post-mortem from a core dump using gdb:
*
* (gdb) printf "%s", panicstr
*/
char panicstr[65536];
bin/varnishd/cache_panic.c より
カーネルか!?
アーキテクチャ(フィロソフィ)
●
Designed and coded
Poul-Henning Kamp (アーキテクト)
●
Project infrastructure
Dag-Erling Smørgrav
俺たちがルールだ! (?)
構造
Varnishは典型的なマネージャープロセス(root権限で動く)・ワーカー
プロセス(非特権ユーザー権限で動く)で構成されている。ワーカープロ
セス(子プロセス)は更に他数のワーカースレッドが活動している。
varnishd
マネージャープロセス
子プロセスマネージャー
VCLコンパイラ
ウォッチドックタイマー
他
ワーカープロセス
ストレージ
共有ログ/統計
アクセプター
バックエンド
ワーカースレッド
ハッシュ
キャッシュ破棄
他
言語
●
ここではVCLについて以下の項目について解説する。
●
言語仕様
●
宣言子
–
backend宣言子・director宣言子・acl宣言子・sub宣言子
●
関数
●
変数
●
正規表現
□参考文献
『VCL(7) – Varnish Configuration Language』
『VCL』 http://varnish.projects.linpro.no/wiki/VCL
『Using Varnish or VCL for webmasters』(Poul-Henning Kamp, 2008)
http://phk.freebsd.dk/pubs/varnish_vcl.pdf
言語(言語仕様)
●
VCLの文法はCおよびPerlに似せてある。
●
ブロックは { ステートメント; } でくくられる。
–
ブロックの終わり(})の後に ; は不要。
●
C言語のコードを埋め込む C{ C言語文 }C ブロック。
●
文字列は ”” (ダブルクォート)でくくる(%xxエスケープ有効)。
●
改行を含む文字列は {” 〜 ”} と書く(%xxエスケープ無効)。こ
れはブロックではなくステートメントの一種である。
●
ステートメントは ; で終わる。
●
VCL自体にプリプロセッサは無い。
●
C言語に変換されてコンパイル・組み込まれる。
●
いわゆる「識別子」は [A-Za-z][A-Za-z0-9_-]* である。
言語(言語仕様)
●
エスケープ文字 \ はない。代わりに%xx(xは16進数一
桁)で代用する。
–
–
–
●
%があって%xxというフォーマットになっていない場合は致命
的なエラーとなる。「%」や「”」を表現したい場合は「%25」あ
るいは「%22」と記述する。
\ の重ね打ちはどんな時(正規表現中)でも不要。
また制御文字(0x00〜0x20, 0x7f)を指定することができな
い。
文字列の連結は文字列を並べるだけでよい。
–
例: ”文字列1” req.url ”文字列2” ”文字列3”
言語(言語仕様)
●
コメントは以下の3種類が使える。
–
–
–
●
/* ~ */ (C由来)
//
(C++由来)
#
(Perl由来)
他のファイルから持ってくるための include 文。
include “ファイル”; として使う。このスタイルを守れば不条理
なくらいどこでも使える(ステートメントの途中でも)。
ファイルはフルパスで記述すること。path originを期待しない
(厳密には/usr/local/varnish/インスタンス(ホスト)名/が
path origin)。
言語(言語仕様)
VCLには明示的な型はないが、システム変数、文脈において
暗黙的に型が使用されている。明示的な表現がないため、内
部表現で型を解説する。Prefixについては後述。
●
BOOL型
●
FLOAT+SIZE Prefix
true または false
●
INT型
●
FLOAT型
RATE型
FLOAT+RATE Prefix
unsigned int型([0-9]+)
●
SIZE型
●
TIME型
FLOAT+TIME Prefix
double型([0-9]+(\.[0-9]*)?)
●
STRING型
“文字列”など
●
RTIME型
●
符号+FLOAT+TIME Prefix
言語(言語仕様)
数字(浮動小数点)指定の後に以下のプレフィックス
を付け加えることでオーダーを調整することができる。
●
TIME Prefix(秒単位)
●
SIZE Prefix(バイト単位)
●
ms
(ミリ秒 / ÷ 1000)
●
b
(バイト / × 1)
●
s
(秒 / × 1)
●
kb
(キロバイト / × 1024b)
●
m
(分 / × 60秒)
●
mb
(メガバイト / × 1024kb)
●
h
(時 / × 60分)
●
Mb
(メガバイト / × 1024kb)
●
d
(日 / × 24時間)
●
gb
(ギガバイト / × 1024mb)
●
w
(週 / × 7日)
●
Gb
(ギガバイト / × 1024mb)
RATE Prefix は上記組み合わせで作ることができる。
例: Mb/w (メガバイト/週 ⇒ バイト/秒に内部で変換)
言語(言語仕様)
二項演算子各種
●
==
(比較 一致)
●
!=
(比較 不一致)
●
●
●
●
●
<=
<
>=
>
~
●
!
(否定 – boolean)
●
||
(論理和 - boolean)
●
&&
(論理積 - boolean)
●
=
(代入)
●
+=
(代入 加算後)
●
-=
(代入 減算後)
●
*=
(代入 乗算後)
●
/=
(代入 除算後)
(比較 以下)
(比較 より小さい)
(比較 以上)
(比較 より大きい)
(包含 - 正規表現またはACLのマッチングで使用)
言語(言語仕様)
●
+
(加算)
●
-
(減算)
●
*
(乗算)
●
/
(除算)
●
++
(未定義 - たぶんインクリメンタル)
●
--
(未定義 - たぶんデクリメンタル)
●
<<
(未定義 - たぶん左シフト)
●
>>
(未定義 - たぶん右シフト)
※剰余はない
言語(言語仕様)
●
制御構文は if に限る(ループ構文は存在しない)。
–
–
–
●
if
elsif または elseif
else
組み込み変数しかなく、代入時に set を使用する。
「=」「+=」「-=」「*=」「/=」の代入操作時にsetを必要とする。
例: set req.hash += req.http.host ”#” req.url;
言語(backend宣言子)
●
backend宣言子
バックエンドサーバーに関する情報を記述する。「バック
エンド識別子」とともに、下記の設定を行う(host のみ
必須)。
–
host (STRING型)
バックエンドサーバーのホスト名またはIPを指定。IPv4またはIPv6で
一意であることが必要。ホスト名の場合、正引きした結果、複数のIP
(またはIPv6)アドレスを持つ場合NGとなる。IPv4およびIPv6がそれ
ぞれ1つづつの場合はOK。
–
port (STRING型)
バックエンドサーバーのポート名またはポート番号を指定。指定が無
い場合、80が使用される。
言語(backend宣言子)
–
host_header (STRING型)
HTTPのHost:ヘッダーで指定する名前。指定が無い場合、hostが使
用される。正直これはprobe(後述)内で使われるべき設定だと思う。
–
connect_timeout (TIME型)
バックエンドサーバーに接続に行くときのタイムアウト時間。指定が無
い場合、Varnishディフォルト値の400ms。
–
max_connections (INT型)
バックエンドサーバーに接続可能な最大接続数。指定が無い場合、
0(無制限)。
言語(backend宣言子)
–
probe (probe は更に下記の情報を有す)
●
●
●
●
バックエンドサーバーのヘルスチェックのためのパラメータを指定す
る。全てのパラメータは省略可能である。
url (STRING型)
ヘルスチェックに使用するURLを指定する。reqeustが指定され
てない場合に使用される。更に指定がない場合は「/」となる。
request (STRING型)
ヘルスチェックに使用するHTTPリクエストをそのまま記述する。
複数の文字列を指定でき、それぞれの文字列の結合時に\r\nを
付加する。requestが指定されるとurlの指定は無効になる。
timeout (TIME型)
応答が返ってくるまでのタイムアウトの指定。指定が無い場合は、
2秒。
interval (TIME型)
ヘルスチェックの時間間隔の指定。指定が無い場合は、5秒。つま
り5秒に1回ヘルスチェックを行う。
言語(backend宣言子)
●
●
window (INT型)
ヘルスチェックの状態をチェックする直近に行われた回数を指定
する。指定が無い場合は、8回。直近8回のヘルスチェックの結果
に基づいて判定が行われる。
threshold (INT型)
windowで指定された回数のうち、threshold値以上の回数、正常
であった場合、「Healthy」と判定される閾値。指定が無い場合
は、3回。上記と合わせて8回中3回正常に応答を返せば、指定さ
れたバックエンドサーバーは正常であると判断される。
言語(backend宣言子)
windowとthresholdには一定のルールがかせられる。
●
●
windowが指定された場合、 thresholdを指定しなければならない。
windowが指定されてない場合、thresholdが指定されていると、
windowはthreshold+1が設定される。
●
windowもthresholdも最大は63。0については要注意。
●
windowはthreshold以上でなければならない。
ヘルスチェックにより、バックエンドが正常であると判断されるに
は、最大timeout×threshold+interval×(threshold-1)秒必要とす
る。
intervalを短めに取って、サーバーに負荷をかけるか、intervalを長
めに取って、稼働状態にするまでの時間を長くとるかなど、トレード
オフが発生する。
言語(backend宣言子)
backend宣言子を最大限に指定した場合の例:
backend default {
}
.host
.port
.host_header
.connect_timeout
.max_connections
.probe
.url
.request
=
=
=
=
=
=
=
=
.timeout
.interval
.window
.threshold
=
=
=
=
}
バックエンド識別子は
「default」である。
➢ requestの設定があるので
urlの設定は無効である。
➢
“192.168.0.1”;
“http”;
“www.example.jp”;
400ms;
0;
{
“/”;
“GET / HTTP/1.1”
“Host: www.example.jp”
“Connection: close”;
2s;
5s;
8;
3;
言語(director宣言子)
●
director宣言子
複数のバックエンドをどう取り扱うかを記述する。
「director識別子」を指定し、「director種別」を
「random」または「round-robin」の2つから選択する。
最低1つのバックエンドを指定する必要がある。
–
–
retries (INT型 / random の時のみ使用 / オプション)
backend(必須), weight(randomの時必須)の組を指定
●
●
backend (backend 識別子)
バックエンドサーバーを指定する。backend識別子を指定する方
法とbackend宣言子で指定するような形で指定する方法がある。
weight (INT型 / random の時のみ使用)
バックエンドサーバーへのアクセス比率を「比重」で指定する。
言語(director宣言子)
director宣言子を最大限に指定した場合の例:
director random_dir random {
.retries
}
= 4;
{ .backend = default_1; .weight = 1; }
{ .backend = default_2; .weight = 1; }
director round-robin_dir round-robin {
{ .backend = default_1; }
{ .backend = default_2; }
}
ディレクター識別子はそれぞれ「random_dir」「round-robin_dir」
である。
➢ random_dirは比重を合計した2に対し、比重に応じた確率でアクセ
スが行われる。この場合1/2。
➢
言語(acl宣言子)
●
acl宣言子
アクセスコントロールのためのIPのリストを記述する。
「acl識別子」を指定した後、1個以上のIPまたはホスト
名を指定する。
–
IPアドレス (IPアドレス型)
“IPアドレス”/プレフィックス; と指定する。
–
ホスト名 (文字列またはIPアドレス型)
“ホスト名”;と指定する。DNS問い合わせを行い、”IPアドレス”/32;の
形に展開される(複数可)。DNSの問い合わせタイミングはVCLのコ
ンパイル時に行われ、ランタイムでないことに注意。
プレフィックスを指定することができるが、参照解決の結果、IPv4また
はIPv6いずれかでなければならない。
言語(acl宣言子)
aclの評価はトライ(プレフィックス)木に
よる最適化が行われている。
●
●
●
●
自己矛盾(”localhost”; !
“localhost” のような)を事前に排除
(実際には致命的エラー)
10
複雑怪奇な設定であったとしても、
一意性と最長一致性を担保
アルゴリズムの特性から、ACLの数
によらず検索性能が一定である
またトライ木をそのままコードに落と
し込む(生成)ため、無駄が少ない。
IPv6
IPv4
0
128
172
192
16
168
言語(acl宣言子)
acl宣言子を最大限に指定した場合の例:
acl clients {
➢
“localhost”;
!
“localhost”;
“127.0.0.1”/32;
ホスト名を指定した場合、必ず参照解決できな
ればならない。参照解決できなくて、それを無視
していい場合は括弧(())でくくる。その場合、最
初からなかったものとして取り扱われる。
“0000:0000:0000:0000:0000:0000:0001”/128;
( “www.example.jp”/32 );
! ( “www.example.jp” );
“10”/8;
!
}
“10.0.1”/24;
➢
➢
ホスト名の参照解決はランタイムに行われない
ので注意。
!と()の対応に注意。またIPとマスク値の指定が
独特の表現なので注意。ホスト名にマスク値を
付ける時は要注意。
言語(sub宣言子)
●
sub宣言子
サブルーチンを定義し、Varnishにおける各種「判断」を
行う場を提供する。C言語においてmain関数がプログ
ラムの入口であったように、Varnishでは9個のサブルー
チンがそれぞれの用途毎に応じて呼び出される。
また、9個のサブルーチンを起点にユーザー定義サブ
ルーチンの呼び出しが可能である。
call サブルーチン; としてユーザー定義サブルーチンを
呼び出せる。
言語(sub宣言子)
pass
pipe
vcl_recv
vcl_pass
lookup
vcl_hash
pass
pass
バックエンド
から
vcl_miss
hash
vcl_error
deliver
vcl_fetch
fetch
キャッシュ無
error
deliver
pass
キャッシュ有
vcl_hit
vcl_deliver
deliver
deliver
vcl_pipe
pipe
pass
9つのサブルーチンとアクションキーワードによる相関関係
□参考文献
sed -n '/^DOT/s///p' bin/varnishd/cache_center.c | dot -Tpsより
言語(sub宣言子)
●
サブルーチン
ユーザー定義サブルーチンの呼び出しは
call サブルーチン識別子;
として行う。この時、サブルーチンが非0(return 1;など)
を返すと、アクションが確定したものとして、それ以上処
理を進めない。サブルーチン内に return が無い場合、
return 0; が指定されたものとしてリターンする。
言語(sub宣言子)
sub宣言子を使用した例:
sub subroutine-1 {
/* 暗黙の return 0; */
}
➢
➢
sub subroutine_2 {
call subroutine-1;
return 1;
/* 暗黙の return 0; */
}
sub vcl_recv {
call subroutine-1;
lookup;
call subroutine_2;
/* 暗黙の return 0; */
}
➢
➢
➢
サブルーチン識別子は、subroutine-1,
subroutine_2, vcl_recvの3つ。
returnの引数はINT型。
サブルーチンからの戻りを、呼び出した
側から評価することはできない。0が
返ってきたから処理が継続している。
サブルーチンの最後に到達した時に
returnが存在しない場合、retrun 0;が
指定されたものと評価される。
Varnishに返るまでにアクションが確定
しなければならない。
言語(関数)
●
関数
Varnishにも組み込みで、いくつかのビルトイン関数が
用意されている。サブルーチンとは違い、関数の戻り値
は、呼び出し元で自由にできる。現時点で使用可能な
関数は以下の4つある。
–
–
–
–
regsub
regsuball
purge_url
purge_hash
言語(関数)
●
regsub(文字列, 正規表現, 置き換え文字列);
「文字列」中の「正規表現」に最初に合致するものを「置き換え
文字列」に置き換える。
例:set req.hash+=regsub(req.url, "\?.*$", "");
●
regsuball(文字列, 正規表現, 置き換え文字列);
regsub関数の「最初に」ではなく「全て」に適用されたもの。
例:set req.url=regsuball(req.url, “\$(([0-9A-Faf])([0-9A-Fa-f]))”, “\1:\3\2”);
※上記関数の正規表現と置き換え文字列(特に参照)については後
述する正規表現について参照のこと。
言語(関数)
●
purge_hash(正規表現);
正規表現に合致するオブジェクトのキャッシュの消し込みを行
う。ホスト(バーチャルホスト)単位込みでの消し込みが可能。
例:purge_hash(”www.example.jp#/.*”);
●
purge_url(正規表現);
正規表現に合致するURLのキャッシュの消し込みを行う。ホスト
(バーチャルホスト)に関係なく消し込みが可能。
例:purge_url(“\.jpg”);
言語(変数)
●
グローバル変数
●
●
now
エポック秒からの現在の時間
各サブルーチンで使用可能なもの
●
client.ip
クライアントのIP
●
server.ip
クライアントからの接続を受けた時のサーバーのIP
●
server.port
クライアントからの接続を受けた時のサーバーのポート
言語(変数)
●
req.request
リクエストタイプ(GET, POST等)
●
req.url
リクエストURL
●
req.proto
クライアントからのHTTPプロトコルバージョン
●
req.http.header
HTTPリクエストヘッダー
●
req.hash
キャッシュオブジェクトへの参照キー
●
req.backend
指定されたバックエンドサーバー
●
req.restarts
再処理が行われた回数
●
req.grace
バックエンドが処理(コンテンツ生成)を終えるまでの間、他のス
レッドが滞らないよう、古いキャッシュデータを使用する猶予期間を
指定する。
言語(変数)
●
bereq.request
バックエンドに送るリクエストタイプ
●
bereq.url
バックエンドに送るURL
●
bereq.proto
バックエンドに送るHTTPプロトコルバージョン
●
bereq.http.header
バックエンドに送るヘッダーリクエスト
言語(変数)
●
obj.proto
キャッシュのHTTPプロトコルバージョン
●
obj.status
キャッシュのHTTPステータスコード
●
obj.response
キャッシュのHTTPレスポンスメッセージ
●
obj.cachable
キャッシュオブジェクトが「キャッシュ可能」かどうかの状態(可能/不
可能)を保持する。ステータスコードが200, 203, 300, 301, 302,
404, 410でExpiresやCache-Controlヘッダーにより与えられる
TTL(生存期間)が0でないものをキャッシュ可能とする。
●
obj.ttl
●
obj.lastuse
キャッシュの生存期間(Time To Live / 秒)
キャッシュが最後にリクエストされてからの経過時間(秒)。
言語(変数)
●
resp.proto
レスポンス時のHTTPプロトコルバージョン
●
resp.status
HTTPステータスコード
●
resp.response
HTTPレスポンスメッセージ
●
resp.http.header HTTPレスポンスヘッダー
言語(変数)
変数名
now
client.ip
server.ip
server.port
req.backend.healthy
req.request
req.url
req.proto
req.http.header
req.hash
req.backend
req.restarts
req.grace
bereq.request
bereq.url
bereq.proto
bereq.http.header
obj.proto
obj.status
obj.response
obj.cachable
obj.ttl
obj.lastuse
resp.proto
resp.status
resp.response
resp.http.header
属性
RO
RO
RO
RO
RW
RW
RW
RW
RW
WO
RW
RO
RW
RW
RW
RW
RW
RW
RW
RW
RW
RW
RO
RW
RW
RW
RW
型
TIME型
Ip型
Ip型
INT型
BOOL型
STRING型
STRING型
STRING型
HEADER型
HASH型
BACKEND型
INT型
TIME型
STRING型
STRING型
STRING型
STRING型
STRING型
INT型
STRING型
BOOL型
TIME型
TIME型
STRING型
INT型
STRING型
HEADER型
vcl_recv vcl_pipe
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
×
×
○
○
○
○
○
○
×
○
×
○
×
○
×
○
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
×
vcl_pass
○
○
○
○
○
○
○
○
○
×
○
○
○
○
○
○
○
×
×
×
×
×
×
×
×
×
×
vcl_hash vcl_miss vcl_hit
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
○
×
×
○
○
○
○
○
○
○
○
○
×
○
×
×
○
×
×
○
×
×
○
×
×
×
○
×
×
×
×
×
×
×
×
○
×
×
○
×
×
○
×
×
×
×
×
×
×
×
×
×
×
×
vcl_fetch
○
○
○
○
○
○
○
○
○
×
○
○
○
○
○
○
○
○
○
○
○
○
○
×
×
×
×
vcl_deliver
○
○
○
○
○
×
×
×
×
×
×
○
○
×
×
×
×
×
×
×
×
×
○
○
○
○
○
vcl_error
×
○
○
○
×
○
○
○
○
×
○
○
○
×
×
×
×
○
○
○
○
○
○
×
×
×
×
言語(正規表現)
●
●
●
Varnishの正規表現の実装はPOSIXのregex(3)の
仕様に準拠する。
いわゆるREG_EXTENDED|REG_ICASEが有効
になっているため、拡張正規表現(egrepタイプの)
で大文字小文字を区別しない。
regsub/regsuballのように置換文字列の中でグ
ルーピング(「()」による)にマッチした文字列の参
照方法は「\0」〜「\9」で行う。10個を越えるグルー
ピングには対応していない。
コマンドの使い方
●
Varnishのインストールおよびセットアップについて
解説する。
●
インストール方法
●
varnishdコマンドの使い方
●
varnishadmコマンドの使い方
●
varnishhistコマンドの使い方
●
varnishtopコマンドの使い方
●
●
varnishstatコマンドの使い方
サービスの起動の仕方
インストール方法
●
ports/www/varnishよりインストールを行う。
●
/usr/local/bin以下にプログラムが
●
/usr/local/sbin以下にデーモンが
●
/usr/local/etc/varnish以下に設定ファイル(.vcl)が
●
/usr/local/varnish以下にワーキングディレクトリが
インストールされる。他にもライブラリやヘッダファイル、
マニュアル等がインストールされるが、ここでは取り上
げない。
varnishdコマンドの使い方
●
varnishdはHTTPアクセラレータを担う中核となる
プログラムである。varnishdコマンドには以下のオ
プションがある。
●
-a address|address:port|:port ...
–
–
●
クライアントからのアクセスを受け付ける(Listen)アドレス/
ポートを指定する。複数指定したい場合は、空白で区切ってリ
ストアップする。
例: -a “:80 :8080 127.0.0.1 192.168.0.1:10080 [::1]:80”
-b backend[:port]
–
バックエンドのサーバーを指定する。portが指定されない場
合、8080が仮定される。通常使うことはない。VCLを書かずに
簡単に済ませたい時に使う。
varnishdコマンドの使い方
●
-C
–
●
-d
–
●
フォアグラウンドで起動する。
-f 設定ファイル
–
●
デバッグモードを有効にする。
-F
–
●
C言語にトランスレートした結果を出力して終了する。
ビルトインのディフォルト設定の代わりに指定された設定ファ
イルを使用する。
-g グループ名(グループID)
–
非特権グループで子プロセスを起動する。
varnishdコマンドの使い方
●
-h タイプ[,オプション]
–
ハッシュアルゴリズムとオプションを指定する。
●
●
●
simple_list (または simple)
– 双方向リスト(プロダクションユースでは使用しない)
classic[,バケット数]
– 標準的なハッシュテーブル。ディフォルトのバケット数は16383で、
キャッシュするオブジェクト(URL)の数の1/10程度を指定する。つ
まりディフォルトで16万オブジェクト程扱える。なお、この数字は素
数である方がよい。
-l 共有ログファイルのサイズ
–
共有ログファイルの大きさを指定する。ディフォルトで80MBで
8MBよりも小さくするのはよろしくない。
varnishdコマンドの使い方
●
-n インスタンス名
–
●
-P PIDファイル
–
●
varnishdが使用するテンポラリファイルやパーシステンスス
テートを保持するためのディレクトリを構成するための名前を
指定する。ディフォルトはホスト名で、/usr/local/varnish/イン
スタンス名/として使用する。インスタンス名を/で始めた場合、
ディレクトリそのものとして解釈される。
指定されたPIDファイルにプロセスのPIDを書き込む。
-p パラメータ=値
–
ランタイムパラメータを個別に指定する。ランタイムパラメータ
については後述。
varnishdコマンドの使い方
●
-s タイプ[,オプション]
–
バックエンドストレージを指定する。複数回指定することで、複
数のストレージファイルを指定できる。
●
●
malloc – malloc(3)により確保された各々のオブジェクトを保持する。
file[,パス[,サイズ[,粒度]]]
– 指定されたパス(ディレクトリまたはファイル)によるアリーナバッ
クエンドからオブジェクトを保持する。ディレクトリを指定した場
合、テンポラリファイルが作成される。
– ファイルが存在する場合は、指定されたサイズに切り詰められる
か拡張される。
– サイズの指定は、絶対指定によるものと、%指定による空き容量
の割合によるものと、2つの方法がある。
– ファイルが作成されるにせよ拡張されるにせよ、varnishdは事前
アロケートを行わないので(つまりスパース)、フラグメンテーショ
ンが気になる場合は、事前にdd(1)等により確保しておく必要が
ある。
varnishdコマンドの使い方
–
●
-T address[:port]
–
●
マネージメントインターフェースのためのListenポートを指定
する。マネージメントインターフェースについてはvarnishadm
にて解説する。
-t TTL
–
●
粒度パラメータの指定は確保するサイズの粒度を意味し、ディ
フォルトでVMページサイズとなる。たくさんの小さなオブジェクト
をキャッシュするのであれば、このパラメータを小さく設定すべき
である。
キャッシュドキュメントの最小キャッシュ保持時間を指定する。
これはdefault_ttlランタイムパラメータへのショートカットであ
る。
-u ユーザー名(ユーザーID)
–
非特権ユーザーで子プロセスを起動する。
varnishdコマンドの使い方
●
-w min[,max[,timeout]]
–
ワーカースレッドの数を指定する。minでスタートし、maxまで
を上限とする。アイドル時間がtimeout時間に達したスレッド
は終了し、minまで減らされる。minとmaxが指定された場合、
timeoutは効果を失う。それぞれthread_pool_min,
thread_pool_max, thread_pool_timeoutランタイムパラメー
タのショートカットである。
基本的に必要十分な程度のディフォルトパラメー
タが設定されているので、ストレージサイズを調整
するくらいしか使用することはない。
ラ
ン
タ
イ
ム
パ
ラ
メ
ー
タ
ー
パラメータ名
意味
user
子プロセスの非特権ユーザー
group
子プロセスの非特権グループ
キャッシュのディフォルトのTTL
default_ttl
thread_pools
ロックコンテンション低減のためのワーカースレッドの数
thread_pool_max
ワーカースレッドの最大数
thread_pool_min
ワーカースレッドの最小数
thread_pool_timeout
アイドルワーカースレッドのタイムアウト時間
thread_pool_purge_delay パージスレッド間の待ち時間
thread_pool_add_thresholdワーカースレッド作成のためのオーバーフロー閾値
thread_pool_add_delay スレッド作成間の最低待ち時間
thread_pool_fail_delay
スレッド作成に失敗した時の最低待ち時間
overflow_max
リクエストキューのワーカースレッド数に対するオーバーフロー割合
sess_workspace
HTTPプロトコル処理用ワークスペースのサイズ
obj_workspace
HTTPヘッダー処理用のワークスペースのサイズ
shm_workspace
共有ログ処理用のワークスペースのサイズ
default_grace
ディフォルトの猶予期間
sess_timeout
パーシステンスセッションの維持時間
pipe_timeout
PIPEセッションの維持時間
send_timeout
クライアントへの送信タイムアウト時間
auto_restart
子プロセスが死んだら自動再起動する
fetch_chunksize
Fetcherが使用するディフォルトのチャンクサイズ
共有ログにVCL実行トレースを記録するかどうか
vcl_trace
クライアントからのアクセスを受け付けるListenポート
listen_address
Listenキューの数
listen_depth
srcaddr_hash
ソースアドレスのハッシュのバケット数
ソースアドレスエントリーのTTL
srcaddr_ttl
バックエンドへのリクエストを強制的にHTTP/1.1とする
backend_http11
クライアントへの応答を強制的にHTTP/1.1とする
client_http11
マスターからのCLIに対する子のタイムアウト時間
cli_timeout
親から子へのping間隔
ping_interval
cc_command
VCLコンパイル時のCコンパイラやそのオプションの指定
max_restarts
1リクエストに対する最大バックエンド選択回数
connect_timeout
ディフォルトのバックエンドへの接続タイムアウト時間
accept_fd_holdoff
ファイルディスクリプタが尽きたときのスレッドのスリープ時間
prefer_ipv6
バックエンドがデュアルスタックであった場合のIPv6優先
cli_buffer
CLIのバッファサイズ
log_hashstring
ハッシュ文字列を共有ログに記録する
log_local_address
クライアントの接続先Listenポートを共有ログに記録する
acceptor
アクセプターカーネルインターフェースの選択
diag_bitmap
診断のためのビットマップ
err_ttl
エラーページのTTL
purge_dups
重複したpurgeの発見と除去
ディフォルト値
nobody
nogroup
120秒
1スレッド
500スレッド
5スレッド
300秒
1000ミリ秒
2リクエスト
200ミリ秒
200ミリ秒
100%
8192バイト
8192バイト
8192バイト
10秒
5秒
60秒
600秒
on
128キロバイト
off
:80
1024
1049バケット
30秒
off
off
5秒
3秒
cc..
4回
400ミリ秒
50ミリ秒
off
8192バイト
off
off
default
0x0000
0
off
最小
-
最大
0
UINT_MAX
1
UINT_MAX
なし(0)
1
なし(0)
2
なし(0)
1
なし(0)
100
0
UINT_MAX
0
UINT_MAX
100
UINT_MAX
0
UINT_MAX
1024
UINT_MAX
1024
UINT_MAX
4096
UINT_MAX
0
UINT_MAX
0
なし(0)
0
なし(0)
0
なし(0)
off
on
4
UINT_MAX÷4
off
on
0
UINT_MAX
63
UINT_MAX
0
UINT_MAX
off
on
off
on
なし(0)
0
なし(0)
0
0
なし(0)
0
UINT_MAX
0
3600×1000
off
on
4096
UINT_MAX
off
on
off
on
0x0000 0xf07f
0
UINT_MAX
off
on
有効タイミング 実験的
要再起動
要再起動
次のアクセスから
順次
○
順次
○
順次
○
順次
○
順次
○
即時
○
即時
○
即時
○
即時
○
順次
順次
順次
順次
即時
即時
順次
即時
即時
○
即時
要再起動
要再起動
要再起動
○
即時
○
即時
○
即時
○
即時
要再起動
要再起動
即時
即時
即時
○
即時
○
即時
即時
即時
要再起動
○
即時
即時
即時
-
varnishadmコマンドの使い方
●
varnishadmコマンドはvarnishdに対する管理ツー
ルである。以下のオプションが存在し、CLIと呼ばれ
るコマンドをvarnishdに実行させる。
●
-T address:port
–
●
マネージメントインターフェース(varnishdで-Tオプションで指
定される)を指定する。
コマンド(CLI)
varnishadmコマンドの使い方(CLI)
●
help
使用可能なコマンドの一覧を表示する。
●
param.set パラメータ名 値
ランタイムパラメータを設定する。
●
param.show パラメータ名
ランタイムパラメータの現在の値を表示する。
●
param.show [-l]
ラインタイムパラメータ一覧(値を含む)を表示する。もし-lオプションが
指定されている場合は、簡単な説明を含む。
●
ping [タイムアウト]
子プロセスにpingする。
●
start
子プロセス(サービス)を開始する。
varnishadmコマンドの使い方(CLI)
●
stats
サーバー統計値を表示する。統計値はサーバー起動時からの合計値
で、変化量を見たい場合はvarnishstatコマンドを使用する。
●
status
子プロセスの活動状態を表示する。
●
stop
子プロセス(サービス)を停止する。
●
url.purge 正規表現
指定された正規表現にマッチするURLのキャッシュを無効にする。
●
vcl.discard コンフィグ名
コンフィグ名(起動時のVCLはboot)を抹消する。リファレンスカウント
が1以上(VCLが各スレッド使われている間)の時は何もしない。
●
vcl.inline コンフィグ名 VCL
クォートされたVCLコードをそのまま取り込んだ新しい設定を作る。本
来ならファイルから読み込まなければならないところを、オンザフライで
設定したい場合に使う。
varnishadmコマンドの使い方(CLI)
●
vcl.list
存在する設定ファイルとリファレンスカウント(使用中のスレッドの数)
の一覧を表示。アクティブになっている設定には「active」とつく。
●
vcl.load コンフィグ名 設定ファイル名
指定された設定ファイル名に記述されている設定をコンフィグ名として
ロードする。この時点では有効にならない。vcl.useを使用すること。
●
vcl.show コンフィグ名
指定されたコンフィグ名の設定内容を見る。
●
vcl.use コンフィグ名
以後にアクセスされるリクエストは新しいコンフィグ名で指定される設
定を使用するようにする。旧アクセスはセッションが終了次第、開放さ
れる。完全に使用しないようにするためにはvcl.discardを実行する必
要がある。
varnishhistコマンドの使い方
●
●
●
●
●
直近最大2000アクセス(固定/n=?の値)に対する応答時
間と数をヒストグラムにして表示するプログラム。
横軸を対数とし、10-6秒から102秒までスケールされてい
る。
縦軸は該当する応答時間におけるアクセス数の累積で、
「1:n」で比率が変わる(累積個数×nで実際のアクセス数
となる)。
キャッシュにヒットしたものを「|」で、ヒットしなかったものが
「#」で表示される。
細かいオプションは色々あるが、あまり使うことはない。
varnishtopコマンドの使い方
●
共有ログエントリのランキングを表示する。
●
思ったよりも使えないので省略。
varnishstatコマンドの使い方
●
●
サーバー内の各種リソースの利用統計を秒間使用量で表示し
てくれるコマンド。正直これも使いでがない。
ただし、以下のコマンドを使用した結果を加工すると面白い結
果が得られる。
varnishstat -1 -f
client_req,cache_hit,cache_hitpass,cache_miss,sm_balloc,sm_bfree
ヒット率: (cache_hit+cache_hitpass)/client_req
ミス率:
cache_miss/client_req
その他(pipe等)の率:
(cache_req-cache_hit-cache_hitpass-cache_miss)/cache_req
共有メモリ使用量: sm_balloc / 共有メモリ空き容量: sm_bfree
共有メモリ使用率: sm_balloc/(sm_balloc+sm_bfree)
サービスの起動の仕方
●
以下の3つのrcNGスクリプトがインストールされている。
●
●
●
varnishd – varnishd本体を起動するスクリプト
–
varnishd_enable=”YES”
–
varnishd_listen=”:80”
–
varnishd_config="/usr/local/etc/varnish/service.vcl"
–
varnishd_storage="file,/tmp,1024M"
varnishlog – varnishlogをデーモンモードで起動するスクリプト
–
varnishlog_enable="YES"
–
varnishlog_file="/var/log/varnishd.bin"
varnishncsa – varnishncsaをデーモンモードで起動するスクリプト
–
varnishncsa_enable="YES"
–
varnishncsa_flags="-P /var/run/varnishncsa.pid -c -D -a -w
/var/log/varnish-access.log"
サービスの起動の仕方
●
/etc/syslog.conf
ほとんど出力することはないが0ではないので。
local0.*
●
/var/log/varnishd.log
/etc/newsyslog.conf
1日1回程度はローテーションした方がいい。
/var/log/varnishd.log
644 156
* $W0D0 JC
/var/log/varnishd.bin
644 1095 * @T00
JB
/var/run/varnishlog.pid
/var/log/varnish-access.log
644 1095 * @T00
JB
/var/run/varnishncsa.pid
サービスの起動の仕方
●
/etc/sysctl.conf
各種パラメータを設定しておく。
kern.ipc.nmbclusters=65536
kern.ipc.somaxconn=16384
kern.maxfiles=131072
kern.maxfilesperproc=104856
kern.threads.max_threads_per_proc=4096
●
/boot/loader.conf
●
各種パラメータを設定しておく。
kern.ipc.maxsockets="131072"
kern.ipc.maxpipekva="104857600"
□参考文献
『Performance』 http://varnish.projects.linpro.no/wiki/Performance
サービスの起動の仕方
●
カーネルコンフィギュレーション
●
SCHED_ULEを有効に。
●
ZERO_COPY_SOCKETSは危険。サービスには使えない。
●
●
FreeBSD/i386ではKVA_PAGES=512を指定しておく。ユーザー
ランドのメモリ消費量も大きいが、カーネルのメモリ消費量も馬
鹿にならないため。
その他
●
●
ファイルシステムのマウントをsoftupdateではなくsyncにするよう
指示があるが、時々行われるであろうメンテナンス時に後悔する
こと一押しなのでお薦めしない。
ログを吐かなければ何が起こってるのかわからないくらい静か。
ディスクI/O性能もファイルシステムの特性も意味はない。
運用
●
運用においては、典型的には設定ファイルの修正および反映
が手順として挙げられる。以下におおよその手順を示す。
●
●
●
●
●
●
設定ファイルの編集
文法チェック
varnishd -C -f 設定ファイル名
設定の読み取り
varnishadm -T:6082 vcl.load 新コンフィグ名 設定ファイル名
設定の有効化
varnishadm -T:6082 vcl.active 新コンフィグ名
設定の確認
varnishadm -T:6082 vcl.list
旧設定の破棄
varnishadm -T:6082 vcl.discard 旧コンフィグ名
運用
●
●
VarnishはGETおよびHEADメソッド(バックエンド
に対してはGETを実行)しかキャッシュしない。これ
はVCLによる制御以前のVarnishの仕様である。
VCL作成のポイントはポリシー決めにある。以下の
要素を考慮して設定を行う。
●
●
●
仮想ホストおよびURLによるグルーピング
グルーピングそれぞれにおけるバックエンド指定
またそのコンテンツのキャッシュの可否、キャッシュ保持
時間の制定
参考文献
●
基本解説
●
●
言語ネタ
●
●
http://phk.freebsd.dk/pubs/varnish_vcl.pdf
パフォーマンスチューニング
●
●
http://www.bsdcan.org/2007/schedule/attachments/
18-The_Varnish_HTTP_Accelerator_Poul-Henning
%20Kamp
http://varnish.projects.linpro.no/wiki/Performance
その他
●
プログラムソース
参考文献
●
本資料
●
●
http://www.ninth-nine.com/presentation/AsiaBSDCon2009-Varnish.pdf
本資料のエラッタ(絶対出てるはず!)
●
http://www.ninth-nine.com/presentation/AsiaBSDCon2009-Varnish_errata.txt