CouchDB 座談会

(2009年7月30日開催)

しおや「最近クラウド・コンピューティングが流行しているということで、どんな技術があるんだろうとみていくうちに、クラウドのプラットフォームの話、アマゾンのEC2だとかWindows Azureだとかはいっぱい出てるんですけど、それを使って書いたアプリケーションの話はあんまりないな、と。もうひとつは、私はログ管理の製品も担当しているんですが、大量のデータをログとして蓄えないといけないという時に、具体的にクラウドだったらどういうソリューションがあるのかな、と。そう思って色々見渡しているときにクラウドの処理能力を活かしたデータベースということでCouchDBに興味を持ちました。きっかけはIBMのDeveloperWorksの記事を見たことで、今少し使ってみてます」

CouchDB とは?

しおや「この図は結構いろいろ描き込んであるんですけど、CouchDBはErlangというプログラム言語で記述されたデータベースでして、ストレージエンジンとビューエンジンがこのErlangバーチャルマシンの上で稼働しています。

ストレージエンジンのほうではJSON形式のデータをどんどんたくわえていきます。JSONなので、いままでのRDBと違ってどんな構造のデータでもどんどん入れていける。フリーフォーマットですね。かつ、Web APIとしても非常に扱いやすい。

データベースなのにそんな不定形のデータをいっぱいためこんでどうするのかというところで、こっちのビューエンジンというのがありまして、こちらのほうではMapReduceフレームワークを使ってデータをどんどん処理していきます。このビューエンジンの「ビュー」というのはリレーショナルデータベースで言うビューとイメージとしては同じです。データは別にあって、それの見せ方をデータと別に定義ができますよ、ということですね。

データは不定形に持っているんですけれども、MapReduceで提供されるクラウドの計算力を活かしてどんどんそのインデックスを作っていって、そのインデックスをユーザーに提供する。そういう構想のデータベースです。

この図はあとJavaScriptでSpiderMonkeyというエンジンを使ってますよというのと、国際化対応でICUライブラリを使ってますよというのと、データ検索でLuceneを使っている。あと複製にも対応しますよという図ですね。

アプリケーション側から見ると、クラウドを使っている、不定形のデータをどんどん蓄えることができる、という点がおもしろい。アーキテクチャ的に見ると、テクニカルな話になるんですけれども、ストレージにどんどんデータを追記していく形になっている。たとえばオラクルなどの普通のリレーショナルデータベースですと、古いデータを新しいデータに置き換えるときはトランザクションをコミットして...という流れになっていて、それが失敗した時に何が起きても大丈夫なようにRedoログだのUndoログだのをいっぱい作っておく、というようになってるんですけど、CouchDBの場合は、とにかく古いデータには古いバージョンナンバーを、新しいデータには新しいバージョンナンバーをというふうに、シリアルなバージョンナンバーを振ってどんどん新しいデータを書き足していく。で、書いている途中に何かトラブルがあったら、それは一番さきっちょの今書いているところがトラブりました、古いデータは大丈夫です、だから古いデータを読んでください、というような仕掛けになっています。

彼らはそれをcrash only architectureと呼んでるんですけども、RDBみたいにRedoログやUndoログがいらない、どんどん書き足していくだけの動作なので非常にシンプルかつデータの破損が起こりにくいしくみになっているぞ、と彼らは言ってます。そのあたりの話はtechnical overviewに詳しいんですけども、そういうパフォーマンスを出すための工夫というのがまたいろいろと盛り込まれていて...」

いぬい「ディスクがいっぱいになってきますよね?」

しおや「ディスクがいっぱいになってきた場合にはですね、ガーベジコレクションみたいな仕組みで古いバージョンのデータを消していきます」

いぬい「ビューエンジンがクラウドというのはどういう意味ですか?」

しおや「ビューエンジンがクラウドというのは、たとえばここに、nameというツリー構造の項目を持つJSONのドキュメントがあるとします。また、こっちには全然別の構造なんだけどやはりnameという項目を持つデータが含まれている別のドキュメントがあるとします。こういうのがどんどんストレージにたまっていく。ビューエンジンのほうはMapReduceフレームワークに対応したプログラムとして登録されていて...」

