54行で分散KVSを実装する(レプリケーション機能付き)
Ruby と MessagePack-RPC があれば、簡単なkey-valueストレージは簡単に作れます。54行で書けます(レプリケーションと負荷分散機能付き。サーバー38行、クライアント16行)。
簡単なKVSをベースにして、ログ集計や遠隔デプロイ、遠隔管理機能などの機能を追加していけば、ちょっと便利なサーバープログラムをサクサク自作できるハズ。
この分散KVSは、(keyのハッシュ値 % サーバーの台数)番目のサーバーにkeyを保存します。また、サーバーの名前順でソートしたときの「次のサーバー」と「次の次のサーバー」にデータをレプリケーションします。
すべてのサーバーで同じ設定ファイルを使います。サーバーごとの設定は引数を自分のホスト名に書き換えるだけなので、デプロイが容易です。
MessagePack-RPC for Ruby を使うと、分散しないkey-valueストレージ*1は以下のように書けます:
require 'msgpack/rpc' class KVServer def initialize @hash = {} end def get(key) # publicなメソッドがRPCで呼べるようになる! @hash[key] # @hashからkeyを取り出して返す end def set(key, value) @hash[key] = value # @hashにkey-valueをセット end end # MessagePack::RPC::Server#listen(アドレス, ポート番号, インスタンス) svr = MessagePack::RPC::Server.new svr.listen('0.0.0.0', '3030', KVServer.new) svr.run # イベントループ開始
と、20行足らずで実装できます。
クライアントは以下のようになります:
require 'msgpack/rpc' cli = MessagePack::RPC::Client.new('127.0.0.1', 3030) cli.timeout = 5 # 5秒でタイムアウトするように # MessagePack::RPC::Client#call(メソッド, 引数...) cli.call(:set, "key1", "val1") puts cli.call(:get, "key1")
このコードにレプリケーションと負荷分散の機能を追加すると、githubにあるソースコードのようになります:http://github.com/frsyuki/simple-kvs
コマンド1発でサーバー群を起動 & テストできるようになっているので、実際に動かしてみます:
$ gem install msgpack-rpc # MessagePack-RPC ライブラリ $ gem install chukan # 分散テストを自動化するライブラリ $ git clone git://github.com/frsyuki/simple-kvs.git && cd simple-kvs $ ./test.rb # 自動テスト開始
MessagePack-RPC for Ruby で作る分散KVSでした。
*1:「分散KVS」は「書き込みの性能がスケールアウトするKVS」を意図しています。