kumofs を試してみる

kumofs を試してみたのでメモをまとめておく。 記述内容のベースは 2010.04.30 時点での実験内容に基づいている。

kumofs とは

  • kumofs は分散型の key value store である。
  • 名前の由来は 雲 fast storage である。
  • データ保持サーバは動的に追加・離脱することができる。
  • memcached と互換性のあるインタフェイスを持つ。
    • set / get / delete ができる。
    • 細かいオプション (flags とか expiration time とか) はバージョンによって サポートしていたりいなかったりする。
    • 0.4.0 で CAS (Compare-And-Swap) 操作をサポートした。
  • Ficia (オンライン写真管理サービス)で使用されている。
  • えとらぼで古橋貞之氏によって作られた。
  • 2010.01.18 にオープンソースソフトウェアとしてリリースされた。
  • ライセンスは Apache License 2.0 を採用している。
  • 公開物件は github に置かれている。
    • github には ドキュメント も置いてあり、 大変親切に書かれているので助かる。
  • 更新情報は 作者のブログ 及び 作者の twitter などから得られる。
  • twitter hashtag には #kumofs が使われている。
  • SoftwareDesign 2010 年 02 月号に特集がある。
  • 2010.05.01 時点で version 0.3.5 である。

構成

kumofs は三種類のプログラムで動作する。

  manager ... 全体の統括を行う管理サーバ。
  server  ... データを保存するサーバ。レプリケーションも行う。
  gateway ... アプリケーションと server の橋渡しを行う。

役割を分担することでスケールする部分が明確になっている。

manager

manager はサーバ群の統括を行う。 1機または2機 で動作する。 2機ある場合は master-slave でレプリケーションを行う。

manager では、 kumoctl などの cli を用いて状態確認やサーバの attach などを行うことができる。 ブラウザとか妙な GUI とかが要らないところが良い。 作業ログを残したりする時に便利だし、キャラクタ端末があれば状態確認ができる っていうのは実にグッドだ。

デフォルトではポート番号 19700 を LISTEN する。

server

server はデータの保持とレプリケーションを行う。 1機からn機まで。動的に追加・離脱できる。

データ保持用のバックエンドに Tokyo Cabinet のハッシュデータベースを使用する。

デフォルトではポート番号 19800 と 19900 を LISTEN する。

gateway

gateway は アプリケーションと server の橋渡しをする。 アプリケーションを動かすサーバ上で動かすので、台数としては1機からn機となる。

アプリケーションからは localhost で動いている memcached サーバ であるかのように見える(見せる)。

アプリケーションが kumofs にアクセスするには memcached プロトコルを使用する。

試してみる

実験機材は 以下の通り。

本体
  ThinkPad x61s 15th Anniversary Edition

  % uname -rms
  FreeBSD 7.0-STABLE i386
  ベースシステムは 2008.03.31 頃cvsup/buildworld
  ports ツリーは   2010.04.28 頃cvsup

  % dmesg | grep 'real memory'
  real memory  = 2120941568 (2022 MB)

まずは全機能を一台で頑張ってみる。

準備

FreeBSD では ports から導入できる。カテゴリは databases である。 メンテナは kuriyama さんである。

バージョンは 2010.04.28 時点で 0.3.4 であったが、 このメモを書いている最中に 2010.05.01 になり、0.3.5 に上がった。 (2010.05.20 追記:0.4.0 に上がった。) かなりライブに追従されている様子なので、野良ビルドを考える必要はなさそう。

依存関係は3つ。裏にもう一つ。

  • バックエンドの databases/tokyocabinet
  • シリアライズのための(?) devel/msgpack
  • msgpack の ruby インタフェイス devel/rubygem-msgpack
  • rubygem が出てくるので、lang/ruby

ruby は上下に波及する依存が大きいが、それ以外の依存関係はシンプルだ。 今どきの FreeBSD 機なら ruby は入っているだろうから、 他の ports/packages との相性とかバッティングとかの心配は無い と言っていいだろう。

インストール

インストールは通常の ports の手順で大丈夫だ。

 # cd /usr/ports/databases/kumofs
 # make

まずは (入っていなければ) BUILD_DEPENDS な port が作られる。 tokyocabinet はインストールオプションを聞いてくる。 特にこだわりがなければデフォルトで良い。 ちなみにデフォルトは以下の通り。

                [ ] DEBUG    Debugging support
                [ ] DEVEL    Development build
                [ ] PROFILE  Profiling build
                [ ] OFF64    Use to compile on 64-bit system
                [ ] FASTEST  Fastest run
                [ ] SWAB     Swapping byte-orders build
                [ ] UYIELD   Detecting race conditions
                [ ] ZLIB     Disable ZLIB compression
                [X] BZIP2    BZIP2 compression
                [ ] PTHREAD  Disable POSIX thread support

