冥冥乃志

ソフトウェア開発会社でチームマネージャをしているエンジニアの雑記。アウトプットは少なめです。

follow us in feedly

LevelDBをMac OSX + javaで使ってみた

最近、仕事で新しい技術に触れることが少なくなっているので、プライベートではなるべく意識して触ってみようとしています。
今は新しい言語とKVSとBTSを使って、使用感をまとめているところです。実際に取り組んでいるのは、以下の表の通りです。

言語 KVS BTS
Python levelDB Redmine

今回は、この中のlevelDBについて一通り使ってみるところまでやってみたので、まとめてみたいと思います。

LevelDBとは?

その前に、levelDBについてです。
Googleオープンソースで公開した軽量・高速なKVS(Key Value Store)のC++用組み込みライブラリ*1です。
leveldb - A fast and lightweight key/value database library by Google. - Google Project Hosting
ちなみに、使ってみるKVSを決める際に、levelDBでなければダメな理由は特にありませんでした。やってみようと思い立ったときにlevelDB公開のニュースが耳に入ってきたため、そのときにタイミングが良かった(?)だけの話です。

LevelDBのビルドとインストール

前述のサイトに飛んだ方ならお分かりかと思いますが、今のところソースからビルドするしかありません。
なので、Source Checkout - leveldb - A fast and lightweight key/value database library by Google. - Google Project Hostingを参照してSVNからソースをチェックアウトします。svnコマンドは以下です(サイトにも載っています)。

svn checkout http://leveldb.googlecode.com/svn/trunk/ leveldb-read-only

ソースをダウンロードしたら、次はビルドです。ビルドとインストールは下記サイトを参考にしました。
FreeBSDで,Google leveldbを使ってみた. - なぜか数学者にはワイン好きが多い
http://fallabs.com/blog-ja/promenade.cgi?id=130
上記ブログを見る限り、FreeBSD系で結構試行錯誤しながらビルドしています。実はC/C++は大学のときに計算プログラムを組んだときにしか触っていないので、Mac OSXでも同じになるのでは?、とやる前に少し戦々恐々としていました。
ところが。。。何のエラーも吐かずにmakeが通って逆に不安になる事態にww目の色変えてErrorの文字がないか探しましたww

で、これだけだとjavaでは使えない

C++用の組み込みライブラリなので当然javaからは使えません。公式にはjavaはサポートしていないようです*2
で、ググってみたところ、javaのサポートについて回答がついているQAを発見。
database - Does LevelDB support java? - Stack Overflow
質問:

I want to know if LevelDB supports java ? Where can i get the LevelDB. There are no files under http://code.google.com/p/leveldb/

回答:

You can use the https://github.com/fusesource/leveldbjni java library which gives you a Java API to LevelDB via JNI.

LevelDB JNIを作ってgithubに公開している人がいるよ、とのことです。という訳で早速ダウンロードしてみます。
インストール(というかビルド手順)もgithubに公開されています。詳細は、fusesource/leveldbjni · GitHubを参照してください。ビルドにはsnappy*3Mavenが必要です。

実は、ここが一番詰まりました

JNIのパッチをあててleveldbを再度makeしたところ。。。できない???
大まかに引っかかったところを列挙すると。。。

  • パッチあてたけど、make: Nothing to be done for `all'.と返ってくる
    • make -Bで強制的に実行
  • maven使ってビルドするときにエラーが出た
    • [ERROR] Java heap space -> [Help 1]
    • [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/OutOfMemoryError
    • javaのヒープサイズ不足??
      • より詳しくと思って mvn -e 叩いてみたのが運のつき
      • [ERROR] No goals have been specified for this build.
      • こんなん出ててよりわからんくなった。。。
      • マニュアル見ながら紆余曲折、全て失敗
      • 結局初心に返ってヒープサイズを見直して実行

そんなこんなで何とかできました。。。

ようやくjavaで使ってみたみました

JNIのサンプルを見ながら使ってみますが、Optionsクラスの生成でClassNotFoundExceptionが発生しました(T_T)。
どうやら org.fusesource.hawtjni.runtime.Library というクラスが必要らしいのですが、確かにビルドしたJNIにはそんなパッケージはありません。
実行時に依存するらしいのですが、JNIのReadmeに書かれていなかっただけのようです。hawtjni-runtime-1.3jar*4を追加します。ともかく、これで実行時に依存するライブラリに関してはクリアされているはずです。
。。。行けました。
で、levelDB JNIを通してlevelDBを使ってみて気づいたことを列挙してみます。

  • DB.open時に指定したディレクトリにデータベースが作られる
  • 実行時に存在しない場合は、設定によって挙動が変えられる
    • openメソッドに渡すOptionsでいろいろ設定可能っぽい
  • ドキュメントには、全てのコンテンツはこのディレクトリ以下にあるとのこと
  • destoryメソッドでデータベース一式を破棄できる
  • keyとvalueはJNIのインタフェースとしてはバイト列になっている
    • オブジェクトもシリアライズすれば格納可能
    • マルチバイト文字もOK
    • 値のアクセスは基本put,get,deleteの3種類のみ
    • 存在しないキーをgetしようとした場合は、DBException: NotFoundがスローされる
  • 値はputしたキーの昇順に格納される
    • Iteratorを取得して確認すると、キー順になっている
  • カスタムコンパレータを使用して、ソート順を変更することができる
    • ただし、設定はdatabaseのオープン時のみで、読み込んだdatabase全体の設定になる
  • バッチ書き込み(要はトランザクション発行)が可能
    • 複数の更新をアトミックに発行することができる。
  • オプションによっては圧縮をしないこともできるらしい。
  • キャッシュの設定も可能。

残りの設定などに関しては、公式ドキュメントをざっくりと翻訳しながら覚えているところです。

最後に

正直なところ、levelDBの各種機能がKVSとして基本的なところかどうかも自分の知識の中に比較対象がないのでよくわかりませんが、「KVSと戯れる」という目的であれば、levelDBを選択しなくても他に選択肢はいろいろあったと思います(Casandoraとか)。わざわざソースからダウンロードしてビルドまでする必要ないですし。今回は本筋以外のところで勉強に勉強になった感じです。
それと、普段英語に接していない私からすると、英語ドキュメント漬けの状態は正直疲れました。何の拷問かと。。。
ちなみに、levelDBの公式ドキュメントを翻訳中です。今回いろいろ試してみたソースはテストコードとともに、いずれgithubに公開するつもりですので、お役に立てばお使いください。

そろそろ読書のアウトプットの方も再開したいですね。

*1:どうやらChromeのIndexedDatabaseの実装になるとのこと

*2:GoogleCodeにleveldb-java-clientというのがありましたが、リポジトリはあってもソースがないw

*3:Googleの圧縮ライブラリ

*4:JNIのネイティブコード呼び出しフレームワークっぽいのですが、JNI詳しくないのでよくわかりません