libmemcache を使ってみる
会社でちと memcached を使ってみるかってことになりまして、その C のクライアントの libmemcache を使って簡単に実装をしてみました。
手元のノート PC に入れてる coLinux、Linux debian 2.6.17-co-0.8.0 #1 PREEMPT Sun Jul 8 14:00:12 CEST 2007 i686 GNU/Linux で試しました。
つうわけで、まずは必要なライブラリをインストール。
-
[maihara@debian:~] $ aptitude search libmemcache
-
p libmemcache-dev - development headers for libmemcache C client API
-
p libmemcache0 - C client API for memcached memory object caching system
-
[maihara@debian:~] $ sudo aptitude install libmemcache-dev
-
[maihara@debian:~] $ dpkg -L libmemcache-dev
-
/.
-
/usr
-
/usr/lib
-
/usr/lib/libmemcache.a
-
/usr/lib/libmemcache.la
-
/usr/include
-
/usr/include/memcache.h
-
/usr/include/memcache
-
/usr/include/memcache/buffer.h
-
/usr/include/memcache/_buffer.h
-
/usr/share
-
/usr/share/doc
-
/usr/share/doc/libmemcache-dev
-
/usr/share/doc/libmemcache-dev/changelog.Debian.gz
-
/usr/share/doc/libmemcache-dev/copyright
-
/usr/share/doc/libmemcache-dev/changelog.gz
-
/usr/lib/libmemcache.so
で、こんな感じのソース、mcclient.cc を書いてみました。
-
#include <iostream>
-
#include <string>
-
#include <map>
-
-
#include <memcache.h>
-
-
using namespace std;
-
-
class memcacheWrapper {
-
public:
-
memcacheWrapper() {
-
_mc = mc_new();
-
}
-
-
~memcacheWrapper() {
-
mc_free(_mc);
-
}
-
-
struct memcache* _mc;
-
};
-
-
class memcacheReqWrapper {
-
public:
-
memcacheReqWrapper() {
-
_mcr = mc_req_new();
-
}
-
-
~memcacheReqWrapper() {
-
mc_req_free(_mcr);
-
}
-
-
struct memcache_req* _mcr;
-
};
-
-
int main(int argc, char* argv[]) {
-
// 初期化
-
memcacheWrapper mr;
-
int ret = mc_server_add4(mr._mc, "127.0.0.1:11211");
-
if (ret != MCM_ERR_NONE) {
-
cerr <<"mc_server_add4 failed" <<endl;
-
exit(1);
-
}
-
ret = mc_server_add4(mr._mc, "127.0.0.1:11212");
-
if (ret != MCM_ERR_NONE) {
-
cerr <<"mc_server_add4 failed" <<endl;
-
exit(1);
-
}
-
-
// 適当に値追加
-
map<string, string> m;
-
string k1 = "0123";
-
string v1 = "forever";
-
string k2 = "4567";
-
string v2= "5years";
-
string k3 = "89ab";
-
string v3= "old";
-
string k4 = "cdef";
-
string v4= "net";
-
m.insert(make_pair(k1, v1));
-
m.insert(make_pair(k2, v2));
-
m.insert(make_pair(k3, v3));
-
m.insert(make_pair(k4, v4));
-
for (map<string, string>::const_iterator cit = m.begin();
-
cit != m.end();
-
++cit) {
-
ret = mc_set(mr._mc,
-
const_cast<char*>(cit->first.c_str()),
-
k1.length(),
-
const_cast<char*>(cit->second.c_str()),
-
v1.length(),
-
6000,
-
MCM_RES_FREE_ON_DELETE);
-
if (ret != MCM_ERR_NONE) {
-
cerr <<"mc_set failed: " <<cit->first <<" : " <<cit->second <<endl;
-
exit(1);
-
}
-
}
-
-
// 値を取得してみる
-
memcacheReqWrapper mrw;
-
memcache_res* res1 = mc_req_add(mrw._mcr, const_cast<char*>(k1.c_str()), k2.length());
-
memcache_res* res2 = mc_req_add(mrw._mcr, const_cast<char*>(k2.c_str()), k2.length());
-
memcache_res* res3 = mc_req_add(mrw._mcr, const_cast<char*>(k3.c_str()), k3.length());
-
memcache_res* res4 = mc_req_add(mrw._mcr, const_cast<char*>(k4.c_str()), k4.length());
-
mc_get(mr._mc, mrw._mcr);
-
cerr <<res1->key <<" : " <<static_cast<char*>(res1->val) <<endl;
-
cerr <<res2->key <<" : " <<static_cast<char*>(res2->val) <<endl;
-
cerr <<res3->key <<" : " <<static_cast<char*>(res3->val) <<endl;
-
cerr <<res4->key <<" : " <<static_cast<char*>(res4->val) <<endl;
-
-
// 統計情報を取得する
-
struct memcache_server_stats* s = mc_stats(mr._mc);
-
cerr <<s->get_hits <<endl;
-
cerr <<s->total_items <<endl;
-
mc_server_stats_free(s);
-
-
return 0;
-
}
で、コンパイルして実行してみますと、
-
[maihara@debian:~/work] $ g++ -lmemcache -o mcclient mcclient.cc
-
[maihara@debian:~/work] $ ./mcclient
-
[NOTICE@1186032723.409892] mcm_server_connect():2302: Software caused connection abort
-
[NOTICE@1186032723.410127] mcm_server_connect_next_avail():2333: Software caused connection abort
-
[WARN@1186032723.410197] mcm_server_connect_next_avail():2338
-
mc_add failed
ハイ。memcached 自体を上げてないので当たり前。インストールしてデーモン上げます。
-
[maihara@debian:~/work] $ aptitude search memcached
-
[maihara@debian:~/work] $ sudo aptitude install memcached
-
[maihara@debian:~/work] $ sudo /etc/init.d/memcached stop
-
[maihara@debian:~/work] $ sudo /usr/bin/memcached -m 64 -p 11211 -u root &
-
[maihara@debian:~/work] $ sudo /usr/bin/memcached -m 64 -p 11212 -u root &
-
[maihara@debian:~/work] $ ps alwwx | grep memcached
-
4 0 5130 4686 21 5 5924 4736 epoll_ SN pts/0 0:00 /usr/bin/memcached -m 64 -p 11211 -u root
-
4 0 5131 4686 22 5 5920 4736 epoll_ SN pts/0 0:00 /usr/bin/memcached -m 64 -p 11212 -u root
-
0 1000 5133 4686 15 0 2784 752 pipe_w S+ pts/0 0:00 grep memcached
で、mcclient 再実行。
-
[maihara@debian:~/work] $ ./mcclient [1556 9:52午後]
-
0123 : forever
-
4567 : 5years
-
89ab : old
-
cdef : net
-
4
-
4
下の 2 行は統計情報の出力です。set して get するだけですが、とりあえず動きました。
で、ここまでは良かったんですが、set し続けるプログラムを作って走らせている間に、memcached を 1 つ kill したりすると、
-
[ERROR@1186044634.069779] mcm_buf_read():361: read(2) failed: Operation now in progress: server unexpectedly closed connection
つって怒られて exit しちゃう現象に遭遇。Python extension for libmemcache の Known Bugs と同じですわ。アガガ。
というわけで、パッチ作ったるワイと今日 1 日を潰すことになるのですが、それはこの続き、「libmemcache のパッチを作ってみる」に書きます。
フー。久しぶりにプログラムの話がでけました。

No comments
Jump to comment form | comments rss [?] | trackback uri [?]