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 すると、 引き続き使える。
参考サイト
いっぱいある。
- key-valueストアの基礎知識
SoftwareDesign 2010 年 02 月号の記事。基礎知識が解説してある。 このページは多くのところから参照されることだろう。 - 分散Key-Value ストア「kumofs」の概要とインストール
インストール手順。yum でやる人向け。参考ページが充実している。 - ほぼまっさらな CentOS5.4 に kumofs をインストール
Cent な人向け。起動スクリプトが参考になる。 - memcached client for Java + kumofs 0.3.4 での接続確認
接続テストコードや flags 回りの注意点が参考になる。 - memcached in Java
たいがいの Web アプリは非同期キャッシュは要らないだろうから memecached for java でよいだろう、と書かれている。 - 【調査】【memcached】memcached client for java VS spymemcached
memcached for java の方がシンプルだからよい、と書かれている。 - 【ハウツー】memcached client for java - Java で memcached を使おう
サンプルコードが参考になる。 - Debian GNU/Linux Sarge で java memcached client を試す
オブジェクトを格納する際の注意点が参考になる。
記事も多いし、反響も大きい。実際に動かしてみて、その「簡単さ」が実感できた。 ドキュメントが平易な日本語で丁寧に書かれていることも重要なポイントだ。 あとは「KVS の適用領域がどこであるか」ということをきちんと理解さえすれば、 さっくり実戦投入できそうだ。