いぬい「MapReduceフレームワークとは何ですか?」

しおや「MapReduceフレームワークはクラウドでよく使われているもので、Mapのほうはこの例で言えばnameという項目のついたデータ、たとえば name=Taro、name=Jiroというデータをどんどん集めていく。Reduceのほうはそれを処理していき、たとえばサマリーとしてnameのあるデータが2件ありましたよ、と報告していくという分業体制でデータを処理します。

こういう分業体制をとることによって、クラウドのような、沢山コンピュータはあるけれどお互いに何かを共有しているわけじゃない、バラバラに動いているというような環境で、計算機リソースをうまく活用するしくみです」

かわの「他に誰がやってるかを気にしなくても分業できるということですね?」

しおや「そうですね。だからここ(ビューエンジン)の処理が重荷だということになれば、ここはいくらでもノードを増やして処理ができる...それがさっきクラウドと言ったところですね。この結果出来たものが、ビューとしてユーザに提供される、と」

かわの「name=Taroとかname=Jiroとかいうフィールド名は、構造上違うところにでてきても、同じnameというフィールド名が付いていれば取り出せるというところがポイントなわけですね?」

しおや「そうですね。もうちょっと詳しく言うと、取り出すところもJavaScriptのプログラムで書けるようになっていて、だからどんなフォーマットでも取り出せるといっても当然取り出すプログラムを細かく書いてあげなければいけないんですけど、RDBと違ってあらかじめnameというカラムを定義しておかなきゃいけないっていうことはない、と」

かわの「じゃ、データ構造を変えてもそれに合わせたJavaScriptのコードを書いてやれば対応できるっていうこと?」

しおや「そうです」

ともじ「CouchDBってアマゾンのSimpleDBとかグーグルのBigTableとかと比べられることって多いんだろうと思うんですけれども、それぞれの違いとか特徴というとどうなりますか?」

しおや「SimpleDBやBigTableはキーバリュー形式のDBと言いまして(編注・BigTableは単純なキーバリュー形式ではなく、列指向)、1つの式に対して1つの値が対応するというかなりシンプルな形のデータベースなんですよ。当然、アプリケーションを組むとそれだけでは足りないというときもあるんで、結局アマゾンですとストレージサービスを用意するのでそこでデータベースを走らせてくださいとかなんとかしてくださいとかいうことになります。CouchDBはバリューに相当するところに豊かな構造を持つドキュメントを格納することができる、という違いがあります」

ともじ「それは技術的にCouchDBのほうが進んでいるというような(意味ですか)?」

しおや「進んでいるというより、アーキテクチャが違うということですね」

ともじ「SimpleDBはちょっとだけお遊びで使ったことがあって、遅いなっていうのが最初の印象だったんですけど、CouchDBはいかがですか?」

しおや「手元のMacで構築した環境では遅いですけど、ほとんどインストールしているだけなので(笑)、実際の性能まで含めてどうだ、ということまではなんとも言えないですね。ただ、彼らの主張によると、データを書き込んでいくわけですけれども、データがシリアルに書き込まれていくので常に一直線なわけですよ。普通のデータベースと違って、古いデータだからちょっとここに戻りますとかそういうことが基本的に無い、書き込むのは常に一番端っこの場所の空いてるところと決まっていて、そういうようにパフォーマンスが出るよう工夫されていると思います。ただクラウド環境のストレージだから、実はこういう工夫は関係ないかも?しれません」

しおや「アーキテクチャ面ではもう一つ、Erlangで動かしているというのもおもしろいところです。簡単に説明しますと、Erlangというのはスウェーデンの通信会社エリクソンが自分たちの通信プログラムを書くために開発した超並列実行型の言語で、我々がふだん使っているCとかJavaとかと違って最初から並列処理が念頭に置かれて設計されているので、いろいろと設計思想が違うところがあるそうです。私もまだこの程度の知識で詳しく試してないんですけれども、たぶんこのあたりは分散環境とかを研究されているといろいろ話題に出たりするのかもしれないですけども」

