2008-02-26

ETagについて

はてなブックマーク   livedoor clip

今回は ETag(Entity Tag) の話題です。サーバの構成をいろいろと考えていて気になり始めた技術の一つです。

ETag の詳細な説明は省きますが、HTTP/1.1 で定義されているヘッダで、キャッシュコントロールに使われます。

Apache の実装ではデフォルトで ETag はファイルサイズ、最終更新日時、inode 番号の3つから計算されるのですが、これが分散環境ではキャッシュの効かない原因になります。(同じ内容ファイルでも別のサーバ上にある場合には inode 番号が同じになることはほぼあり得ないため、負荷分散の都合で別サーバに割り当てられた場合、ETagも変わってしまう。)サーバの分散をするに当たってどんな問題があるかを調べていてみつけました。これを回避するためには、Apache 2.0 以降では FileETag ディレクティブの設定で ETag に inode 番号を含めず、ファイルサイズと最終更新日時だけから計算されるようにすればいいのですが、inode 番号を設定しない場合に問題になることはあるのでしょうか?

そもそも 最終更新時刻もファイルサイズも変わらずに inode 番号だけが変わることってあるのでしょうか?
inode 番号だけが変わるってことはファイルを移動したとかでしょうか? 普通にmvしても変わらないですよね。cp -a してコピー元を rm すれば変わりますね。でも移動しても内容が変わっていなければクライアント側には同じファイルと認識されてかまわないですよね。特に問題ないような気がしてきました。

もし「こんな問題がある」ってわかる人はぜひ教えてください。

ところで、Google 先生に聞いてみると「正しく LastModified が設定されているなら ETag なんてとってしまえ」という意見も散見されますが、それだと一秒以内の更新のときに対応できないですね。ファイルサイズと更新時刻からなる ETag をつけていても、一秒以内でしかもファイルサイズの変わらない更新(追加や削除のない文字の訂正とか)だと対応できないので、ETagをつければ問題がなくなるというわけではないですが。

これに関しても、 何か意見や情報がある人は教えてください。私はサーバ側ではいろいろなキャッシュコントロールのやり方をサポートして、クライアントに好きなやり方を選ばせるのがいいんじゃないかなと思います。まだサーバ側の負荷で困った経験もないので理想論に過ぎないかもしれませんが。

ここでちょっと話は変わって、Rails での ETag の話です。

上のようなことを気にしながら Rails 2.0.2 で開発中のアプリをこねくり回していて気づいたんですが、Rails では ETag を勝手につけてくれるらしいです。どうやって計算しているのでしょう? 以前も付いてたのでしょうか?

以下応答の抜粋です。

GET /search?q=xxx HTTP/1.1
Host: localhost:3000
If-None-Match: "3f79be44e27fc7dc248258b4f4fca3a9"
HTTP/1.x 304 Not Modified
Etag: "3f79be44e27fc7dc248258b4f4fca3a9"
Server: Mongrel 1.1.3

で、調べてみたところ、答えは response body 全体の MD5 ハッシュでした。
/usr/lib/ruby/gems/1.8/gems/actionpack-2.0.2/lib/action_controller/response.rbの中に以下の部分を見つけました。

def handle_conditional_get!
  if body.is_a?(String) && (headers['Status'] ? headers['Status'][0..2] == '200' : true)  && !body.empty?
    self.headers['ETag'] ||= %("#{Digest::MD5.hexdigest(body)}")
    self.headers['Cache-Control'] = 'private, max-age=0, must-revalidate' if headers['Cache-Control'] == DEFAULT_HEADERS['Cache-Control']
    if request.headers['HTTP_IF_NONE_MATCH'] == headers['ETag']
      self.headers['Status'] = '304 Not Modified'
      self.body = ''
    end
  end
end

ネットワークとCPUのどちらのリソースが先に逼迫してくるかで、とりあえずは「ネットワークが先」という判断になっているんですね。ちなみに actionpack-1.13.6 にはこれはなかったので、Rails 2.0 以降の機能のようです。

2008-02-18

AtomPub Interop 2008 in Tokyo に参加してきました。

はてなブックマーク   livedoor clip

前回に引き続き、今月(2008/2)の12日午後に行われた AtomPub の Interop に参加してきました。
今回は全部で 6 社から 13 名が参加していましたが、リコーからは 5名、リコーソフトウエアからも 1 名参加していたので、非常にリコー率が高くなってしまいました。yoheiさんに影響されて社内でも AtomPub への関心が高まっていますね。

今回もホスト役をしていただいたNTTコミュニケーションズの朝倉さん、坂野さん、ありがとうございました。

事業部から参加した二人と私は前回と同じく Java ME のサーバとクライアントを持って参加したのですが、yohei さんは curl(一般的なコマンドラインのHTTPクライアント)で、研究所から参加したもう一人はその場で perl のクライアントを書いていました。参加の目的は相互接続試験というよりも、AtomPub 周辺の議論をするためだったようですね。ちなみにリコーソフトウエアの方は Ruby on Rails のサーバを持ってきていました。

私は私用で最後までいられなかったのですが、参加者の皆さんそれぞれバグが発見されたり、仕様で明確に決まっていない部分の議論ができたりと有意義に過ごされたようです。

最後になってしまいましたが、補足しておくと Interop とは Interoperability test、つまり相互接続試験のことです。AtomPub のように通信系の仕様の場合、その実装同士が通信できないとお話にならないので、各社が開発中の製品などを持ち寄ってお互いに通信できるかどうかのテストをしたり、できない場合にその場でバグを修正したりします。AtomPub の場合は通信相手はお互いに PC の場合が多いので今回の Interop も皆さんノート PC を持ち寄っていましたが、bluetooth などの Interop ではデジタルカメラや携帯電話などを持ってくることも多いので、発売前の製品は布などで隠した状態のまま確認したりすることもあるようです。

2008-02-13

RESTとリソース指向アーキテクチャについての資料

はてなブックマーク   livedoor clip

2/12 に NTT コミュニケーションズ様の社内勉強会にて、REST に関する講演をさせていただきました。NTTコミュニケーションズ様の了解をいただいたので、その資料を公開します。

rest_and_roa.png

REST を具現化するアーキテクチャとして、「RESTful Web サービス」で提案されているリソース指向アーキテクチャ(Resource Oriented Architecture; ROA) をご紹介しました。

2008-02-01

「RESTful Web サービス」プレゼント当選者発表

はてなブックマーク   livedoor clip

Tシャツプレゼント企画にたくさんのご応募をいただき、ありがとうございました。幸い、定員以上の応募がなかったため、応募者全員の方にプレゼントをすることができます。当選者は以下の4名の方です。

お手数ですが、当選者の方はお問合わせフォームより送付先の登録をお願いします。必要なのは以下の項目です。

  • お名前
  • メールアドレス
  • 電話番号
  • 送付先住所(お問い合わせ内容の欄にご記入ください)