The Operation and Installation of the Varnish HTTP Accelerator 株式会社エンターモーション システム開発部 重村法克 n_shigemura@entermotion.jp nork@ninth-nine.com nork@FreeBSD.org 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
© Copyright 2024 Paperzz