2011年3月17日木曜日

PythonからCouchDBに大量データをInsertしようとした

PythonからCouchDBに大量データをinsertしようとしてみました。
しようとした…としているのは結論から言うと出来なかった為です。

まず、マニュアルに沿ってCouchDBのinstallをしました。
(OSはFedora13です)

// yumで必要なパッケージをインストール
yum install erlang subversion icu libicu-devel js js-devel libcurl-devel libtool

// ソースの取得
svn checkout http://svn.apache.org/repos/asf/couchdb/trunk couchdb

// CouchDBのインストール
cd couchdb
./bootstrap
./configure
make install

// 起動
couchdb
---------------------------------------------------------------------
Apache CouchDB 1.2.0a1078467 (LogLevel=info) is starting.
Apache CouchDB has started. Time to relax.
---------------------------------------------------------------------
これで起動完了です。"Time to relax"なんて洒落てますよね。

次にCouchDBのPython用のドライバのinstallを実施しました。
easy_install couchdb

またBrowserからアクセスして新しいDBを作成します。
ここではtestdbを作成しました。

ここまでは何の問題も無く終了。

次に以下のようなソースを実行します。
基本的にはMongoDBで使ったものとほとんど一緒です。
以前もやったようにCSVネタとして100万件のneta.csvを用意しておきます。

----------------------------------------------------------------
#!/usr/bin/env python

import csv
import couchdb
import time

if __name__ == '__main__':
    start = time.time()
    server=couchdb.Server()
    db = server['testdb']
    reader = csv.reader(open("./neta.csv"))
    for row in reader:
        _id = row[0]
        value = row[1]
        t = {"_id":_id , "value":value}
        db.save(t)
    print time.time()-start
----------------------------------------------------------------

上記を実行すると我慢出来ない位遅い結果となりました。
大体ですが、100件save()するのに8〜9sかかります。
つまり100万件saveするには丸一日かかってしまいます。

尚、CouchDBはデフォルトのままで使用しており、パラメータチューニング?等は全く行っていません。なんで、こんなに遅いんでしょうか?正確には不明ですが、save()の度にcommit()に近い処理が行われてる為なのかな・・・と思い色々調査しましたが、原因が分かりませんでした。Pythonのコードの書き方が原因だと思うんですが。。。


以下は気づいた点です。


・couchdb.Server()の設定値
Pythonドライバのマニュアルではcouchdb.Serverを実行する際に
 full_commit=Truesession=None
がデフォルトとなっているようだが、上記二つの値の正確な意味が不明。このあたりの仕組みが理解出来れば何とかなるのでは・・・と思ったが分からず。

・saveをまとめてやる
save()をまとめてやれれば、パフォーマンス改善しそう…ですが、実装方法が分かりませんでした。


・delayed_commits
/usr/local/etc/couchdb/default.ini の記述をよく見ると、

delayed_commits = true ; set this to false to ensure an fsync before 201 Created is returned
という一行があり、defaultではsave()毎に実行するであろうfsync()を待たずに動作していると思われる。




尚、CouchDBにはその他DBMSやMongoDBと違ってコマンドラインからselectしたりupdateしたりするクライアントが無く、全てFutonと呼ばれるGUIからしか操作する事になります。また、単純なselectに該当するものが簡単には出来ない為、RDB慣れしてる者にとっては非常にとっつきにくい印象を受けます。


<まとめ>
・CouchDBのインストールはスムーズに完了
・Pythonのコード自体も非常にシンプルに実装可能
・データ挿入のパフォーマンスは???測定不能。Pythonのコーディングの問題??
・RDBに慣れてるものにとっては何だかとっつきにくい

全然RELAX出来ませんでした。むしろいらいらします。


慣れの問題ですかね???
個人的にはMongoDBの方を推奨ですかね。。