真にスケーラブルなWebアプリケーションを作るには?という話題で盛り上がった件
先週末は上京してRubyKaigiに参加してきました。
運よくLT枠をいただくことができたので、タイトルのようなテーマで(結構紆余曲折があって、当初の想定から逸れてしまった...)プレゼンさせてもらうことができました。
話の流れとしては、
「WebアプリケーションのボトルネックはRDB」
↓
「RDBってAmazonEC2みたいなHaaSではスケールしないよね。」
↓
「本当に(アプリのコードをそのままで)スケールさせようと思ったら、AmazonSimpleDBのようなクラウドDBを使うしかない」
↓
「SimpleDBはMySQLより一桁以上遅いから、単純にRDBをSimpleDBに置き換えると、えらいことになる」
↓
「SimpleDBへのアクセスを極力少なくするため、リクエストはMemcachedとかでキャッシュしまくる必要があるね」
↓
「このあたりを今Lang-8で実験している。将来的にはキャッシュ機能付きSimpleDBインターフェイスをライブラリ化して公開したい」
って感じ。(使用したスライドは先日のエントリに掲載済み)
すると、スピーカとして米国から来日していたJEG2ことJames Edward Gray 2世氏が、僕の発表に関心を持ってくれたらしく、運営委員の方が紹介してくださった(かくたにさん、レオさん、ありがとうございました!)
それで、このテーマに関して彼と簡単にディスカッションしてみたのだけれど、ちょうど彼も同じことをやっている最中だったようで、しかもその中身がなんだかすごい。
Helene
まず、教えてもらったのは、彼がコミッタとして参加しているHelene(ヘリーン)というRailsのPlugin。Amazonが提供する各種クラウドプラットフォーム(SimpleDBやS3等)をRailsから簡単に使うためのPluginで、GitHubでホストされている。
http://github.com/ahoward/helene/tree/master
まだ少ししかコードを見てないけれど、これはすごい。SimpleDBを高速に活用するための様々な仕掛けが満載のようだ。
たとえば、SimpleDBでは、アイテム(レコード)の更新は各アイテムごとに一件ずつ処理するしかないのだけれど、これではRDBでおなじみのレコード横断的なUPDATEと等価な処理を行うのに非常に時間がかかる。そこでHeleneではSimpleDBへのコネクションを複数個プールしておき、複数の更新クエリを非同期かつパラレルに送信してしまう!(※追記:Plug-inなので、もちろん全てRubyで書かれている) Array#threadifyの実用例を始めて見たな〜。
さらに、なんでもSimpleDBは、アイテムの削除に非常に時間がかかり、更新処理のほうが高速らしい。そこで"deleted_at"というattributeをレコードに導入することで、アイテムの論理削除をできるようにしていたりとか。(これも当然複数アイテムに対してパラレルに実行可能)
とにかく色々と考え抜かれている。
まだ開発途上のプロジェクトみたいだけれど、Railsのクラウド対応ライブラリのデファクトスタンダードになりそうな迫力を感じた。Lang-8でも使わせてもらおうかなぁ。ただ透過キャッシュ機構は特に準備されておらず「アプリサイドで個別に対応しているよ」とのこと。僕としては参照系の性能向上に一番興味があるので、いずれにせよキャッシュ周りは自家製になりそうだ。
ちなみに、なぜHelene(ヘリーン)と名付けたか聞いたら「ギリシャ神話の登場人物で、軍団(女戦士)の中で足が速かった」とかなんとか。
Redis
次に教えてもらったのは、Redisというプロジェクト。GoogleCodeでホストされている。イタリア人の開発者が開発しているらしい。
http://code.google.com/p/redis/
これは、ただの文字列を突っ込むだけではなく、各種リスト操作が可能、かつディスクへの非同期永続化+αが可能なMemcachedのようなデーモンで、TokyoCabinetをさらに高速、高機能にしたようなもの。しかも爆速。毎秒11万クエリとか、すごい。。
公式ページによれば、
It is possible to think at Redis as a data structures server, it is not just another key-value DB, see all the commands supported by Redis to get the first feeling. Redis supports operations like atomic push and pop of elements on lists, taking ranges of elements from this lists at once, trimming of lists, server-side intersections of sets and even sorting data! To show our points we wrote a simple Twitter clone with PHP + Redis: it's a very simple but still a real world example of web application, the article explains step by step how to write scalable applications with Redis.
とか。「君のプロジェクトに向いてるかもよ?」とのアドバイスをいただく。
以下のページに紹介ビデオがあった。Redisとは何かを端的に説明してくれている。
http://mwrc2009.confreaks.com/13-mar-2009-19-24-redis-key-value-nirvana-ezra-zygmuntowicz.html
ちなみに上の動画、発表者に5分だけ与えられるLT形式で、最後に警告音が鳴り響いてプレゼンが打ち切られてた。万国共通のスタイルなんですかね、LTって :)
あと、JEG2と彼の奥さんのDanaは、二人ともかなり日本文化に興味を持っていて、現在日本語を勉強中だとか。二人ともLang-8にとても関心を持ってくれた :)