通过mapkeeper把自己的数据库和YCSB连接

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/clever_wr/article/details/89027717

首先要保证mapkeeper可以在ycsb上被load和run,在前面的博文中我写了具体的操作方法。

在把数据库和自己的数据库相连时候,首先要保证自己的机器的环境中有boost和thrift。同时保证mapkeeper文件夹中对应的thrift已经编译成功。

那么什么是thrift呢?这里给出维基百科的解释:

       Thrift包含一套完整的栈来创建客户端和服务端程序。顶层部分是由Thrift定义生成的代码。而服务则由这个文件客户端和处理器代码生成。在生成的代码里会创建不同于内建类型的数据结构,并将其作为结果发送。协议和传输层运行时库的一部分。有了Thrift,就可以定义一个服务或改变通讯和传输协议,而无需重新编译代码。除了客户端部分之外,Thrift还包括服务器基础设施来集成协议和传输,如阻塞、非阻塞及多线程服务器。栈中作为I/O基础的部分对于不同的语言则有不同的实现。

Thrift支持众多通讯协议:

  • TBinaryProtocol – 一种简单的二进制格式,简单,但没有为空间效率而优化。比文本协议处理起来更快,但更难于调试。
  • TCompactProtocol – 更紧凑的二进制格式,处理起来通常同样高效。
  • TDebugProtocol – 一种人类可读的文本格式,用来协助调试。
  • TDenseProtocol – 与TCompactProtocol类似,将传输数据的元信息剥离。
  • TJSONProtocol – 使用JSON对数据编码。
  • TSimpleJSONProtocol – 一种只写协议,它不能被Thrift解析,因为它使用JSON时丢弃了元数据。适合用脚本语言来解析。

下面开始连接自己数据库的准备工作:

1.在mapkeeper中添加一个新的自己数据库的文件夹

mkdir newdb/

2.在newdb文件夹中新建一个Makefile文件

vi Makefile

3.Makefile文件中添加以下内容

include ../Makefile.config
EXECUTABLE = mapkeeper_RHDB
all : thrift
	g++ -Wall -o $(EXECUTABLE) *cpp -I $(THRIFT_DIR)/include/thrift -I $(THRIFT_DIR)/include \
        /usr/local/lib/libsnappy.a -lboost_thread -lboost_filesystem -lthrift -I ../thrift/gen-cpp \
	-L $(THRIFT_DIR)/lib  \
        -L ../thrift/gen-cpp -lmapkeeper \
           -Wl,-rpath,\$$ORIGIN/../thrift/gen-cpp	\
           -Wl,-rpath,$(THRIFT_DIR)/lib \
	-std=c++11

thrift:
	make -C ../thrift

run:
	./$(EXECUTABLE) 1 0 0

clean :
	- rm -rf $(THRIFT_SRC) $(EXECUTABLE) *.o 

wipe:
	- rm -rf data/*

4.下面开始新建一个server接口用于连接自己的数据库。

/**
 * This is a implementation of the mapkeeper interface that uses newdb
 */
#include <cstdio>
#include "MapKeeper.h"
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/thread/shared_mutex.hpp>
#include <boost/filesystem.hpp>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <protocol/TBinaryProtocol.h>
#include <server/TThreadedServer.h>
#include <transport/TServerSocket.h>
#include <transport/TBufferTransports.h>
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using namespace ::apache::thrift::concurrency;
using boost::shared_ptr;
using namespace boost::filesystem;
using namespace mapkeeper;

int syncmode;
int blindinsert;
int blindupdate;
class newdbServer: virtual public MapKeeperIf {
public:
newdbServer(const std::string& directoryName) :
   directoryName_(directoryName) {
   // open all the existing databases
}

    ResponseCode::type ping() {
        return ResponseCode::Success;
    }

    ResponseCode::type addMap(const std::string& mapName) {
        return ResponseCode::Success;
    }

    ResponseCode::type dropMap(const std::string& mapName) {
    }

    void listMaps(StringListResponse& _return) {
        DIR *dp;
        struct dirent *dirp;
        if((dp  = opendir(directoryName_.c_str())) == NULL) {
            _return.responseCode = ResponseCode::Success;
            return;
        }

        while ((dirp = readdir(dp)) != NULL) {
            _return.values.push_back(std::string(dirp->d_name));
        }
        closedir(dp);
        _return.responseCode = ResponseCode::Success;
    }

    void scan(RecordListResponse& _return, const std::string& mapName, const ScanOrder::type order,
              const std::string& startKey, const bool startKeyIncluded,
              const std::string& endKey, const bool endKeyIncluded,
              const int32_t maxRecords, const int32_t maxBytes) {
    }

    void scanAscending(RecordListResponse& _return, std::map<std::string, std::string>& map,
              const std::string& startKey, const bool startKeyIncluded,
              const std::string& endKey, const bool endKeyIncluded,
              const int32_t maxRecords, const int32_t maxBytes) {
        _return.responseCode = ResponseCode::ScanEnded;
    }

    void scanDescending(RecordListResponse& _return, std::map<std::string, std::string>& map,
              const std::string& startKey, const bool startKeyIncluded,
              const std::string& endKey, const bool endKeyIncluded,
              const int32_t maxRecords, const int32_t maxBytes) {
        _return.responseCode = ResponseCode::ScanEnded;
    }

    void get(BinaryResponse& _return, const std::string& mapName, const std::string& key) {
        _return.responseCode = ResponseCode::Success;
    }

    ResponseCode::type put(const std::string& mapName, const std::string& key, const std::string& value) {
        std::string mapName_ = mapName;
        return ResponseCode::Success;
    }

    ResponseCode::type insert(const std::string& mapName, const std::string& key, const std::string& value) {
        // TODO Get and Put should be within a same transaction
        return ResponseCode::Success;
    }

    ResponseCode::type update(const std::string& mapName, const std::string& key, const std::string& value) {
        // TODO Get and Put should be within a same transaction
        return ResponseCode::Success;
    }

    ResponseCode::type remove(const std::string& mapName, const std::string& key) {
        return ResponseCode::Success;
    }

private:
    std::string directoryName_; // directory to store db files.
    boost::shared_mutex mutex_; // protect map_
};

int main(int argc, char **argv) {
    if(argc != 4) { printf("Usage: %s <sync:0 or 1> <blindinsert:0 or 1> <blindupdate:0 or 1>\n", argv[0]); }
    syncmode    = atoi(argv[1]);
    blindinsert = atoi(argv[2]);
    blindupdate = atoi(argv[3]);
    int port = 9090;
    std::shared_ptr<newdbServer> handler(new newdbBServer("data"));
    std::shared_ptr<TProcessor> processor(new MapKeeperProcessor(handler));
    std::shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
    std::shared_ptr<TTransportFactory> transportFactory(new TFramedTransportFactory());
    std::shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
    TThreadedServer server (processor, serverTransport, transportFactory, protocolFactory);
    server.serve();
    return 0;
}

5.判断新建的接口是否可以连接成功(和leveldb连接方式类似):

./mapkeeper_newdb 1 -d ~/mapkeeper/newdb/data

6.之后只要把自己的接口加进newdbserver中就可以啦。。真的搞了好久额,好难额。

猜你喜欢

转载自blog.csdn.net/clever_wr/article/details/89027717