Mnesia で作った memcached もどきにレプリケーション機能とディスク保存機能を追加した

まだ中途半端だが、晒してみる。
突っ込み大歓迎。

インストール

% cd /path/to
% svn co http://labs.miu.vc/svn/cooldaemon/erl/yamd/trunk/ yamd
% cd yamd
% make

FreeBSD なら make のかわりに gmake を実行。

使い方

scripts ディレクトリ配下の yamd を実行する事で操作を行う。

起動
% yamd start -n yamd1@`hostname` -p 11211 -t ram
-n 起動する erlang ノード名を指定する。(-sname ではなく、-name を使っているので注意)
-p ポート番号
-t ram もしくは disc。disc にすると、読み込みはメモリから、書き込みはディスクへ行う。
停止
% yamd stop -n yamd1@`hostname`

rpc:call/4 を使って、init:stop/0 を実行しているだけなので -n オプションに指定する erlang ノード名は、ネットワーク越しでも良い。

エラーログの確認
% yamd show -m error

yamd start を実行した後、とりあえず echo コマンドで「Starting Yet Another Memcached.」と表示しているが、何かのエラーがあると stdout や stderr に何も出力せず落ちる。
そこで、上記のコマンドを実行すると、落ちた理由が表示される。
※-detached で erlang ノードを起動したら、どうやって stdout とか stderr に文字を出力するんだろうか?sasl 使ってるから別に良いけど。

レプリケーション
% yamd copy -s yamd1@`hostname` -n yamd2@`hostname` -p 11212 -t ram
-s コピー元の erlang ノード名。ネットワーク越しでも良い。
-n,-p,-t 省略

copy と言いつつ、起動も行う。
コピー先の erlang ノードを ram ではなく disc で起動した場合、停止後の再起動は、既にディスクにデータが存在しているので「yamd copy」ではなく「yamd start」で行う必要がある。

試す

まずは、ディスクにデータを保存する yamd1 を起動する。

% yamd start -n yamd1@`hostname` -p 11211 -t disc
Starting Yet Another Memcached.

試す。

% telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
set key1 0 6
value1
SUCCESS
get key1
SUCCESS key1 6
value1
quit
Connection closed by foreign host.

次に、メモリにデータを保存する yamd1 のレプリケーション yamd2 を起動する。

% yamd copy -s yamd1@`hostname` -n yamd2@`hostname` -p 11212 -t ram
Starting replication node.

yamd1 で書き込んだデータを、yamd2 で取得できる事を確認する。

% telnet localhost 11212
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
get key1
SUCCESS key1 6
value1
quit
Connection closed by foreign host.

yamd1 を止めてしまう。

% yamd stop -n yamd1@`hostname`
Stopping.

ディスク書き込みを行うノードを止めてしまうので、ここでハード障害等が起こると、データが消えてしまう(w;
更に、yamd2 でデータを書き込む。

% telnet localhost 11212
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
set key2 0 6
value2
SUCCESS
quit
Connection closed by foreign host.

yamd1 再起動。

% yamd start -n yamd1@`hostname` -p 11211 -t disc
Starting Yet Another Memcached.

yamd1 が停止中に yamd2 で書き込まれたデータを、yamd1 で取得できる事を確認する。

% telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
get key2
SUCCESS key2 6
value2
quit
Connection closed by foreign host.

この状態で、全てのノードを停止後に再起動を行っても、当然データは残っている。

今後
  • テストコードをちゃんと書く
  • yamd chtype で、起動中のノードを ram <-> disc できるが、まだテストしないのでテストする
  • 相変わらず memcached プロトコル非対応だが、I/F を分離したので、後で暇をみつけて対応する
  • エラー処理をちゃんとやる(起動時と、tcp I/F まわり)
  • 他のノードに source code を送り込んで、勝手に yamd ノード化するコードを書く
  • 複数のキーを一度に操作する機能を追加する
  • async で書き込み・削除できる I/F を store に追加してあるので、tcp I/F を書く
  • そのうち性能評価する