CouchDB について Erlang 分散システム勉強会で紹介してきました
先日、Erlang分散システム勉強会で、最近私が追っている CouchDB というオープンソースのドキュメント指向分散データベースについて紹介してきました。発表資料をおいておきます。
分散システムでしかも Erlang というニッチっぽい勉強会でしたが、30人の参加者が一瞬で集まり、非常に熱い会でした。私も自分の好きな話を好きなように話してしまい、参加者のみなさんはドン引きだったかもしれません…
これだけでは何なので、ついでに手元の Fedora7 on coLinux に CouchDB の trunk を入れたときの手順と、簡単な couchdb の使い方をご紹介しておきます。
基本的にはオフィシャルwikiにあるとおり、yum でモジュールを入れていけば問題ありません。素の coLinux からの場合、以下のモジュールが必要でした。
sudo yum install automake gcc libtool erlang \ help2man icu libicu-devel js js-devel
次に svn から最新の trunk を取ってきます。
svn co http://svn.apache.org/repos/asf/incubator/couchdb/trunk couchdb
普通にコンパイルします。最初に ./bootstrap が必要です。
cd couchdb; ./bootstrap; ./configure; make
ちゃんとコンパイルできたら、あとはインストールするだけです。
sudo make install
オフィシャルの説明では couchdb ユーザを作って /usr/local/etc/couchdb/couch.ini を編集するようになっていますが、いろいろいじるときは自分のアカウントで動かした方が楽です。
cd ~mkdir couchdbcd couchdb mkdir databases cp /usr/local/etc/couchdb/couch.ini . vi couch.ini
/usr/local/etc/couchdb/couch.ini が雛形なので、それをコピーし、
- データベースファイル(.couch)を格納するディレクトリ(DbRootDir)
- 他のマシンからアクセスするためのIPアドレス(BindAddress)
- ログファイルの位置(LogFile)
- ログレベル(LogLevel)
を書きかえます。ログレベルは debug にしておく方が、いろいろ情報が出てわかりやすくなります。
; etc/couchdb/couch.ini.tpl. Generated from couch.ini.tpl.in by configure. [Couch] ConsoleStartupMsg=Apache CouchDB is starting. DbRootDir=/home/yohei/couchdb/databases Port=5984 BindAddress=192.168.0.2 DocumentRoot=/usr/local/share/couchdb/www LogFile=/home/yohei/couchdb/couch.log UtilDriverDir=/usr/local/lib/couchdb/erlang/lib/couch-0.8.0-incubating/priv/lib LogLevel=debug [Couch Query Servers] javascript=/usr/local/bin/couchjs /usr/local/share/couchdb/server/main.js
あとは -c オプションで設定ファイルを指定して couchdb を起動するだけです。
% /usr/local/bin/couchdb -c couch.ini Apache CouchDB 0.8.0-incubating (LogLevel=debug) Apache CouchDB is starting. Apache CouchDB has started. Time to relax. [debug] [<0.1.0>] Config Info /home/yohei/couchdb/couch.ini: CurrentWorkingDir=/home/yohei/couchdb DbRootDir=/home/yohei/couchdb/databases BindAddress="192.168.0.2" Port="5984" DocumentRoot=/usr/local/share/couchdb/www LogFile=/home/yohei/couchdb/couch.log UtilDriverDir=/usr/local/lib/couchdb/erlang/lib/couch-0.8.0-incubating/priv/lib DbUpdateNotificationProcesses= FullTextSearchQueryServer= javascript=/usr/local/bin/couchjs /usr/local/share/couchdb/server/main.js
このようなログが流れれば起動は成功です。
curl でアクセスしてみましょう(curl が入っていない場合は yum で入れてください)。
colinux% curl -v http://192.168.0.2:5984
* About to connect() to 192.168.0.2 port 5984 (#0)
* Trying 192.168.0.2... connected
* Connected to 192.168.0.2 (192.168.0.2) port 5984 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.16.4 (i386-redhat-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.8
> Host: 192.168.0.2:5984
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: MochiWeb/1.0 (Any of you quaids got a smint?)
< Date: Thu, 19 Jun 2008 05:42:35 GMT
< Content-Type: text/plain;charset=utf-8
< Content-Length: 50
<
* Connection #0 to host 192.168.0.2 left intact
* Closing connection #0
{"couchdb":"Welcome","version":"0.8.0-incubating"}
ルートにアクセスすると Welcome メッセージとバージョン番号が入った JSON ドキュメントが取得できます。
データベースは PUT で作成できるので、PUT /test というリクエストを送ってみます。
colinux% curl -v -X PUT http://192.168.0.2:5984/test
* About to connect() to 192.168.0.2 port 5984 (#0)
* Trying 192.168.0.2... connected
* Connected to 192.168.0.2 (192.168.0.2) port 5984 (#0)
> PUT /test HTTP/1.1
> User-Agent: curl/7.16.4 (i386-redhat-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.8
> Host: 192.168.0.2:5984
> Accept: */*
>
< HTTP/1.1 201 Created
< Server: MochiWeb/1.0 (Any of you quaids got a smint?)
< Date: Thu, 19 Jun 2008 05:44:58 GMT
< Content-Type: text/plain;charset=utf-8
< Content-Length: 11
<
* Connection #0 to host 192.168.0.2 left intact
* Closing connection #0
{"ok":true}
ちゃんと 201 Created が返ってきましたね。今度は ドキュメントを追加してみます。ドキュメントの名前(id)がURIに入るので、PUTでドキュメントを作成できます。
colinux% curl -v -X PUT -H "Content-Type: application/json" \
--data "{\"hoge\": \"fuga\"}" http://192.168.0.2:5984/test/testdoc
* About to connect() to 192.168.0.2 port 5984 (#0)
* Trying 192.168.0.2... connected
* Connected to 192.168.0.2 (192.168.0.2) port 5984 (#0)
> PUT /test/testdoc HTTP/1.1
> User-Agent: curl/7.16.4 (i386-redhat-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.8
> Host: 192.168.0.2:5984
> Accept: */*
> Content-Type: application/json
> Content-Length: 16
>
< HTTP/1.1 201 Created
< Server: MochiWeb/1.0 (Any of you quaids got a smint?)
< Etag: "1623090219"
< Date: Thu, 19 Jun 2008 05:55:33 GMT
< Content-Type: text/plain;charset=utf-8
< Content-Length: 45
<
* Connection #0 to host 192.168.0.2 left intact
* Closing connection #0
{"ok":true,"id":"testdoc","rev":"1623090219"}
ドキュメントの追加はデータベースURIへの POST でもできます。この場合はドキュメント名を指定する必要はありません。サーバ側で適当な名前を付けてくれます。
colinux% curl -v -X POST -H "Content-Type: application/json" \
--data "{\"hoge\": \"piyo\"}" http://192.168.0.2:5984/test;
* About to connect() to 192.168.0.2 port 5984 (#0)
* Trying 192.168.0.2... connected
* Connected to 192.168.0.2 (192.168.0.2) port 5984 (#0)
> POST /test HTTP/1.1
> User-Agent: curl/7.16.4 (i386-redhat-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.8
> Host: 192.168.0.2:5984
> Accept: */*
> Content-Type: application/json
> Content-Length: 16
>
< HTTP/1.1 201 Created
< Server: MochiWeb/1.0 (Any of you quaids got a smint?)
< Date: Thu, 19 Jun 2008 05:57:47 GMT
< Content-Type: text/plain;charset=utf-8
< Content-Length: 70
<
* Connection #0 to host 192.168.0.2 left intact
* Closing connection #0
{"ok":true,"id":"2366ffde9e795d8e9c9047f1303cfbcd","rev":"4244254602"}
POST の場合は Location ヘッダが返ってきた方がいいような気もしますが、ありませんね。今ソースを確認したところ、POST の場合でも Location を返さないようです。couchdbのバグっぽいですね。
ドキュメントができたらやっと GET できます。これは簡単です。
colinux% curl -v -X GET http://192.168.0.2:5984/test/testdoc
* About to connect() to 192.168.0.2 port 5984 (#0)
* Trying 192.168.0.2... connected
* Connected to 192.168.0.2 (192.168.0.2) port 5984 (#0)
> GET /test/testdoc HTTP/1.1
> User-Agent: curl/7.16.4 (i386-redhat-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.8
> Host: 192.168.0.2:5984
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: MochiWeb/1.0 (Any of you quaids got a smint?)
< Etag: "1623090219"
< Date: Thu, 19 Jun 2008 06:10:04 GMT
< Content-Type: text/plain;charset=utf-8
< Content-Length: 51
<
* Connection #0 to host 192.168.0.2 left intact
* Closing connection #0
{"_id":"testdoc","_rev":"1623090219","hoge":"fuga"}
レスポンスの Content-Type が text/plain なのがちょっと気に入りませんが、これはリクエストの Accept ヘッダに application/json がない場合は text/plain を返すように couchdb が実装されているからです。ブラウザなんかで見るときは、text/plain の方がなにかとありがたいからでしょう。Accept ヘッダを付けた場合の例も示しておきます。
colinux% curl -v -X GET -H "Accept: application/json" http://192.168.0.2:5984/test/testdoc
* About to connect() to 192.168.0.2 port 5984 (#0)
* Trying 192.168.0.2... connected
* Connected to 192.168.0.2 (192.168.0.2) port 5984 (#0)
> GET /test/testdoc HTTP/1.1
> User-Agent: curl/7.16.4 (i386-redhat-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.8
> Host: 192.168.0.2:5984
> Accept: application/json
>
< HTTP/1.1 200 OK
< Server: MochiWeb/1.0 (Any of you quaids got a smint?)
< Etag: "1623090219"
< Date: Thu, 19 Jun 2008 06:11:48 GMT
< Content-Type: application/json
< Content-Length: 51
<
* Connection #0 to host 192.168.0.2 left intact
* Closing connection #0
{"_id":"testdoc","_rev":"1623090219","hoge":"fuga"}
こんな感じで、curl のような HTTP クライアントがあれば、すぐに CouchDB で遊んでみることができます。各言語用のライブラリもいろいろ出てきていますので、それを使うのもいいでしょう。HTTP ライブラリさえあれば、ラッパーを作るのは簡単なのでぜひお試しください。