みや 「この前デモで見せてもらったときは、実際にデータを追加して項目も追加して、それを後から検索して、カラムの定義とか一切せずにどんどんやっていって、かつ、ロールバックやらロールフォワードやら全然無視していたり、なんだか今までのRDBとはまったく思想が違う新種のものだよっていうのが印象に残ってるんで、それが根付けばまた新しい世代のアプリケーションとシステムがどんどんできてくる、そのへんをウォッチしていったほうが(よいと感じてます)」

CouchDB だからできること

かわの「アーキテクチャ上のおもしろさはなんとなく分かったんですけど、用途として今までできなかったこういうことができるとかこういうことに向いているとかいう点はどうなりますか?」

しおや「そうですね、ここまでの話とはちょっとずれるかもしれませんけど、(CouchDBは)古いデータを上書きしないでどんどん新しいデータを追記していくという形で、バージョン管理システムになってるんです。古いバージョンのデータは容量がいっぱいにならない限りはいつまでも残っている、と。ですから、これはどこかで提案されていた話なんですが、具体的な用途としてはWikiのバックエンドのデータベースですとか、そういう小まめに更新が入るし構造も人によって違うというようなデータにむいているんじゃないかと考えてます。どんなデータでもいれられるっていうことは、企業用のシステムというより個人のちょっとしたパーソナルデータベースみたいな使い方のほうがおもしろいのかな、と」

いぬい「これってREST形式でアップできるんですよね」

しおや「APIはそうです」

いぬい「WebAPIでアップできるので、Webのインターフェイスで直接DBを触れるわけですね。要は、DBが動いているサーバにはプログラムが要らないっていうか、これがあればアクセスできっていう...」

しおや「そういうことになります」

いぬい「そういう使い方ができるのかなと思いました」

かわの「REST形式って何ですか?」

いぬい「Web APIにそういうアクセス形式があって、データのフォーマットで...」

しおや「(ブラウザ画面を指して)このURLのところでいろいろコマンドですとかパラメータですとかを入れてデータのやりとりをするような方式という説明でまぁ違ってないと思います」

いぬい「そうですね」

かさい「HTTPのリクエストを発行すれば何でもいいらしいんですよ。telnetで接続して、telnetでコマンド打ち込んでもいい...」

いぬい「すみません、あんまりデータベースよく分かってないんですけど、たとえばnameがTaroでageが21才とか入れるじゃないですか、その場合に、後からTaroさんって何才だっけ、とか引くときは当然引けるわけですよね?」

しおや「引けますね」

いぬい「で、リレーショナルデータベースだと、カラムを増やすときに、定義しておいて入れないといけないじゃないですか。CouchDBは、たとえば名前と年齢のデータベースがあって、途中から性別も入れよう、ということになったときに、そこから突然性別も含むデータを入れていけるという話ですか」

かさい「今の話だと、データはかならずビューを参照して見るようになってるんですけども、今ここで名前の件数を見るビューを定義したわけですけど、ここで別に年齢を表示するビューを追加すると、それまでのドキュメントには年齢がないのでビューにとっては関係ないというか反映されないドキュメントになるわけですけど、ユーザーがそのドキュメントに性別を追記すれば、そこからはビューにも反映されるようにできます」

いぬい「ちょっと細かい話になりますけど、SQLだとどのキーがuniqueかということを定義できるじゃないですか。たとえば名前を一意だとするとNameがuniqueなキーになるじゃないですか。そういう場合、CouchDBではどのように処理されるんですか?」

しおや「CouchDBの場合どういうことになるかというと、ここのMapというデータを集めるプログラムの書き方次第ということになりますね」

いぬい「ということは、そこは自分で作るということですか?」

しおや「そういうことですね。たとえば、一意性(の制約)をもってデータを拒否するのはできなくなっているので、(ビューエンジンを指して)ここのところで名寄せをするようなプログラムを書くわけです」

