Caching Rules

Caching Rulesタブでの設定

CacheFuに同梱されているドキュメント(cachefu/CacheSetup/doc/audience.rest)の超訳です。
Page 7 of 7.

キャッシングルールはCacheFuの中核となる概念です。これはZopeへのリクエストを分析してルールを適用するためのルールセットです。ルールがリクエストにマッチするとそのルールに応じた動作が適用されます。

た とえばブラウザがあるCSSを受け取り、このリクエストがZopeまで届いたとすると(すなわちSquidなどが返したわけではないとすると)、リクエス トはここで設定したルールのチェックを受けながら届きます(ルールは上から下へ順番に評価されます)。マッチしたルールは次のような感じで適用されます:

  • そのページをZODBのメモリにキャッシュする
  • ヘッダを含んだリクエストがレスポンスと共に送られ、これらのヘッダはブラウザによって解釈され、プロクシにキャッシュされる(たとえば「これを1時間キャッシュしておくように」とか「これはキャッシュしないように」などというように)

ルールは一番最初にマッチしたものが採用されるので、すべてのリクエストに対して一つのルールだけが適用されます。もし一つもルールがマッチしなかった場合は、何も起こりませんし、そのページはふつうに返される事でしょう。

それではCacheFuに最初から備わっているルールを少し見てみましょう。これらのルールを理解する事が、CacheFuを理解する事につながります。

HTTPCache

このキャッシュはCacheFuの外側でマッチする事はありません。しかしこれをカスタマイズすると非常に便利です。

こ のルールは、(変更される事がなく)完全にキャッシュされてもよいページ(あるいはたとえばロゴなどの画像)があるときに使われます。ログインしてもしな くても、コンテンツの内容が変更されても、「常に」同じように見えるページを想像してみてください。あなたのサイトに関する(静的な)ヘルプなどが良い例 です。コンテンツを持たない、あるいはコンテンツに依存しない、あるいはログインの状態によって変更のないようなものが該当します。ここでsite- helpというページテンプレートを考えてみましょう。

このページをキャッシュすることをCacheFuに教えるためには、あなたはこれを HTTPCacheというキャッシュマネージャに関連づける必要があります。そのためにsite-helpテンプレートにいって、Cacheタブから HTTPCacheに関連づけることになります。

これまでZopeでこのことをするためには、Acclerated HTTPCache ManagerというHTTPCacheに関連づけていたかと思います。そしてこのキャッシュマネージャはヘッダにそれ自身をセットしていました。しかし CacheFuではHTTPCacheそれ自身は特にアクションを起こしません。ただ当該オブジェクトに関して、HTTPCacheされうることをマーク づけするだけであり、だからこそ、そのページはこのルールに適合する事になるのです。

ここで実際のCacheFuの設定を見てみると、デフォルトではどのコンテントタイプも選択されていないので、すべてのタイプのコンテンツにこのルールが適用される事になっています。

いくつかのオプションもありますが、ここでは特に使われていません。

anonymous に対するヘッダと認証ユーザに対するヘッダは、ルールに対する最初の成果となります。このルールに適合したコンテンツは、デフォルトで anonymous、認証ユーザ両方に対して24時間ブラウザにキャッシュします。もし1時間だけこれをキャッシュしたいならば、ドロップダウンメニュー から「cache-in-browser-for-1-hour」を選びます。もしここにない選択肢(例えば10分だけキャッシュさせるなど)を使いたい ならば、ヘッダセットタブでその選択肢を作る事もできます。

最後にある「Last-Modified Expression」は、そのコンテンツがいつ更新されたのかを決定するために使われる表現です。

Content

このルールは、(フォルダでもイメージでもない、例えばニュースアイテムのような)ふつうのコンテンツのキャッシュに使われます。

デフォルトではPloneのふつうのコンテンツがこのルールによってキャッシュされます。これを他のキャッシュマネージャに関連づけることは特に必要ありません。

このルールにマッチさせるコンテンツは「Content Types」で選ばれています。ここで選ばれているのはファイルやイメージ、フォルダではないコンテンツタイプです。

もちろんニュースアイテム「そのもの」をキャッシュしたいわけではないでしょう。むしろここでは、そのニュースアイテムのHTMLとしてのビュー(View)をキャッシュしたいわけです。

デ フォルトビューがチェックされたとき、このルールは、リクエストがスキンオブジェクト(ページテンプレートやPythonスクリプトなど)に対して送られ てきたときに適用されます。なので例えばこのルールは「http://news-items/project-a」と「http://newsitems /project-a/newsitem_view」に適合します(newsitem_viewはニュースアイテムのデフォルトビューなので)。しかし一 方で「http://news-items/project-a/special_newsitem_view」には適合しません。

