2006年08月01日
負荷分散環境でブラウザキャッシュが効かないときは - ETagの解説 -
ETag とはなんぞやというと、Apache が返すレスポンスヘッダのひとつで、
オブジェクトに付与される属性です。
で、何に使うかというと、ブラウザのキャッシュ管理に使われます。
一度、http://example.jp/index.html にアクセスした後でもう一度(リロードとかで) アクセスすると、ブラウザは最初のリクエストのときに得た ETag の値を覚えておいて、
というリクエストをサーバに投げます。
このリクエストを受け取ったサーバは、要求されたオブジェクトの ETag を調べて、"3b-60273fc0" なら 304 Not Modified を返します。んで、304 を受け取ったブラウザは自分のキャッシュの中にあるデータを表示するわけです。
304 の場合はオブジェクトそのもののデータはやり取りされないので、速く表示できるわけですね。
で、この ETag なんですが、サーバはどうやってこの属性値を決めるかというと、Apache のデフォルトでは
を基に生成しています。なので、ファイルが変更された場合は、ETag が変わるのでちゃんと変更後のデータが返されるわけです。
が、実はこれでは分散環境でうまく動かないんです。
分散環境下の各 Web サーバで、最終更新時刻とサイズを同一にすることはできるのですが、iノード番号まで揃えるのは現実的に不可能です。
なので、デフォルトの設定では、オブジェクトは同じであるにも関わらず、分散された実サーバが違うと (iノードの値が異なるため) ETag の値も異なるので、304 でなくレスポンスコード 200 と共に、オブジェクトのデータが返されてしまいます。
これを回避するには、Apache の設定で、
とすればよいです。こうすると、iノード番号を使わずに ETag の値を生成するので、分散環境で実サーバが異なっても、ETag が同じになるわけです。
ちなみに、この場合、ETag の値は一意な ID としては使えません。iノード番号も生成に含める場合は別ですが、最終更新時刻とサイズだけだと、オブジェクトが異なってもこの2つのファイル属性が同じならば ETag の値も同じなるからです。
HTTP/1.1 200 OK
Date: Mon, 24 Jul 2006 06:18:07 GMT
Server: Apache
Last-Modified: Wed, 13 Apr 2005 21:48:55 GMT
ETag: "3b-60273fc0" ←これ★
Accept-Ranges: bytes
Content-Length: 59
Connection: close
Content-Type: text/html
オブジェクトに付与される属性です。
で、何に使うかというと、ブラウザのキャッシュ管理に使われます。
一度、http://example.jp/index.html にアクセスした後でもう一度(リロードとかで) アクセスすると、ブラウザは最初のリクエストのときに得た ETag の値を覚えておいて、
If-None-Match: "3b-60273fc0"
というリクエストをサーバに投げます。
このリクエストを受け取ったサーバは、要求されたオブジェクトの ETag を調べて、"3b-60273fc0" なら 304 Not Modified を返します。んで、304 を受け取ったブラウザは自分のキャッシュの中にあるデータを表示するわけです。
304 の場合はオブジェクトそのもののデータはやり取りされないので、速く表示できるわけですね。
で、この ETag なんですが、サーバはどうやってこの属性値を決めるかというと、Apache のデフォルトでは
- iノード番号
- 最終更新時刻
- サイズ
を基に生成しています。なので、ファイルが変更された場合は、ETag が変わるのでちゃんと変更後のデータが返されるわけです。
が、実はこれでは分散環境でうまく動かないんです。
分散環境下の各 Web サーバで、最終更新時刻とサイズを同一にすることはできるのですが、iノード番号まで揃えるのは現実的に不可能です。
なので、デフォルトの設定では、オブジェクトは同じであるにも関わらず、分散された実サーバが違うと (iノードの値が異なるため) ETag の値も異なるので、304 でなくレスポンスコード 200 と共に、オブジェクトのデータが返されてしまいます。
これを回避するには、Apache の設定で、
FileETag MTime Size
とすればよいです。こうすると、iノード番号を使わずに ETag の値を生成するので、分散環境で実サーバが異なっても、ETag が同じになるわけです。
ちなみに、この場合、ETag の値は一意な ID としては使えません。iノード番号も生成に含める場合は別ですが、最終更新時刻とサイズだけだと、オブジェクトが異なってもこの2つのファイル属性が同じならば ETag の値も同じなるからです。
トラックバックURL
この記事へのトラックバック
1. クラウド環境でのApacheの設定 [ cloudrop ] 2009年09月12日 18:42
クラウドのホスティングサービスは、一定リソースの時間極課金+通信トラフィックの従量課金が一般的です。
CPUやメモリなどのリソースは、1%しか使わなくても100%使っても時間内の料金は同じです。
一方で通信料は使った分だけGB単位などで段階的に課金される仕組みです。
...
2. クラウド環境でのApacheの設定 [ cloudrop ] 2009年09月12日 18:42
クラウドのホスティングサービスは、一定リソースの時間極課金+通信トラフィックの従量課金が一般的です。
CPUやメモリなどのリソースは、1%しか使わなくても100%使っても時間内の料...
この記事へのコメント
1. Posted by bull 2006年08月17日 22:42
ファイルの絶対パスを使ってETagの値を作れれば,パスさえ揃えれば複数サーバで同一ETagが作れそうですね。という要求をここで愚痴っていても仕方ないので,Apacheの開発者MLに投げないといけないんでしょうな。