lushan - 基于 Memcache 的 key-value 数据库


BSD
跨平台
C/C++

软件简介

lushan 是一个基于 Memcache 协议的 key-value 数据库, 可以动态挂载多个库, 用来进行静态数据的存储,
适用于存储更新频次较低的数据. 可以作为redis的有效补充, 以节省昂贵的内存服务器成本, lushan不像redis那样需要将数据完全存在内存中,
而是结合使用内存和硬盘, 内存只用来存储索引文件, 硬盘则用来存储真正的数据文件. 另外在写入时不能像redis那样实时写入,
而是通过加载离线的静态数据文件完成(例如用MapReduce生成的数据)

lushan的每个库由数据文件和索引文件组成, 数据文件命名为dat, 索引文件命名为idx, 目录命名为hdict_xxxxxxxxxxx,
后面是时间编号. 索引文件由一个个key-pos对组成. 其中key就是key-value结构中需要查询的key, 而pos则包含两部分信息,
它的前40位表示value在dat文件中的偏离值off, 后20位表示value的长度length,
通过off和length来共同定位dat文件中的value

关于lushan的实现原理可以参考微博推荐博客的这篇博文: http://www.wbrecom.com/?p=453

使用方法

源码编译

依赖的第三方源码包

  • libevent1.4

步骤

  1. git clone https://github.com/wbrecom/lushan.git

  2. 创建lushan编译环境

    SOURCE_DIR=/tmp/lushan_environment/
    

    mkdir ”$SOURCE_DIR”

  3. 复制lushan项目源码到lushan编译环境目录

    cp -r lushan "$SOURCE_DIR"
    
  4. 编译libevent

    cd "$SOURCE_DIR"lushan/depend/libevent-1.4.14b-stable
    

    ./configure –prefix=”$SOURCE_DIR”libevent
    make && make install

  5. 编译lushan

    cd "$SOURCE_DIR"lushan/src
    

    修改common.mk, 将LIBEVENT_HOME的值修改为刚才安装libevent的目录

    LIBEVENT_DIR=”$SOURCE_DIR”libevent
    sed -i “s#LIBEVENT_HOME.*#LIBEVENT_HOME = $LIBEVENT_DIR#g” common.mk
    make

部署lushan

  1. 创建lushan部署环境

    SOURCE_DIR=/tmp/lushan_environment/
    

    DEPLOY_DIR=/tmp/lushan_deploy/
    mkdir -p $DEPLOY_DIR

  2. 创建bin conf hdb logs upload目录

    cp -r "$SOURCE_DIR"lushan/bin $DEPLOY_DIRcp -r "$SOURCE_DIR"lushan/conf $DEPLOY_DIRcp -r "$SOURCE_DIR"lushan/hdb $DEPLOY_DIRcp -r "$SOURCE_DIR"lushan/logs $DEPLOY_DIRcp -r "$SOURCE_DIR"lushan/upload $DEPLOY_DIR
    
  3. 替换编译好的lushan程序

    cp "$SOURCE_DIR"lushan/src/hyper_dict "$DEPLOY_DIR"bin
    
  4. 修改lushan.conf配置文件

    HDB_DIR="$DEPLOY_DIR"hdb
    

    sed -i “s#HDB_PATH=.#HDB_PATH=$HDB_DIR#g” ”$DEPLOY_DIR”conf/hyper_dict.conf
    UPLOAD_DIR=”$DEPLOY_DIR”upload
    sed -i “s#UPLOAD_PATH=.
    #UPLOAD_PATH=$UPLOAD_DIR#g” ”$DEPLOY_DIR”conf/hyper_dict.conf

  5. 挂载数据

将含有数据文件的目录复制到hdb目录下(数据文件目录命名为hdict_$datetime)

该目录包含choic.flg done.flg dat idx这4个文件

    cp -r hdict_20150820131415 "$DEPLOY_DIR"hdb/1
  1. 启动lushan

    bash "$DEPLOY_DIR"bin/hyper_dict.sh
    
  2. 补充: 动态挂载数据

将含有数据文件的目录复制到upload目录下(数据文件目录命名为hdict_$datetime)

该目录包含done.flg dat idx这3个文件

    cp -r hdict_20150820142244 "$DEPLOY_DIR"upload/2
touch "$DEPLOY_DIR"upload/2/hdict_20150820142244/done.flg

访问示例

启动后即可通过stats命令查看lushan状态

echo -ne "stats\r\n" | nc 127.0.0.1 9999

查询某个key的value(get dbnum-key)

echo -ne "get 1-123456\r\n" | nc 127.0.0.1 9999

生成数据

生成符合lushan格式的数据有两种方法

脚本转化

0. 有一个原始的数据文件dat, 每行都是key-value结构, 用:分隔, key必须为整数
1. 通过tools/generate_idx.py脚本生成索引文件
2. 如果数据文件的key是无序的, 可使用index_sort程序对索引文件排序
3. 新建hditc_xxxxxxxxx目录, 将idx文件和dat文件放到该目录下

MapReduce直接生成

如果是在hadoop上用MapReduce直接生成数据, 则需要使用tools/LushanFileOutputFormat.java,
指定MapReudce的输出格式类为LushanFileOutputFormat

job.setOutputFormat(LushanFileOutputFormat.class)

支持命令

  • info

查看库是否挂载成功, 显示每个库的信息, 打开时间, 当前处理的请求量, 库里面有多少条记录

  • stats

查看lushan本身的状态, 主要是通信部分的信息(例如: 当前等待处理队列里有多少请求, 有多少请求在等待队列里超时了). 这些信息,
有利于知道服务是否稳定, 是否性能满足要求

  • randomkey

随机取得一个key

  • get

取得一个或多个key的value

  • open reopen

动态挂载库

  • stats reset(慎用)

重置lushan统计信息

  • close

关闭客户端连接