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-01-28

RFC 5023 翻訳公開の裏話

はてなブックマーク   livedoor clip

はじめまして、ソフトウェア研究開発本部の日野原寛です。普段は Web アプリの開発やサーバ環境の構築などをしています。この blog のサーバも私が設定しましたが、最近のOSはデフォルトが厳しい方向に振ってあるので設定が楽ですね。

本当はそういった方面の話題を書きたいのですが、今やっている作業がひと段落して公開されてからでないと書きにくいことも多いというのと、周りの「早く何か書け」というプレッシャーがだんだん強まってきたという理由から、まずは以前公開した RFC の日本語訳のことについて書きたいと思います。

Atom Publishing Protocolは2007年10月9日に RFC になりRFC 5023の番号が付きましたが、私たちはその3日後の12日に日本語訳を公開することができました。

もちろんたった3日で全部を訳したわけではなく、事前に Draft-17 の日本語訳を準備していたのですが、実際に翻訳を開始したのは6月末の Draft-15 からでした。そのときにはこのままRFCになるだろうと思っていたのですが、7月に入ってから Draft-16、17と立て続けに出てしまったのにはびっくりしました…

翻訳を開始するにあたっては社内の Web 技術者向け blog で協力者を募集したのですが、あっという間に8人も集まってくれました。内訳は研究所から5人、事業部から2人、グループ会社から1人です。

翻訳自体は Wiki 上で早い者勝ちで行いました。
まずはまとめページを作って基本的な訳語などを共有しつつ、手のあいている人や現実逃避したい人が順次章毎に訳したページを作っていくという形式です。その結果やたらと yohei の担当分が多くなったのですが、当時よっぽど現実逃避したかったのでしょうか… いえ、きっとAtomPubにかける情熱がほかのメンバーよりもはるかに強かったんですね(・∀・)

7月の前半にはほぼ全ての翻訳作業が終わり、各自 Draft-17 に追従したところで RFC になるのをじりじりと待っていたのですが、その間に概要や謝辞を訳したり、html に整形しなおしたりもしました。

そして 10/9 に RFC が公開されると、まずはリコーのルールに従って社外公開のための申請書を作成し、Draft-17 と RFC の差分の翻訳への適用の作業も始めました。このときは主にIRCで情報を交換していました。
修正は午後一から始めて 15:00 頃には終わったのですが、申請が通るまでにはまだ時間があったので、この間に html のスタイルなどの微調整やコードのシンタックスハイライティングもしました(Text::Hatena を使わせていただきました)。
その作業も 18:00 頃には終わり、後は申請の承認待ちです。「他の誰かが翻訳を公開してしまうのではないか」とハラハラしながら待ち…待ちで 10/12 です。
大企業のつらいところです。
代わりに、本来ならば Web ページの公開は夜間のバッチ処理なので一晩かかるのですが、担当者にかなりの無理を言ってその日のうちに公開してもらいました。

当時この blog があればもっと迅速に公開できたのに、惜しいところです。(従来の情報公開の申請ルールは論文などを対象として作られたものなので、Web のようなメディアのスピード感には対応できていませんでした。それに対してこの blog の記事のチェック体制は従来に比べてスピーディに公開できるようにしてもらっています。)

最後はちょっと愚痴っぽくなってしまいましたが、以上が翻訳公開の裏話です。

ちなみにはてなブックマークではありがたいことに原文の 6 件(プレーンテキスト版html版をあわせて)を大きく引き離して 147 件ものブックマークをしていただいています(件数はともに本記事の公開時点)。ありがとうございます。今後はこういった情報公開もこの blog 上で行っていきますので、これからもよろしくお願いしますm(_ _)m