いぬい「そのプログラムを書くということはJavaScriptで書く訳ですけど、基本的なJavaScriptは用意されているということですか?というのは、すべてそういう条件を自分で書いてやるというのはえらい大変な話ですよね。たとえば純粋に既存のデータベースのように使おうとして、たとえば社員管理をしたいとするじゃないですか。カラムはすべて決まってます、と。そのときにおそらく、名前は一意にはならなくてuniqueな社員番号をふってそれで管理しますね、そういうものを入れようとしたときに、ふつうのSQLのデータベースだと何も考えずに入れていけば済みますけど、CouchDBだとMap というところを何か作らないといけない?」

しおや「そうですね、ドキュメントそのものはいくらでもいれられるけど、たとえば社員番号で一意にしまった社員名簿を作りたいというときは、MapとReduceのプログラムを書いてやらないといけない。もちろん、一覧くらいはパッと出ますけれども。一意性で社員番号が同じデータがあったらどうするかというと、RDBだったらDBに入れないという判断をするわけですけど、CouchDBの場合は、データはどんどん入れていく。一意性などのコントロールはMap/Reduceのプログラムでうまくやってくれということで、同じ社員番号のデータがみつかったらどうするのかということを、プログラムを書く人が考えてやらないといけない」

いぬい「それはどれぐらいのプログラムを書く必要があるんですか、たとえば年齢が21才の人を出したいとしてそういうときもプログラムを書く必要があるということですか」

しおや「そうですね」

いぬい「それをSQL文で書こうとしたらSELECTを使って1行かけば出てくるじゃないですか、CouchDBではそういうものじゃなくてプログラムを何か...」

しおや「プログラム的にはですね、Map側というのは条件を書くんです。これはドキュメントをどんどん集めているMap側のプログラムなんですけど...(Mapの出力は)データをどんどん放り込んでいくだけなんで...」

いぬい「このプログラムというのはどこで書くんですか?」

しおや「操作用のインターフェイスが別にあってそこに登録するんです」

いぬい「これはインタラクティブに対応できる、そういうシェルみたいなものがあるという...」

しおや「あります、Futonという名前のWebインターフェイスなんですが」

いぬい「そこではJavaScriptを手で入力する?」

しおや「手で入れてます。そのJavaScript のプログラム自体もCouchDB が管理するデータ(ドキュメント)になってます。(関数が納められているこのドキュメントが)デザインドキュメントと呼ばれるドキュメントです」

いぬい「じゃ、デフォルトの関数というのもたくさんあるんですね?」

しおや「私もまだちょっとしか(把握していないですけれど)…それなりにあるらしいです」

(ここで塩谷氏による Futon の実際の操作デモ)

かわの「リレーショナルDBのときにレコードだったところがCouchDBだとドキュメントになるってことですね?」

しおや「そうです。このカラムっていうのはいくらでも種類が増やせる。おもしろいのはここにバージョンのリンクがあると思うんですけど、データを登録するとどんどん新しくバージョンが増えていくわけですね。(ここでデモ)データが更新されるとバージョンが新しくなることが分かります。(再びデモ)クエリーはこんな感じで書きます。ここに実行結果が表示されます」

いぬい「どういう場面で使えるんですかね?」

しおや「たとえば製品カタログみたいに、似たような項目はいっぱいあるけれども必ずしもかちっとフォーマットが決まってない、構造が厳密にはきまってないとか...」

ともじ「ひとつの応用の仕方として、全然まとはずれかもしれないんですけど、XML データってあるじゃないですか。XMLデータのツリー構造をJSON形式に落として、いわゆるXML-DBとしてCouchDBを使うというのは?」

しおや「そのままできると思います。いまのXML−DBはリレーショナルDBとXMLを統合するかたちで進化して来てると思うんですけど、CouchDBは逆にまずツリー構造のデータを使いたい、RDBとは違うアプローチで、とやってるんですけども、それが(企業向けのソリューションとして)プラスなのか、あまり企業受けしないのかは…(よくわからない)」

CouchDB の本質

かわの「そもそも何でこういうものを作ったんでしょう、その動機というのは何だった?」

いぬい「(その問いは言い換えれば)これを使うとベストなアプリケーションは何かということですよね」

かわの「きっとCouchDBを作った人は、それまでにある道具で満足できない理由があってこれを作ったんですよね」

