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
git clone https://github.com/wbrecom/lushan.git
创建lushan编译环境
SOURCE_DIR=/tmp/lushan_environment/ mkdir "$SOURCE_DIR"
复制lushan项目源码到lushan编译环境目录
cp -r lushan "$SOURCE_DIR"
编译libevent
cd "$SOURCE_DIR"lushan/depend/libevent-1.4.14b-stable ./configure --prefix="$SOURCE_DIR"libevent make && make install
编译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部署环境
SOURCE_DIR=/tmp/lushan_environment/ DEPLOY_DIR=/tmp/lushan_deploy/ mkdir -p $DEPLOY_DIR
创建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
替换编译好的lushan程序
cp "$SOURCE_DIR"lushan/src/hyper_dict "$DEPLOY_DIR"bin
修改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
挂载数据
将含有数据文件的目录复制到hdb目录下(数据文件目录命名为hdict_$datetime)
该目录包含choic.flg done.flg dat idx这4个文件
cp -r hdict_20150820131415 "$DEPLOY_DIR"hdb/1
启动lushan
bash "$DEPLOY_DIR"bin/hyper_dict.sh
补充: 动态挂载数据
将含有数据文件的目录复制到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文件放到该目录下
如果是在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
关闭客户端连接
数据库类型 dbm.gnu dbm.ndbm dbm.dumb 创建一个新的数据库 # dbm_new.py import dbm with dbm.open('/tmp/example.db', 'n') as db: db['key'] = 'value' db['today'] = 'Sunday' db['author'] = 'Doug' # dbm_whic
Adds or retrieves given value associated with given key. (Don’t confuse with data- attributes) See also Element.removeData Parameters keystringkey to store data valueanyvalue to store Returns: objectE
设置元素属性。需要注意的是,应该始终调用该方法来修改属性,而不是直接 element.xxx = ... 这样的形式,因为后者不会重绘物体。 参数 名称 类型 默认值 描述 key string|Object 设置的属性。可以是 string 类型的属性名称,或者 Object 类型的属性及其值。 value * 属性值。 例子 element.attr('position', [100, 200
在很多情况下,日志内容本身都是一个类似于 key-value 的格式,但是格式具体的样式却是多种多样的。logstash 提供 filters/kv 插件,帮助处理不同样式的 key-value 日志,变成实际的 LogStash::Event 数据。 配置示例 filter { ruby { init => "@kname = ['method','uri','verb'
Orient Key/Value Server 是一个基于文档数据库技术的 Key/Value 存储服务器,提供 Java 的 API 和基于 HTTP 的 RESTful 访问,支持集群。
问题内容: 在php中,可以使用以下关联数组处理状态名称及其缩写的列表: 输出(保留键顺序): 编辑:请注意,数组元素的顺序保留在php版本的输出中。使用HashMap的Java实现不能保证元素的顺序。Python中的字典也没有。 如何在Java和python中完成?我只找到给定键的提供值的方法,例如python的方法: 编辑:基于答案,这是我在python中的解决方案, 输出: 这正是所需要的。