「special_newsitem_view」のような特別なビューをキャッシュさせたい場合は、「Templates」フィールドにそのIDを追加します。

「Cache Templates」は、このルールにマッチするテンプレートだけでなく、テンプレートの結果もキャッシュすることを意味します。これはたとえプロクシキャッシュがなくてもCacheFuがメモリキャッシュを利用するのに役立ちます。

「http://news-item/project-a」と「http://news-item/project-a?form_var=1」は異なるリクエストであり、これは別々にキャッシュされるということに注意してください。

「Cache Preventing Request Values」はこのようなフォームの変数などを特定するのに利用されます。これが存在した場合は、そのリクエストはキャッシュされません。デフォルトで は「portal_status_message」がここにリストされています。「portal_status_message」はふつうフィードバック メッセージのために使われるもので、デフォルトではオレンジ色で表示されます。一つのページテンプレートはいくつものフィードバックメッセージ(変更が保 存されました、とか、コンテンツが追加されました、などなど)で表示されるので、それぞれのコピーをキャッシュしておくのは非常にディスク容量を浪費し、 訳にもたちません。そのためCacheFuはこういったメッセージが存在するときにはそのページはキャッシュしません。

「Predicate」 を使えばさらにTALES表現によってチェックする事が可能です。すなわちリクエストは、「Content Typesで選択されている」「デフォルトビューである、あるいは明示的に選択されたテンプレートである」「portal_status_message を含まない」、そして「この表現をパスする」ことによって、ルールが適用されるのです。

デフォルトでは「Header Set for Anonymous Users」は(Squidなどの)プロクシキャッシュに1h保存されるように、また認証ユーザに対してはETagによってキャッシュするようにセットさ れています(Header Set for Authenticated Users)。ETagは変更があったときに最新情報を送るようにするためのメカニズムです。

ETagについて

ETagはウェブサーバとブラウザの間でやりとりされる付加情報を扱うメカニズムです。この付加情報はたとえば、リクエストしたユーザの種類や最終更新日などです。

なのでたとえば「http://news-items/project-a」をリクエストしたとき、サーバは「ETag: joelburton-2006/12/25-en」というようなETagを含めた応答をします。

こ のETagは「このリクエストはJoel Burtonに対するもので、このコンテンツは2006年のクリスマスに更新され、英語で記述されている」ということを意味しています。キャッシュプログ ラムはコンテンツとともにこのETagも保存するでしょう(このETagは正確なフォーマットではありませんが、概念としては正しいものです)。

こ こでブラウザがこのページをもう一度リクエストしたとき、古いETagもZopeに送ります。Zopeはその時点で生成されたETagと古いETagを比 較し、同じであるならば「何も変更はないよ。キャッシュを使ってね」というHTTPレスポンスを返します。もちろん違っていれば新しいページを返します。

た とえば「ログアウトした」Joelが再び「http://news-items/project-a」を訪れたとき、まず彼のブラウザはZopeに対して 最後に訪れたときのETag(joelburton-2006/12/25-en)を手渡します。一方Zopeは(Joelは今ログアウトしているので) 「anonymous-2006/12/25-en」というETagを生成します。これは以前とは異なっているETagであり、誰だかわからない anonymousユーザにはJoelとは違ったページが必要なので、コンテンツそのものを返す事になります。

SquidはETagを扱えないので、この種のリクエストはSquidをスルーします。

「ETag Components」では、どんなものを付加情報としてETagに含めるかと言うことを選びます。ここで選択したものに変化があった場合は、ETagに変更が加えられ、その結果ページは最新のものが利用されます。

デフォルトの設定はまともですが、少し注意が必要です。もしそのページや現在のスキン、圧縮されているかどうか、あるいはカタログが最後に変更された時間をリクエストしたユーザに変化があった場合は、再生成されることになります。

こ こでリストされているものは興味深い例になります。もしあなたが新しいアイテムを編集したときには、もちろんCacheFuには古いアイテムを返して欲し くはありません。そしてたとえばそのニュースを含んでいるフォルダのタイトルを変えた場合も、古い見え方を返しては欲しくないですよね。なぜならそのフォ ルダのタイトルは、ナビゲーションやパンくずリストなんかに現れるからです。それが古いままでは困ってしまいます。

ETagに、カタログの 最終更新日を含めると、どんなオブジェクトのどんな変化であってもCacheFuのページ再生成を引き起こしてしまいます。このことは最新のナビゲーショ ンを保証してくれますが、ちょっとばかり古くても良いような部分でこのようなことが起こるのはちょっともったいないです。

が、このETagはログインしたユーザのためのものです。anonymousユーザに対しては(ETagにかかわらず)プロクシサーバに1時間保存されます。ですからすべての変更がキャッシュに無効になるわけではありません。

