taro-nishinoの日記: 私がCouchDBを使わない理由
私は家ではMongoDBを使用しています。では、何故RDBMS(種類は何でもいいですが)でないかと言いますと、家の外へ一歩でも出れば、やれORMがどうのこうの、スキーマがどうのこうの、SQLがどうのこうの、と日夜囲まれているのに、そんなもん家に入れたくないでしょう?
MongoDBはインタラクティブシェルとしてjavascriptシェルを持っているので、JSONでデータを格納出来ますし、今ややっとPerlドライバであるMnogoDB(元々は、ご存知Florian Ragwitz氏が手掛けられ、今のメンテナはKristina Chodorow女史です)が安定して来ましたので、Devel::REPLを使用すれば、Perlのハッシュのままインタラクティブに格納出来ます。私の個人的な記録はすべてMongoDBに放り込んでいます。卓上メモ代わりのようなもんです。
これを言うと必ず「じゃ、CouchDBはどう?」と、さも親切気に言う人がいます。私の身辺にもいました。勿論、とっくにCouchDBも調査済みです。公式サイトにあるドキュメントは全部目を通しましたが、すべていいことだらけなんです。普通はいいことが多いけれども、こういう制限事項があるとか、短所はこうだとか、ベンチマークはこうだとか、何らか具体的記述があってもいいのに、一般論的記述に終始していましたので、逆に胡散臭いものを感じました。エンジニアリングはトレードオフ、妥協の産物です。すべて最高のシステムなぞ有り得ないのです。ですから、選択肢から外しました。CouchDBを勧めてくれた知人には、CouchDBのロゴよりMongoDBロゴの方が恰好いいのが理由だと言いました。真剣に技術論争が好きな輩がいますが、時間の無駄です。
とは言っても、私と同じような感触を受けた人はいないのだろうかと考え、見つけたのがYuval Kogman氏の″Why I don't use CouchDB″です。これはエッセイと呼ぶよりは論文に近い重厚さがあります。勿論、下辺にいるような私の感触より遥に具体的に踏み込んでいます。以下、その私訳を載せておきます。
追記: 11月17日
この記事とは本質的に関係ないのですが、知人より問合せがありましたので、補足しておきます。
PerlドライバであるMongoDBは、MnogoDB本体のバージョンが1.1.3以上でないと、テストがこけます。
また、UTF-8の取扱いについては、CPAN Annotatedで、私が注釈を加えていますので、参考の程を。
私がCouchDBを使わない理由
2009年5月15日 Yuval Kogman
CouchDBは非常に面白い。CouchDBXパッケージを使ってmacにインストールするのは実に簡単だ。ナイスなウェブUIとともに手に入り、すぐに楽しめる。事実上どの言語からも使用出来る簡単なAPIを与えるために、RESTとJSONを使っている。素晴らしいトランザクションモデルを含んでいて、とても手軽に完全なACIDセマンティックスを持たせる。それなのに、何故私は使わないのか? まぁ、幾つかの理由がある。'tubesで聞いたことのあるありふれた中傷は省略する。さぁ、始めよう...
ビュー
CouchDBのビューの概念は実のところ洗練されている。データベースにあるドキュメントをマップする純粋な機能である。これはjavascriptを使って、好きなようにデータを処理出来ることを意味するが、CouchDBはデータの新鮮性、及びその結果が効率的なクエリと更新を与えるように、安全なキャッシュとインデックスを想定してよい(少なくとも理論上は)。
残念ながら、オリジナルのデータからのビューだけを作れる。他のビューが入力となるビューを作る方法はない。これが意味することは、多重ドキュメントからの値に面白いことは何も出来ないということだ。縮小機能を使って、多くのドキュメントからのデータをバケツの中に集約出来るが、そのデータを更に加工は出来ない。
これは、SQLクエリの同様の限界(再帰的でないので、推移関係を記述出来ないという事実)を我慢せざるを得ないことを意味するが、独自のクエリを書くこと及び、それを効率良く実行させることの自由を持たない(独自ビューはサポートされるが、汎用インデックスは無い)。
縮小機能は、これをいくらか緩和するが、少し急場しのぎであると私は個人的に感じる(縮小は実のところマップの特別なケースに過ぎない。すなわち、マップはデータを取り、キーを使ってデータをバケツに出力する。データが前の過程と出力からの結果のバケツであるマップが縮小なのである)。
概要は、CouchDBがGoogleのMapReduceフレームワークを含むことを仄めかしているが、「実際」のMapReduceは、CouchDBの実装よりずっと柔軟である。
レプリケーション
レプリケーション・サブシステムも非道く誇大宣伝されているが、実際どう動くのかについて詳細を見つけるのは困難だ。私の理解は、互いに競合するバージョンがストレージ内に保持されているということであるが、これらの内の一つが「勝利」し、ドキュメントのデフォルトバージョンとなる。CouchDB technical overviewで、これは以下のように合理化している。
CouchDBストレージシステムは、編集競合を例外としてではなく、共通の状態として取扱う。
私の理解が正しければ、競合はエラーではないのだから、明示的に競合を探求しなくても、「勝利者」に作業出来る。ユーザーの観点から、アプリケーションが競合に防御的ではないが、ユーザーがレプリケーションと共に競合を選ぶならば、明らかにデータ損失(データがまだそこにあるが、アプリケーション内でビュー化されない)と矛盾(二つの異なるドキュメントの「勝利者」が、実際のデータに競合が無いのにデータベースの状態について競合する想定を持つならば。しかし、完全にシリアライズされるトランザクションが使用されるならば、これは問題にならないかも知れない)に繋がるだろう。
要するに、私を懐疑的にしている。レプリケーション・サブシステムは分散アプリケーションの構築に便利な足掛かりであろうが、それにはまだ多大な苦心がある。
すぐに使えるレプリケーションのサポートは、デベロッパーとしてラップトップにデータセットを取込むのに便利であり、後で変更をプッシュ出来る。スケーラビリティとクラスタリングについてのクレームに対する反駁出来ない根拠を、私は見ていない。
私にとって、これはニッチなフィーチャーであり、殆どのアプリケーションにとっては実際は存在意義が無い。しかし、多大な努力が投資された結果である。私が全く気にしないフィーチャーの存在は、私が使うべきでないことを意味しない。だが、大変な開発途上にあるプロジェクトとしては、もっと重要なフィーチャーを犠牲している。
遅延時間
私の記憶が正しければ、CouchDBは普通のハードウェア上で1秒間につき2000を超えるHTTPリクエストをサポートするが、これは同時並行する沢山の馬鹿なクライアントを多く抱えるなら最適である一方で、殆どのウェブアプケーションの規模はかなり異なる(一握りのサーバサイドであって、数千ではない)。
ノンブロッキングなクライアントを使っていても、ソケット生成、接続、データへのリクエストとそれを待つ遅延時間は大変大きい。KiokuDBのベンチマークでは、CouchDBは断然に遅いバックエンドであって、良くてもプレーンなファイルをバックエンドにした場合の約2、3倍と同等であり、もっと標準なバックエンド(Berkeley DB, DBI)では数十倍差がある。これは私にとって、Berkeley DBバックエンドのKiokuDBを使う時、数千オブジェクトをフェッチするようなリクエストについて何も考慮する必要が無いことを意味するが、そのリクエストが半秒ではなく五秒ならアプリケーションは使用不可能になる。線形スキーマ無しで動く喜びの一部分は、ツリーとグラフをトラバースしてもっと面白いことが出来るということだ。だが、パフォーマンスは許容範囲でなければならない。リクエストすべてがそんなに多くのオブジェクトをフェッチしないが、そうであってもCouchDBをするには限界がある。
データに従属物を持たせる、すなわち、他のドキュメント内に見つかったデータに基づいてフェッチするのであれば、直ぐにボトルネックとなり得る。大量フェッチングと多段階ビューがサポートされるのであれば、与えられたドキュメントに関連するデータすべてを含む推移的閉包を与えるビューは、単純にグラフトラバーサルをサーバサイドへ移行することにより実装されるだろう。
スループット計測時、CouchDBが完璧に実行するとしても、遅延時間の軽減するパフォーマンスを得ることはかなり難しい。HTTPとJSONを使うことによって得られた簡明性が、イベントベースまたはスレッドベースのクライアント内でノンブロッキングIO使用の困難さによって、見劣りさせる。
公平を期するために、問題の大部分がおそらくAnyEvent::CouchDBのためでもある。KiokuDBのオブジェクト・リンカーはエントリーの大量フェッチングをサポートしていて、これが、少し大きなデータセット移行を必要とするOLTPアプリケーションで許容されるパフォーマンスを作る可能性を持つであろう。
認証と権限付与が無い
権限付与サポートはウェブアプリケーションに大きなパフォーマンスの違いを作るであろう。アクセスを制限するメカニズムが正しく配置されるなら、ボトルネックとしてのサーバサイドのコードを削除して、CouchDBバックエンドは直接ブラウザに露出されるであろう。
サーバサイドが、制限されたドキュメントセットのみにビュー(たぶん編集も)を許す信頼出来るトークンをユーザーに与えられたらいいのだが。柔軟な権限付与フレームワークを創るためにビュー・サブシステムには多くの可能性がある。
これは、完全な信頼出来るサンドボックスの必要性が無くてもCouchDBを、ピュアなjavascriptアプリケーションを書くためのシリアスなプラットホームにするであろう。CouchDBとスタティックなファイルだけが必要なら、アプリケーションの配置は朝飯前である。
LDAP認証はロードマップに載っているが、認証と権限付与は実は別々のフィーチャーであり、柔軟なアクセスコントロールに向けての動きはまだ無いようである。
明らかな開発焦点の不足
私は実際にコードを寄与していないのだから、文句を言う資格が無いと思う。しかし、欠落している重要なフィーチャー(または、少なくとも私が重要だと思うフィーチャー)を追加することの代わりに、既存のものを改善することにチームの焦点があったように私は思える。これは、私の提起した問題の解決について、私を悲観的にする。
私が最後にIRCチャネルにいた時、ディスクB-木フォーマットの2回目の書き直しについて議論があった。個人的に私は先ずフィーチャーの完備を見たいと思う。ディスクフォーマットの書き直しは、おそらく現状より大幅なパフォーマンスの改善にはならないだろうし、例えばAPIが完結するまで、副次的な最適化を残すことは大いに許容されると思う。書き直し前のバージョンを私が使った時は、CouchDBのパフォーマンスは完全に許容されるものだった。従って、特に野心的なロードマップを持っているのに、実践的考えと優先順位の不足を私は感じる。
代替
「ドキュメント指向ストレージ」のため、SQLiteと残念ながらMySQLと同様に、非常に優秀なBerkeley DBを使い続けており、これらすべてが非常に上手く動いている。持続性のサポートは至る所にあり、CouchDBと違って、APIは安定し完備している。
他の調べる価値のあるものはMongoDB(残念ながらトランザクションが無い)、key/valueペアデータベース(これらの多くが最近配布されている)、RDFトリプルストア、XMLデータベースである。
私が重視していない代替は、Amazon SimpleDBだ。Amazon SimpleDBはCouchDBの持つ問題全部を陳列しているが、しかもデータ一貫性の完全な欠損があり、ずっと更に複雑なAPIである。非常に特別なデータ使用用途(OLTPでなく、読込み)を伴う大規模容量を必要としないなら、Amazon SimpleDBは本当に適していない。
スキーマの無いデータストレージを調べる時に留意すべき最も重要なことは、「貴方はGoogleでない」というスケーリングの公理であると思う。人は、スケールするための成功した製品を持つこと無しに、スケーラビリティについて極端な関心を持っているようだ。上で述べた技術すべてが、データサイズとデータアクセスレートの両方の観点から長い道のり歩むだろう。そして、データ格納にナビゲート的アプローチを使うことにより、シェアディングが非常に簡単に追加されるだろう。
ともかくも、CouchDBが最終的には、私が突っ込みしている事と違うものへ成熟することを願うばかりである。現時点においては、抽象的概念の格納と参照が適切に配備されるなら、他製品以上に私に使用を無理強いするものは無い。だが、それは約束の多くを果たすことだ。
私がCouchDBを使わない理由 More ログイン