しおや「思いつきですけど、例えばWikipediaでは特定のテーマについては決まったテンプレートがあって、たとえば歴史なら歴史のページのフォーマットはWikipediaとして決まっていて、さらに個別の小さなテーマごとにサブのテンプレートみたいなものがあって...そういうところからデータを取ってくるのになかなか便利なんじゃないかな、というような感じがします」

かわの「より自由な形式に、より柔軟に対応できるということですね」

かさい「CouchDB(=安楽椅子のデータベース)という名前もそうですし、Futonは日本語の布団に由来すると思うんですけど、いままでのリレーショナルデータベースのガチガチ感から逃れたいっていう気持ち、もうちょっと喜楽にやろうよ、という気持ちから発想したんじゃないですかね」

いぬい「データベースに入れようとしたら大変だけど、これならなんか入れられそう、という...」

かさい「そう、どんどん放り込んどけばいいんだから...定義は後でやればいい。リレーショナルデータベースは最初に設計してやる必要があるけど」

いぬい「なるほど、リレーショナルデータベースは最初に定義されたことを前提のうえで、整理したものを入れていくことになるんですけど、CouchDBの場合は整理するのは後で考えればいい、と」

しおや「名前のRelaxというのも、まさにそういうことなんでしょうね」

いぬい「なんかわかってきましたが、まだちょっとアプリケーションがどういうものが最適なのかが(見えない)」

ともじ「XMLの文書をファイル単位で検索ということでなく、いろんなXMLファイルをとりあえずCouchDBに放り込んでおいて、それからMap/Reduceを書いて処理をかけるというような...」

しおや「XMLやRDBというのは、入れるときもこの形のデータって決めなきゃいけないし、出るときもこういう形のデータなんだからこういうことができますよね、っていう使い方なんですけど、CouchDBの場合、入れるときは好きに入れて、出すときは、よくわかんないけどもふるいに引っかかったものがどんどん出てきますというようなことですね」

かわの「データの定義がなくてもJSON形式で書けさえすればいいわけですね」

しおや「はい。そのかわり、さっきの一意性の社員番号ですとか、データは一件の漏れもなく拾わなくちゃいけないというときにはかえって弱いかもしれない」

かわの「それが必要なときはリレーショナルDBを使えということですね」

しおや「きちんと定義できるんだったらそうしたほうが(早い)」

かさい「リレーショナルデータベースの代替品にはならない、って(ドキュメントにも)書いてありますね」

ともじ「しおやさんだったら、この技術をこれに使ったらおもしろいんじゃないかっていうのがありますか?」かわの「やっぱりログの管理?」

しおや「そうですね...ログの管理はひとつありますね。Map/Reduceの使い方がおもしろいので、ちょっとそれを使ってみたいなっていうのと、あと、たとえばふだん個人的に技術的なメモを書いたときに書いたはしからどんどんそれを放り込んでおいて、いっぱいためといて、あとでキーワードでひっかけてもいいんですけど、タグが付いていれば取り出しやすいとか。適当にタグだけつけておいて、いっぱい個人的なメモを蓄えておく。データベースがわりに使う。あとはバージョン管理があるのでそこをうまく使えればもっとおもしろいかもしれない...」

いぬい「同じ値を持つデータが同じドキュメントかどうかもバージョンで管理する?」

しおや「一応、すべてのドキュメントには唯一のIDがふられるようになってます」

いぬい「ではバージョン管理するときは、そのIDをもとに行うということですか」

しおや「そうです。だから、一意の(ドキュメント)IDが一種類だけシステムレベルで用意されていることになります」

ともじ「バイナリとかも入れられますか?」

しおや「バイナリはですね、以前のバージョンはMIME形式で、電子メールと同じような形で無理矢理テキストに落として入れてたらしいんですけど、次のバージョンでは(テキストに変換しなくても格納できるように)対応するという話のようです」

しおや「(用途については)コラボレーションのようにみんなで何か文章を書きながらアップデートするときなどに使うとおもしろいかもしれない」

ともじ「たとえばDITAの格納DBとかやるとおもしろいんじゃないかな」かわの「まさにぴったりという感じがしますよね」

(インフォサイエンスにて)