も しあなたが最新状態にこだわらず、もうちょっとパフォーマンスをよくしたいとおもうならば、「Time of last catalog change」を「Context modification time」に変えてみるのも良いでしょう。これは、すべての変更がすべてのETagを無効にするわけでもないが、古いタイトルなどが表示されてしまうかも しれないということも意味しています。これはパフォーマンスをよくしますし、一度検討してみることをおすすめします。

ETagを選択肢から 選ぶのもよいですが、リクエスト変数をETagに明示することもできます。デフォルトでは「month」「year」「orig_query」変数がリス トアップされています。これはカレンダーポートレットのための設定です。コンテンツに何も変更を加えなかったとしても、カレンダーポートレットで 「next-month」ボタンを押したユーザには、コンテンツは同じでもポートレットだけは次の月のものを表示するのです。

もしここに他のフォーム変数を追加すれば、そのページのキャッシュのされたかは違ってくるでしょう。

た だ前述した「Cache Preveting Request Values」(「portal_status_message」のところで述べました)との違いに注意してください。cache- preventing-valuesは「もしこの変数があったら、ルールを適用しないでね!」という(のでキャッシングヘッダは送られない)のに対して、 「ETag request values」は「もしこの変数があったら、キャッシュできるけど別のリクエストとみなしちゃうよ!」というわけです。

「ETag Timeout」は安全のための設定です。これはETagが持続する時間で、デフォルトでは3600秒です。これはもしETagの比較によって何の変化が ないと判断されたページであっても、ETagの生成から3600秒経過していたら、とにかく新しいページを生成するということです。

「ETag Exprssion」は追加的なETagの値を記述するためのものです。

「Purge Expression」はSquidのコンテンツを消去するためのスクリプトを記述するためのものです。とりあえず編集しなくてもOKです。

Container

このルールはフォルダ風コンテンツタイプ(フォルダとPloneラージフォルダ)に使うもので、Contentルールに似ています。

違 いは、Contentルールがanonymousユーザに対してはオブジェクトが変更されるまでキャッシュするのに対し、このルールはより長い時間キャッ シュするということです。フォルダは多くの場合それが含むオブジェクトのリストを返すだけなので、このフォルダの見栄えを最新のものにする必要があるの は、新しいドキュメントが追加されたときやそのフォルダに含まれるドキュメントが変更されたときです。

しかしフォルダに含まれるオブジェクトが変 更したかどうかはとても知るのが難しいことです。そこでCacheFuはもう少し手軽で一般的なものをチェックします。全体のカタログの中で変更されたも のはないか?ということです。カタログの中で変更されたものがあればフォルダ風オブジェクトは再生成されることになります。

このためフォルダ風オ ブジェクトはSquidやApacheにキャッシュされることは決してなく、ZopeでContentのETagと同じようにキャッシュされます。つまり anonymousユーザに対しても、ログインユーザに対しても、Contentルールのログインユーザに対するように振る舞うことになります。

Templates

このルールは、コンテンツやフォームを含まないページテンプレートのようなスキンオブジェクトに使われます。この良い例はアクセシビリティ情報です。これはコンテンツでもフォームでもありません。しかし変更があるまではキャッシュすることができます。

「templates」フィールドにはこのルールにマッチさせるテンプレートを記述します。新しいテンプレートを追加したときもここに追加することができます。

これらは上記のコンテンツやフォルダ風オブジェクトと同じようにETagによってキャッシュされます。

フォ ルダ風オブジェクトのルールと同じように、このキャッシュはカタログに変更があった場合にクリアされます。ほとんどのテンプレートは main_templateに依存しており、またこのmain_tamplateも他のテンプレートに依存しているので、これらの依存状況を追跡するのは 非常に難しいことです。よってZopeの中でのどんな変化も、このテンプレートが何を表示するか、クリアするかといったことに影響を与えるようになってい ます。

これは非常に安全です。もしかしたら、anonymousユーザのためにこれらのテンプレートをプロクシサーバに1時間以上(あるいは24 時間以上、あるいはもっと長い時間)キャッシュさせたい人がいるかもしれません。テンプレートそのものの変更、あるいはmain_templateなど、 その他テンプレートの変更は表に現れませんが、この種の変更はほとんどレアですし、もし変更があったとしてもサイト管理者はプロクシキャッシュをクリアす るためにプロクシサーバを再起動することもできます。

なぜフォームは除くのか?

それじゃあフォームはなぜTemplateルールでキャッシュされないのでしょう?

Ploneでのフォームは、フォームを見せるだ けでなく、エラーメッセージを表示するためにも使われます。これをキャッシュしてしまうと、フォームを入力しようとするユーザに対してエラーメッセージを 表示してしまったり、すでに入力されたものを表示してしまったりしまいます。