MessagePack-RPCとkumofsを試す
先週、デブサミ2010に参加したとき、
一番感銘を受けたのがkumofsのセッションでした
kumofsから学ぶNot only SQLの技術 - 古橋貞之の日記
細かい内容はこのエントリを見ていただければいいのですが、
個人的に気になったのが「非同期処理」のデモでして
あくまでkumofsで使う管理ツールのデモではあったのですが、
その非同期処理コードがあまりにも簡潔だったので、
ちょっと調べてみたくなったのです
Ruby で MessagePack-RPC - 古橋貞之の日記
具体的なコードは後述しますが、
あるサーバから別なサーバのCouchDBを非同期に叩いてみました
結果、当然ながら同期とは比較にならない速さですし、
そのコードも驚くほど簡潔でした(`・ω・´) b
そのテストコードを利用して、前に「Tokyo Tyrant」で試したテストを、
CouchDBに対して非同期バージョンで流してみましたが、
とても現実的な数値ではありませんでした
CouchDB自体、そこまでハードな使い方を想定してないのもあるでしょうね
RubyとCの関係みたいなもので、パフォーマンスを犠牲にして、
RESTfulなインターフェースという利便性を取っているわけで
ならば、ストレージを「Tokyo Cabinet」に変えて、
MessagePack-RPCで非同期処理させたら・・・と、
さくっとコードを直してテストし始めたのですが・・・
・・・人はそれを「kumofs」と呼ぶよね・・・Σ(゚Д゚)ガーン
というわけで、今度はkumofsをインストールすることに
./configure --prefix=/usr/local/tokyocabinet ruby extconf.rb --with-tokyocabinet-dir=/usr/local/tokyocabinet
【msgpack】
./configure --prefix=/usr/local/msgpack gem install msgpack
【kumofs】
./configure --prefix=/usr/local/kumofs \ --with-tokyocabinet=/usr/local/tokyocabinet \ --with-msgpack=/usr/local/msgpack
ここまでは良かったのですが、
いざmanagerを立ち上げようとしたところ、
TCのライブラリがないと怒られるのですΣ(・ω・ノ)ノ
もう一度configureのログをチェックしてみると、
以下のようなwarningが
tchdb.h: accepted by the compiler, rejected by the preprocessor!
つまり、configureの時点でTCのライブラリに弾かれているっぽいのです
そんな話をTwitterで書いていたのですが・・・
kumofsをconfigureしようとすると、tchdb.hへのアクセスがrejectされてしまう そのままmakeすると当然起動しない tokyocabinetのPathを変えてるのがまずいのかな・・・? TC自体は普通に動いてるんだけど・・・
http://twitter.com/parrot_studio/statuses/9468372839
@parrot_studio makeができたのであれば、おそらく実行時にライブラリを見つけられなかったのでしょう。export LD_LIBRARY_PATH=/path/to/tokyocabinet/lib を実行するとどうでしょう?
http://twitter.com/frsyuki/statuses/9468565975
@frsyuki "export LD_LIBRARY_PATH=/usr/local/tokyocabinet/lib" を実行したところ、kumo-managerが起動しました ありがとうございます
http://twitter.com/parrot_studio/statuses/9468911311
・・・作者さん本人からアドバイスを(ノ´・ω・)ノミ(m´_ _)m
いやぁ、Twitterってすばらしい・・・
cd /usr/local/kumofs/bin ./kumo-manager -v -l localhost & ./kumo-server -v -m localhost -l localhost:19801 -L 19901 -s /tmp/database1.tch & ./kumo-server -v -m localhost -l localhost:19802 -L 19902 -s /tmp/database2.tch & ./kumo-server -v -m localhost -l localhost:19803 -L 19903 -s /tmp/database3.tch & ./kumo-gateway -v -m localhost -t 11211 & ./kumoctl localhost attach
ちなみに、このあとの会話
よくみたらdocにかいてあるし ちゃんと読まないとダメだな・・・ http://github.com/etolabo/kumofs/blob/master/doc/doc.ja.md
http://twitter.com/parrot_studio/statuses/9469011379
@parrot_studio それ今書きましたw
http://twitter.com/frsyuki/statuses/9469144306
@frsyuki あ、そうだったんですか まあ、誰か同じところで引っかかった方の参考になればなによりです
http://twitter.com/parrot_studio/statuses/9469565026
いやぁ、Twitterって(ry
今日はここまでが限界だったので、
kumofsにデータを流し込むテストはまた後日(`・ω・´)ノ
MessagePack-RPC経由でCouchDBを非同期に叩く
参考にしたのは前述のサイト
ほぼそのままに近い
クライアント側
require 'rubygems' require 'msgpack/rpc' cli = MessagePack::RPC::Client.new("192.168.xxx.xxx", 5000) # 同期テスト ------------------------------------ s_time = Time.now puts "sync start : #{s_time}" 100.times do |i| cli.call(:get, '/') end e_time = Time.now puts "sync end : #{e_time}" puts e_time - s_time # 非同期テスト --------------------------------- s_time = Time.now puts "async start : #{s_time}" # 先にメッセージを投げてしまう reqs = [] 100.times do reqs << cli.send(:get, '/') end # 先に投げたメッセージの返信を待つ reqs.each do |req| req.join.result end e_time = Time.now puts "async end : #{e_time}" puts e_time - s_time cli.close
サーバ側
require 'msgpack/rpc' require 'net/http' class CDBServer def initialize @http = Net::HTTP.new("localhost", 5984) end # 同期GET def get(path = nil) path ||= '/' cdb_get(path) end # 非同期GET def async_get(path = nil) path ||= '/' as = MessagePack::RPC::AsyncResult.new # スレッドに処理を任せてオブジェクトを返す Thread.new do as.result(cdb_get(path)) end as end private def cdb_get(path) req = Net::HTTP::Get.new(path) ret = nil @http.start do |w| response = w.request(req) ret = response.body end # あえて1秒待たせる sleep 1 ret end end # 5000番ポートでlisten svr = MessagePack::RPC::Server.new svr.listen("0.0.0.0", 5000, CDBServer.new) # シグナルをキャッチしたら終了 Signal.trap(:TERM) { svr.stop } Signal.trap(:INT) { svr.stop } svr.run
結果
同期 | 非同期 | |
---|---|---|
1回目 | 100.216915 | 10.783514 |
2回目 | 100.21936 | 10.781574 |
3回目 | 100.223581 | 10.777062 |
GETで1秒のsleepを入れてるので、
同期で100回叩けばほぼ100秒なのは当然として、
さすが非同期だと速いですね・・・