首页 > NoSQL > 用Kyoto Tycoon挂载LevelDB存储(转)

用Kyoto Tycoon挂载LevelDB存储(转)

2013年5月9日

Kyoto Tycoon(以下简称KT)是TokyoTyrant的作者Mikio Hirabayashi 的系列作品之一,KT 是一个数据库网络层服务,它提供一个插件机制,可以挂载几乎所有的数据库存储设备。之前已经有过KT嫁接Memcached 的案例。

本文要讲的是最近Google开源的持久化key-value存储系统LevelDB ,性能相当不错。Mikio刚刚在KT最新版本上实现了对LevelDB 的挂载程序。下面是具体安装过程:
1.安装LevelDB
先获取源代码
$ svn checkout http://leveldb.googlecode.com/svn/trunk/ leveldb-read-only
修改Makefile,加上-fPIC选项
+CFLAGS = -c -I. -I./include $(PLATFORM_CFLAGS) $(OPT)
-CFLAGS = -c -I. -I./include $(PLATFORM_CFLAGS) $(OPT) -fPIC
如果你用的是Ubuntu,那么再修改port/port_posix.h文件:
+#include
-#include
上面几处修改完后,开始安装
$ make
$ sudo cp libleveldb.a /usr/local/lib
$ sudo cp -r include/leveldb /usr/local/include
这样LevelDB就安装完了
2.在KC上挂载式安装LevelDB
下载最新的KC源代码,运行下面命令进行安装
$ cd kyototycoon-x.y.z
$ ./configure
$ make
$ sudo make install
$ cd lab/leveldb
$ make
$ sudo cp ktplugdblevel.so /usr/local/lib
安装完成后就可以运行了
$ ktserver -pldb /usr/local/lib/ktplugdblevel.so casket.ldb
你可以直接挂靠一些Set操作
$ ktremotemgr set japan tokyo
$ ktremotemgr set korea seoul
$ ktremotemgr set china beijing
查看刚刚Set进去的数据:
$ ktremotemgr list -pv
3.插件实现
下面附上一份挂接LevelDB的源码,其逻辑也非常简单:
class LevelDB : public kt::PluggableDB {

bool accept_impl(const char* kbuf, size_t ksiz, Visitor* visitor, bool writable) {
size_t lidx = kc::hashmurmur(kbuf, ksiz) % RLOCKSLOT;
if (writable) {
rlock_.lock_writer(lidx);
} else {
rlock_.lock_reader(lidx);
}
std::string key(kbuf, ksiz);
std::string value;
lv::Status status = db_->Get(lv::ReadOptions(), key, &value);
const char* rbuf;
size_t rsiz;
if (status.ok()) {
rbuf = visitor->visit_full(kbuf, ksiz, value.data(), value.size(), &rsiz);
} else {
rbuf = visitor->visit_empty(kbuf, ksiz, &rsiz);
}
bool err = false;
if (rbuf == kc::BasicDB::Visitor::REMOVE) {
lv::WriteOptions wopts;
if (autosync_) wopts.sync = true;
status = db_->Delete(wopts, key);
if (!status.ok()) {
set_error(_KCCODELINE_, Error::SYSTEM, “DB::Delete failed”);
err = true;
}
} else if (rbuf != kc::BasicDB::Visitor::NOP) {
lv::WriteOptions wopts;
if (autosync_) wopts.sync = true;
std::string rvalue(rbuf, rsiz);
status = db_->Put(wopts, key, rvalue);
if (!status.ok()) {
set_error(_KCCODELINE_, Error::SYSTEM, “DB::Put failed”);
err = true;
}
}
rlock_.unlock(lidx);
return !err;
}

}

http://fallabs.com/blog/promenade.cgi?id=30

分类: NoSQL 标签:
本文的评论功能被关闭了.