make が終ったらインストールする。

 # make install
 (中略)
 ----
       This port has installed the following startup scripts which may cause
       these network services to be started at boot time.
 /usr/local/etc/rc.d/kumofs-manager
 /usr/local/etc/rc.d/kumofs-gateway
 /usr/local/etc/rc.d/kumofs-server
 ----
 (中略)
 ----
       For more information, and contact details about the security
       status of this software, see the following webpage:
 http://github.com/etolabo/kumofs
 ----
 # ls /usr/local/bin/kumo*
 /usr/local/bin/kumo-gateway     /usr/local/bin/kumolog
 /usr/local/bin/kumo-manager     /usr/local/bin/kumomergedb
 /usr/local/bin/kumo-server      /usr/local/bin/kumostat
 /usr/local/bin/kumoctl          /usr/local/bin/kumotop
 /usr/local/bin/kumohash

rc スクリプトが /usr/local/etc/rc.d/ に3つできる。 pkg-plist を見ればわかる通り、インストールされるファイルは全て 「kumo」の接頭辞が付いているので、わかりやすい。 でも k u m o ってキーボード上は全部右手なので、結構打ちにくいかも。

起動

初回動作までは、 本家ドキュメント の「チュートリアル」を見ながらやるとよい。 本家のドキュメントは、本当に丁寧に書かれている。

起動の順番は

  • kumofs-manager
  • kumofs-server
  • kumofs-gateway

である。

ports が提供してくれている rc スクリプトは manager が2台ある前提なので、 ここでは一台の実機で全部上げる手動起動の手順を 「すべてのプロセスをlocalhostで動かす」を参考に、若干書き換えて書いておく。

manager の起動は以下の通り。実験用ということで、シングル構成である。

 # /usr/local/bin/kumo-manager \
   -l localhost -d /var/run/kumofs/manager.pid -o /var/log/kumofs/manager.log
 # netstat -na | grep 19700
 tcp4       0      0  *.19700                *.*                    LISTEN

server の起動は以下の通り。実験用ということで、3本起動してみた。 シングル構成なので、ポート番号を変えて起動する。ちなみにデフォルトは末尾 0 だ。

 # /usr/local/bin/kumo-server \
   -m localhost -l localhost:19801 -L 19901 \
   -d /var/run/kumofs/server1.pid -o /var/log/kumofs/server1.log \
   -s /var/db/kumofs1.tch
 # /usr/local/bin/kumo-server \
   -m localhost -l localhost:19802 -L 19902 \
   -d /var/run/kumofs/server2.pid -o /var/log/kumofs/server2.log \
   -s /var/db/kumofs2.tch
 # /usr/local/bin/kumo-server \
   -m localhost -l localhost:19803 -L 19903 \
   -d /var/run/kumofs/server3.pid -o /var/log/kumofs/server3.log \
   -s /var/db/kumofs3.tch
 # netstat -na | grep 1980
 tcp4       0      0  *.19803                *.*                    LISTEN
 tcp4       0      0  *.19802                *.*                    LISTEN
 tcp4       0      0  *.19801                *.*                    LISTEN

gateway の起動は以下の通り。

 # /usr/local/bin/kumo-gateway -t 11211 -F \
   -m localhost -d /var/run/kumofs/gateway.pid -o /var/log/kumofs/gateway.log
 # netstat -na | grep 11211
 tcp4       0      0  *.11211                *.*                    LISTEN

役者は揃ったので、状態を見てみる。

 # kumoctl localhost status
 hash space timestamp:
   Thu Jan 01 09:00:00 +0900 1970 clock 0
 attached node:
 not attached node:
   127.0.0.1:19801
   127.0.0.1:19802
   127.0.0.1:19803

attach されているサーバは一つもないが、 manager から server が3本とも認識されていて、 それらはまだ attach されていない …という状態であることがわかる。

サーバ群を manager 配下にくっつける。

 # kumoctl localhost attach
 nil
 # kumoctl localhost status
 hash space timestamp:
   Sat May 01 11:07:28 +0900 2010 clock 513
 attached node:
   127.0.0.1:19801  (active)
   127.0.0.1:19802  (active)
   127.0.0.1:19803  (active)
 not attached node:

server が3本とも manager に追加されたことがわかる。

kumotop で稼働状況を見てみる。

 # kumotop -m localhost
               address     #Get     #Set     #Del     items                time
                          Get/s    Set/s    Del/s       QPS               clock
       127.0.0.1:19801        0        0        0         0 2010-05-01 11:09:13
                              0        0        0         0                 569
       127.0.0.1:19802        0        0        0         0 2010-05-01 11:09:13
                              0        0        0         0                 568
       127.0.0.1:19803        0        0        0         0 2010-05-01 11:09:13
                              0        0        0         0                 569

何のデータも入っていないまっさらな状態だが、 少なくとも動いているようだ。

接続してみる。

 % telnet localhost 11211
 version
 VERSION kumofs-0.3.4

返答が得られた。動作しているようだ。

