kt-msgpackを改造してKyotoTycoonを操作できるProcedureを便利にしてみた
KyotoTycoon では.so、.dylibといった共有ライブラリによるプラグインをサポートとして、プラグインとして、memcachedプロトコルを実装したプラグインや、msgpack-rpcで使えるようにした kt-msgpack がある。 kt-msgpack では、msgpack-rpc を利用しているので、同期的なProcedureの呼び出しはもちろん、非同期なProcedureの呼び出しや、レスポンスを返さない通知的なProcedureの呼び出しでKyotoTycoonのデータをいじれるようになっている。 ですがですが、ソースを見てみると、KyotoTycoonで提供しているProcedureがあまりにも少ないことが分かったので、git にあるプロジェクトをforkしてちょっと充実させてみた。
充実させたProcedureたち
今回の改造で、充実&追加したProcedureは以下な感じ。
ping
echo
status
add
set
get
remove
append
seize
clear
replace
cas
increment
increment_double
match_prefix
match_regex
set_bulk
remove_bulk
get_bulk
vacuum
synchronize
データ操作系や検索系、そしてバルク操作系があるので、これぐらいあれば何とかことは足りるかと。 pingという変な名前のProcedureがありますが、これはvoidに相当し、msgpack-rpcの制約(というかIDLからC++のコードを生成するツールの制約?)でProcedureが別名にしています。 詳細はここのProceduresの一覧をご覧ください。
サポートしなかったProcedureたち
今回諸事情サポートしなかったProcedureは以下な感じ。
report
play_script
tune_replication
cur_jump
cur_jump_back
cur_step
cur_step_back
cur_set_value
cur_remove
cur_get_key
cur_get_value
cur_get
cur_seize
cur_delete
report、play_script、tune_replication はちょっと作りこみ(場合によってはKyotoTycoonをいじる必要があるかも)が必要なので今回は対応していない。
cur_xxx系は、KyotoTycoonのアーキテクチャとmsgpack-rpc(mpio)のアーキテクチャが異なっているので、実装するのはちょっとしんどい。KyotoTycoonではセッション毎にローカルストレージにcursorオブジェクトを保持することで対応できているのだが、msgpack-rpc(mpio)では、KyotoTycoonのような感覚でセッションを使える仕組みがないので、同じ機能の実装はmsgpack-rpcを改造でもしない限りちょっと辛いところだ。(というより、自分がmsgpack-rpcに同じような機能があるのを知らないだけ?)
そもそも、cursorの操作については、KyotoTycoonの作者のブログに書いてある意見と同じく、ネットワーク越しに長期間リソースを占有するようなものは、サーバのリソースの無駄遣いだと思う。そのようなことをしたい場合はplay_scriptのようなストアドプロシジャ的なスクリプトでcursor操作をして、さくっと用を足してしまえばいいと個人的に思っている。 なので、今後は、cur_xxx系のProcedureは対応しない方向で考えている。
パフォーマンス測定
せっかく、Procedureを充実させたんで、一番気になるバルク系のデータ操作のパフォーマンスを測ってみた。 計測は5回行い、平均値を計る。サーバ、クライアントは同じマシン上で測定した。
測定プログラム
KyotoTycoon をインストールした際にバンドルされてくるktremotetestとそれをkt-msgpackを向けに改変した、ktmpremotetestによって行う。 また、比較のためktremotetestで、KyotoTycoonのHTTPとBinaryも計測する。 ちなみに、ktmpremotetestは今回改造したこちらからgit cloneしてインストールすると、kt-msgpackといっしょにインストールされる。
マシン環境
マシン環境は以下のとおり。
Macbook (13-inch, Early 2009)
OS: Mac OS X Lion 10.7.3
CPU: 2 GHz Intel Core 2 Duo
Memory: 4 GB 667 MHz DDR2 SDRAM
HDD: 256GB (FUJITSU MHZ2250BH FFS G1 Media SATA)
KyotoTycoonの起動オプション
KyotoTycoonの起動オプションは以下で起動する。
$ ktserver -th 8 -lz -plsv /opt/local/libexec/libktmsgpack.dylib -plex "port=18801#thread=8" "casket.kct#bnum=2000000#opts=ls#ktopts=p"
バケット数は100万レコードの2倍値(bnum=2000000)
データベースオプションは、4バイトアドレッシング、線形リスト(opts=ls)
パフォーマンスをちゃんと計測するために、KyotoTycoon側のスレッド数とkt-msgpackプラグインのスレッド数を同じ値に設定(-th 8, thread=8)
ログ出力はなし(-lz)
データは永続化(ktopts=p)
測定内容
KyotoTycoonの作者のこの記事と同じことをする。サーバに対して、「00000001」「00000002」といった文字列のキーと値を持つレコード合計100万件の読み書きを行う。 以下のコマンド、set系9パターン、get系9パターン、計18パターンを計測する。
ktremotetest bulk -th 4 -set -bulk 1 250000
ktremotetest bulk -th 4 -set -bulk 10 250000
ktremotetest bulk -th 4 -set -bulk 100 250000
ktremotetest bulk -th 4 -set -bin -bulk 1 250000
ktremotetest bulk -th 4 -set -bin -bulk 10 250000
ktremotetest bulk -th 4 -set -bin -bulk 100 250000
ktmpremotetest bulk -th 4 -set -bulk 1 250000
ktmpremotetest bulk -th 4 -set -bulk 10 250000
ktmpremotetest bulk -th 4 -set -bulk 100 250000
ktremotetest bulk -th 4 -get -bulk 1 250000
ktremotetest bulk -th 4 -get -bulk 10 250000
ktremotetest bulk -th 4 -get -bulk 100 250000
ktremotetest bulk -th 4 -get -bin -bulk 1 250000
ktremotetest bulk -th 4 -get -bin -bulk 10 250000
ktremotetest bulk -th 4 -get -bin -bulk 100 250000
ktmpremotetest bulk -th 4 -get -bulk 1 250000
ktmpremotetest bulk -th 4 -get -bulk 10 250000
ktmpremotetest bulk -th 4 -get -bulk 100 250000
-thは、起動スレッド数を意味する。 -setはset_bulkによるレコード設定を意味する。 -getはget_bulkによるレコード設定を意味する。 -bulkは、バルク操作で一度に設定/取得するレコード数を意味する。 ktremotetestの-binはBinaryプロトコルによるバルク設定/取得を意味する。このオプションがない場合は、HTTPプロトコルによるバルク設定/取得になる。
測定結果
100万件のバルク操作の計測結果は以下のようになった。
計測1 計測2 計測3 計測4 計測5 average 1.HTTP set 1 bulk 124.643 126.641 119.626 125.788 140.967 127.533 2.HTTP set 10 bulk 20.731 17.873 15.776 16.058 15.281 17.1438 3.HTTP set 100 bulk 7.052 6.719 8.246 6.54 6.778 7.067 4.Binary set 1 bulk 70.699 71.705 66.925 70.883 70.841 70.2106 5.Binary set 10 bulk 8.44 9.193 8.939 9.877 8.776 9.045 6.Binary set 100 bulk 4.449 4.923 4.341 4.412 4.309 4.4868 7.msgpack-rpc set 1 bulk 78.078 85.017 79.846 77.657 87.636 81.6468 8.msgpack-rpc set 10 bulk 16.943 14.585 13.157 13.645 17.013 15.0686 9.msgpack-rpc set 100 bulk 7.261 7.19 6.894 7.659 10.003 7.8014 10.HTTP get 1 bulk 117.963 124.22 122.057 120.705 132.164 123.4218 11.HTTP get 10 bulk 16.756 19.225 18.153 18.522 21.171 18.7654 12.HTTP get 100 bulk 8.068 8.733 11.251 9.193 9.028 9.2546 13.Binary get 1 bulk 61.831 72.635 74.087 70.9 75.88 71.0666 14.Binary get 10 bulk 9.883 10.741 11.739 10.249 13.278 11.178 15.Binary get 100 bulk 5.861 7.47 6.11 6.061 6.048 6.31 16.msgpack-rpc 1 bulk 79.438 89.539 74.367 92.129 91.659 85.4264 17.msgpack-rpc 10 bulk 18.262 19.146 16.453 20.083 19.446 18.678 18.msgpack-rpc 100 bulk 11.175 10.415 10.667 10.95 14.237 11.4888
やっぱり、Binaryがパフォーマンスいいですね。msgpack-rpcも結構いい感じパフォーマンスでています。この計測結果からみると、パフォーマンスとしては、
Binary > msgpack-rpc > HTTP
といった感じでしょうか。まあ、bulk操作で扱うデータ数を増やせば、まあそれなりの速度で処理することができるので、どれを利用しても実運用上特に問題ないかあと。同期、非同期の通信を柔軟に選択できつつ、パフォーマンスが確保できるっていうのがメリットなのかもしれない。(まあ、Node.jsを利用すれば、それできますけど。。。)
まとめ
kt-msgpackをforkして、KyotoTycoonで提供するProcedureを充実させました。この改造により他の言語でもmsgpack-rpcを利用することで、set、getによるデータ操作、バルク一括操作、検索、そしてcas、incrementが利用できるようになりました。msgpack-rpcのバルク操作のパフォーマンスも、HTTPとBinaryの間なので、通信機能で柔軟にロジックを制御したいっていう場合には、KyotoTycoonを使うユースケースでは、kt-msgpackを選択するのはいいかもしれません。












