Basho Riakが遅すぎる件について
NoSQLの中でも,耐障害性・無単一障害点などの点から本命だと思っていたRiakなんですが,RESTなAPIでベンチマークを取ってみると,とてつもなく遅いことが分かって困っています.
5年前のノートPCを使ったのでハードが余りにも貧弱という可能性はあるのですが,とりあえず結果だけ残そうと思います.
ベンチマークプログラムは,ライブラリPOCOを使ったソケット通信をやる感じで,
Riak用は次のような感じです.
// HTTP module version // g++45 riak_bench2.cc -o riak_bench2 -I/usr/local/include -L/usr/local/lib -lPocoFoundation -lPocoNet -g -fopenmp -Wall #include "basic_header.h" int main(int argc, char *argv[]) { int suc = 0, i; time_t start, set_end, get_end; int n = omp_get_max_threads(); vector<Poco::Net::HTTPClientSession *> pool(n); Poco::Net::SocketAddress server("192.0.0.1", 8098); for(vector<Poco::Net::HTTPClientSession *>::iterator i=pool.begin(); i!=pool.end();++i){ *i = new Poco::Net::HTTPClientSession(server); (*i)->setKeepAlive(true); } start = time(NULL); #pragma omp parallel for shared(suc,i) for(i=0;i<MAX_LOOP;++i) { Poco::Net::HTTPClientSession *client=pool.at((int)(i/(MAX_LOOP/n))); Poco::MD5Engine con; string key, val; size_t sent_len, recv_len; set_key_val(con, (int)(i/REP), key, val); char write_buffer[BUFFER_SIZE], read_buffer[BUFFER_SIZE]; snprintf(write_buffer, BUFFER_SIZE, "/riak/test/%s",key.c_str()); Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_PUT, write_buffer, Poco::Net::HTTPMessage::HTTP_1_1); Poco::Net::HTTPResponse res; req.setHost(client->getHost(), client->getPort()); req.setContentLength(val.size()); req.setContentType("text/plain"); std::ostream &requestStream = client->sendRequest(req); requestStream<<val; std::istream & responseStream = client->receiveResponse(res); if (res.getStatus() != Poco::Net::HTTPResponse::HTTP_OK && res.getStatus() != Poco::Net::HTTPResponse::HTTP_NO_CONTENT) { fprintf(stderr, "set: %s: riak error %s\n", key.c_str(), res.getReason().c_str()); }else { ++suc; } } set_end = time(NULL); #pragma omp parallel for shared(suc, i) for(i=0;i<MAX_LOOP;++i){ Poco::Net::HTTPClientSession *client=pool.at((int)(i/(MAX_LOOP/n))); Poco::MD5Engine con; string key, val; int sent_len, recv_len; set_key_val(con, (int)(i/REP), key, val); char read_buffer[BUFFER_SIZE]; std::string write_buffer; char confirm_buffer[BUFFER_SIZE]; write_buffer = "/riak/test/"+key+"?r=1"; Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, write_buffer, Poco::Net::HTTPMessage::HTTP_1_1); Poco::Net::HTTPResponse res; req.setHost(client->getHost(), client->getPort()); req.add("Accept","*/*"); req.add("User-Agent","Firefox9.0"); std::ostream &requestStream = client->sendRequest(req); std::istream &responseStream = client->receiveResponse(res); size_t total_len = val.size(); recv_len = res.getContentLength(); std::ostringstream readBuffer; Poco::StreamCopier::copyStream(responseStream, readBuffer); if(recv_len!=0){ if(recv_len == val.size()) { if (val != readBuffer.str()) { printf("get: %s(%d bytes): riak error: %s(%d bytes)\n", val.c_str(),val.size(), readBuffer.str().c_str(),readBuffer.str().size()); }else { ++suc; } }else { cout<<"receive length["<<recv_len<<"] != expected length["<<val.size()<<"]"<<endl; } }else { cout<<"response size="<<recv_len<<endl; } } #include "basic_footer.h" return(0); }
stringsクラスやchar*をいろいろ使っていることは特に意味はありません.色々変化させても同じでした.
確かに,Riakは同時アクセス数が増えるとどんどん速くなっています.しかし,RiakのRESTインターフェースは読み込みが書き込みの5倍から10倍遅い,ましてやRedisと比べると,読み書きが1スレッドの場合,1000倍もRiakが遅い...
それでもRiakのサイト
http://wiki.basho.com/
では強気の発言がありますし,似たプロダクトを評価したサイトの翻訳サイト
へ〜たのめも:Riak と Cassandra と HBase、あらまー! - livedoor Blog(ブログ)
を見ても,評価は高いようなので,引き続き調べてみようかと思います.