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(ブログ)
を見ても,評価は高いようなので,引き続き調べてみようかと思います.