何か store してみる。

 % telnet localhost 11211
 set hoge 0 0 8
 HOGEHOGE
 STORED

kumotop で見てみると、

               address     #Get     #Set     #Del     items                time
                          Get/s    Set/s    Del/s       QPS               clock
       127.0.0.1:19801        0        0        0         1 2010-05-01 11:20:58
                              0        0        0         0                 921
       127.0.0.1:19802        0        0        0         1 2010-05-01 11:20:58
                              0        0        0         0                 922
       127.0.0.1:19803        0        1        0         1 2010-05-01 11:20:58
                              0        0        0         0                 922

1 件の set があり、item は分散保管(レプリケーション)されているように見える。

これを get してみる。

 % telnet localhost 11211
 get hoge
 VALUE hoge 0 8
 HOGEHOGE
 END

無事、値が取り出せた。消してみる。

 % telnet localhost 11211
 delete hoge
 DELETED

kumotop で見てみると、即時には消えないようだ。

               address     #Get     #Set     #Del     items                time
                          Get/s    Set/s    Del/s       QPS               clock
       127.0.0.1:19801        0        0        0         1 2010-05-01 11:27:25
                              0        0        0         0                1116
       127.0.0.1:19802        0        0        0         1 2010-05-01 11:27:24
                              0        0        0         0                1116
       127.0.0.1:19803        1        1        1         1 2010-05-01 11:27:25
                              0        0        0         0                1117

技術資料によると kumo-server の -gX オプションで指定される時間が経過すると 消えるらしい。デフォルト値は 3600 なので…、一時間か。

消したものを取り出してみる。

 % telnet localhost 11211
 get hoge
 END

(値が得られないので) 確かに無くなっているようだ。

クライアントから接続

kumofs に繋ぐには memcached で繋げばよい。 3P (Perl、PHP、Python)、Ruby、Java などの多くのプログラミング言語で memcached を操作することができるようだ。

ちゃっちゃと書くなら自分には Java が書きやすいので、Java で実験してみる。 今どきはこういう状況では LL を使ってサクっとやるのが恰好イイんだろうけど。 さて、Java の場合、既製のクライアントライブラリを用いるのがよい。

有名どころが2つあり、2010.04 時点では Memcached for java が優勢のようだ。

Memcached for Java を使ってアクセスしてみる。こんなコードでよい。

    // 接続
    SockIOPool pool = SockIOPool.getInstance();
    pool.setServers(new String[]{"localhost:11211"});
    pool.initialize();

    // クライアントのインスタンスを生成
    MemCachedClient mcc = new MemCachedClient();

    // set
    boolean result = mcc.set("a", "alpha");
    System.out.println(result);

    // get
    String value = (String) mcc.get("a");
    System.out.println(value);

走らせると、

 true
 alpha

と返ってくる。set に成功し、値も取り出せたことがわかる。

MemcachedClinet#set の第二引数には Object を指定できる。 String でなくとも、Serializable なものなら set することができる。

Memcached client for Java の配布物には javadoc もソースも ちゃんと含まれているので、AscIIClient の set のところを読むとよいだろう。 AscIIClient の s と c は小文字なのに I と I が大文字なのは謎だ。 Ascii じゃだめなのかな。

故障

server を一台、殺してみる。

 # kill `cat /var/run/kumofs/server3.pid`
 # kumotop -m localhost

               address     #Get     #Set     #Del     items                time
                          Get/s    Set/s    Del/s       QPS               clock
       127.0.0.1:19801        0        0        0         2 2010-05-01 14:57:36
                              0        0        0         0                7424
       127.0.0.1:19802        0        0        0         2 2010-05-01 14:57:36
                              0        0        0         0                7424
       127.0.0.1:19803Connection refused - connect(2)

この状態でも値は取得できる。

 % telnet localhost 11211
 get a
 VALUE a 32 5
 alpha
 END

というわけで、「雲は落ちません」が実験できた。

停止

実験終了ということで、みな止める。

停止の順番は

  • kumofs-gateway
  • kumofs-server と kumofs-manager (← この二つは順不同でよい)

である。

手動で起動したので、pid ファイルを頼りに手動で停止すればよい。

 # kill `cat /var/run/kumofs/gateway.pid`
 # kill `cat /var/run/kumofs/server2.pid`
 # kill `cat /var/run/kumofs/server1.pid`
 # kill `cat /var/run/kumofs/manager.pid`

止める時と同じ構成で manager と server を起動して attach すると、 引き続き使える。

参考サイト

いっぱいある。

記事も多いし、反響も大きい。実際に動かしてみて、その「簡単さ」が実感できた。 ドキュメントが平易な日本語で丁寧に書かれていることも重要なポイントだ。 あとは「KVS の適用領域がどこであるか」ということをきちんと理解さえすれば、 さっくり実戦投入できそうだ。

[$Revision: 1.2 $ $Date: 2011.05.21 07:43:52 $]
[EOF]