stone for memcachedプロジェクトを開始する

調べると,memcached冗長化・スケールアウト化するための,レプリケーション機能追加パッチやproxyソフトが出ていることが分かります.
http://lab.klab.org/wiki/Repcached
Google Code Archive - Long-term storage for Google Code Project Hosting.
http://www.thesavvyguideto.com/gridblog/2009/09/moxi-a-memcached-proxy/

しかし,私はもっとシンプルで透過的なものが欲しい.
KumoFSやROMAは,いずれもTokyo Cabinetに依存しているので,ディスクを使わないオリジナルのmemcachedにこだわりたい.

というわけで,昔から使っていたstone
Simple Repeater `stone'
をベースにして,memcachedクラウド化・スケーラビリティ確保のためのプロクシアプリを作ることにしました.
一から作らないのは,大人の事情で急ぐこと(笑),ソケット通信の多重化などの部分には時間を割きたくないこと(繰り返しますが,急ぐので),があります.


まず,複数のmemcachedが立ち上がっていて,データが同期されていれば,読み込みについてはstoneをほとんど改造する必要はありません.
ロードバランシング機能を使えば良いです.

IPプロトコルIPv4に限定し,memcachedに関係しない機能及びWindows対応はカットします.BSD/Linuxのみにします.
その改造を施したものをmemcached-stoneと名前を変えまして,コンパイルします.

> make bsd
make FLAGS="-DCPP='\"/usr/bin/cpp -traditional\"' -D_THREAD_SAFE -DPTHREAD -DREG_NOERROR=0 " LIBS="-pthread " memcached-stone
cc  -DCPP='"/usr/bin/cpp -traditional"' -D_THREAD_SAFE -DPTHREAD -DREG_NOERROR=0  -o memcached-stone memcached-stone.c -pthread

memcachedを二つ立ち上げます.

> memcached -vv -p 11212
> memcached -vv -p 11213

データ同期機能は作っていないので,それぞれのmemcachedに初期データとして同じデータをいれます.

# telnet localhost 11212
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
set foo 0 0 3
bar
STORED
^]
telnet> close
Connection closed.
# telnet localhost 11213
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
set foo 0 0 3
bar
STORED
^]
telnet> close
Connection closed.

memcached-stoneを立ち上げます.

> ./memcached-stone -d -B localhost:11212 localhost:11213 -- localhost:11212 localhost:11211
Feb  7 19:05:55.703405 673189952 start (2.3e) [82539]
Feb  7 19:05:55.703468 673189952 Debug level: 1
Feb  7 19:05:55.708292 673189952 stone 3: 127.0.0.1:11212 <- 127.0.0.1:11211

一回目,キーからバリューを取得してみます.存在しないキーについても適当に取得を試みます.

# memcat --servers=127.0.0.1:11211 foo
bar
# memcat --servers=127.0.0.1:11211 1
# memcat --servers=127.0.0.1:11211 2
# memcat --servers=127.0.0.1:11211 3

一つ目のmemcachedのログはこんな感じです.

<18 new auto-negotiating client connection
18: Client using the ascii protocol
<18 set foo 0 0 3
>18 STORED
<18 connection closed.
<18 new auto-negotiating client connection
18: Client using the ascii protocol
<18 get 1
>18 END
<18 quit
<18 connection closed.
<18 new auto-negotiating client connection
18: Client using the ascii protocol
<18 get 3
>18 END
<18 quit
<18 connection closed.

fooがSTOREDされたあと,1と3がgetされてます.

二つ目のmemcachedのログはこんな感じです.

<18 new auto-negotiating client connection
18: Client using the ascii protocol
<18 set foo 0 0 3
>18 STORED
<18 connection closed.
<18 new auto-negotiating client connection
18: Client using the ascii protocol
<18 get foo
>18 sending key foo
>18 END
<18 quit
<18 connection closed.
<18 new auto-negotiating client connection
18: Client using the ascii protocol
<18 get 2
>18 END
<18 quit
<18 connection closed.

fooがSTOREDされたあと,fooと2がgetされてます.


見事に負荷が分散されており,2倍の負荷に耐えられそうです.
あとは,STOREの時に,両方のmemcachedに配信すれば良いはずです.


gitよりも今のところsubversionが好きなので,sourceforgeでプロジェクト管理をします.
関心がある方は御連絡下さい.
アカウントは作ってリポジトリも開いたのですが,まだプロジェクト許可が下りていないのでMLがありません.
許可が下り次第連絡します.