ssdbssdb 连接池的口令在哪里配置

发布一个参考ssdb,用go实现的类似redis的高性能nosql:ledisdb - 推酷
发布一个参考ssdb,用go实现的类似redis的高性能nosql:ledisdb
是一个参考ssdb,采用go实现,底层基于leveldb,类似redis的高性能nosql数据库,提供了kv,list,hash以及zset数据结构的支持。
我们现在的应用极大的依赖redis,但随着我们用户量越来越大,redis的内存越来越不够用,并且replication可能还会导致超时问题。虽然后续我们可以通过添加多台机器来解决,但是在现有机器配置下面,我们仍希望单台机器承载更多的用户。另外,因为业务的特性,我们其实并不需要将所有的数据放到内存,只需要存放当前活跃用户。
经过我们的调研,发现ssdb已经很好的帮我们解决了这个问题,它提供了跟redis一致的接口(当然有些地方还是稍微不同),但是底层采用leveldb进行存储。根据其官网的描述,性能已经接近甚至超越了redis。
本着造轮子的精神,我决定用go实现一个类似的db,取名为ledisdb,也就是
level-redis-db
,为啥不用现成的ssdb,我觉得有如下几个原因:
go语言开发的快速,这点毋庸置疑,虽然性能上面铁定离c++的代码有差距,但是我能够快速的进行原型搭建并实验。实际上,我在很短的时间里面就开发出了ledisdb,让我后续继续开发有了信心。
leveldb的研究,我一直很想将leveldb应用到我们的项目中,作为本机热点数据的首选数据存储方式,通过ledisdb,让我对leveldb的使用有了很多经验。
redis的熟悉,虽然我用了很久的redis,但是很多redis的命令仍然需要去查手册,通过实现ledisdb,我更加熟悉了redis的命令,同时,因为要了解这个命令redis如何实现,对redis内部又重新来了一次剖析。
在准备开发ledisdb的时候,我就在思索一个问题,我需不需要开发另一个redis?其实这是一个很明确的问题,我不需要另一个redis。ledisdb虽然参考了redis,但为了实现简单,有时候我做了很多减法或者变更,譬如对于zset这种数据结构,我就只支持int64类型的score,而redis的score是double类型的,具体原因后续讲解zset的时候详细说明。
所以,我们可以认为,ledisdb是一个基于redis通信协议,提供了多种高级数据结构的nosql数据库,它并不是另一个redis。
因为ledisdb是用go写的,所以首先需要安装go以及配置GOROOT,GOPATH。
mkdir $WORKSPACE
cd $WORKSPACE
git clone :siddontang/ledisdb.git /siddontang/ledisdb
cd /siddontang/ledisdb
#构建leveldb,如果已经安装了,可忽略
./build_leveldb.sh
#安装ledisdb go依赖
. ./bootstap.sh
#配置GOPATH等环境变量
. ./dev.sh
go install ./...
具体的安装说明,可以查看代码目录下面的readme。
使用ledisdb很简单,只需要运行:
./ledis-server -config=/etc/ledis.json
ledisdb的配置文件采用json格式,为啥选用json,我在
里面有过说明。
我们可以使用任何redis客户端连接ledisdb,譬如redis-cli,如下:
127.0.0.1:6380& set a 1
127.0.0.1:6380& get a
127.0.0.1:6380& incr a
(integer) 2
127.0.0.1:6380& mset b 2 c 3
127.0.0.1:6380& mget a b c
因为leveldb是c++写的,所以在go里面需要使用,cgo是一种很好的方式。这里,我直接使用了
这个库,并在上面进行了封装,详见这里。虽然有一个go-leveldb,无奈仍不能用。
cgo的性能开销还是有的,这点在我做benchmark的时候就明显感觉出来,不过后续优化的空间很大,譬如将多个leveldb的调用逻辑该用c重写,这样只需要一次cgo就可以了。不过这个后续在考虑。
leveldb的一些参数在构建编译的时候是需要调整的,这点我没啥经验,只能google和参考ssdb。譬如下面这几个:
+ db/dbformat.h
// static const int kL0_SlowdownWritesTrigger = 8;
static const int kL0_SlowdownWritesTrigger = 16;
// static const int kL0_StopWritesTrigger = 12;
static const int kL0_StopWritesTrigger = 64;
+ db/version_set.cc
//static const int kTargetFileSize = 2 * 1048576;
static const int kTargetFileSize = 32 * 1048576;
//static const int64_t kMaxGrandParentOverlapBytes = 10 * kTargetFileS
static const int64_t kMaxGrandParentOverlapBytes = 20 * kTargetFileS
相关参数的调优,只能等我后续深入研究leveldb了在好好考虑。
任何一个服务端服务没有性能测试报告那就是耍流氓,我现在只是简单的用了redis_benchmark进行测试,测试环境为一台快两年的老爷mac air机器。
测试语句:
redis-benchmark -n 10000 -t set,incr,get,lpush,lpop,lrange,mset -q
redis-benchmark默认没有hash以及zset的测试,后续我在自己加入。
leveldb配置:
compression
block_size
write_buffer_size = 64MB
cache_size
SET: 42735.04 requests per second
GET: 45871.56 requests per second
INCR: 45248.87 requests per second
LPUSH: 45045.04 requests per second
LPOP: 43103.45 requests per second
LPUSH (needed to benchmark LRANGE): 44843.05 requests per second
LRANGE_100 (first 100 elements): 14727.54 requests per second
LRANGE_300 (first 300 elements): 6915.63 requests per second
LRANGE_500 (first 450 elements): 5042.86 requests per second
LRANGE_600 (first 600 elements): 3960.40 requests per second
MSET (10 keys): 33003.30 requests per second
SET: 35971.22 requests per second
GET: 47393.37 requests per second
INCR: 36630.04 requests per second
LPUSH: 37174.72 requests per second
LPOP: 38167.94 requests per second
LPUSH (needed to benchmark LRANGE): 37593.98 requests per second
LRANGE_100 (first 100 elements): 905.55 requests per second
LRANGE_300 (first 300 elements): 327.78 requests per second
LRANGE_500 (first 450 elements): 222.36 requests per second
LRANGE_600 (first 600 elements): 165.30 requests per second
MSET (10 keys): 33112.59 requests per second
SET: 38759.69 requests per second
GET: 40160.64 requests per second
INCR: 36101.08 requests per second
LPUSH: 33003.30 requests per second
LPOP: 27624.31 requests per second
LPUSH (needed to benchmark LRANGE): 32894.74 requests per second
LRANGE_100 (first 100 elements): 7352.94 requests per second
LRANGE_300 (first 300 elements): 2867.79 requests per second
LRANGE_500 (first 450 elements): 1778.41 requests per second
LRANGE_600 (first 600 elements): 1590.33 requests per second
MSET (10 keys): 21881.84 requests per second
可以看到,ledisdb的性能赶redis以及ssdb还是有差距的,但也不至于不可用,有些差别并不大。至于为啥lrange比ssdb高,我比较困惑。
后续的测试报告,我会不断在benchmark文件里面更新。
Todo。。。。。。
还是一个非常新的项目,比起ssdb已经在生产环境中用了很久,还有很多路要走,还有一些重要的功能需要实现,譬如replication等。
欢迎有兴趣的童鞋一起参与进来,在漫漫程序开发路上有一些好基友可是很幸运的。
已发表评论数()
&&登&&&录&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见SSDB100安装方案大熊猫生态园农迁房项目2、3、5、6号楼_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
SSDB100安装方案大熊猫生态园农迁房项目2、3、5、6号楼
上传于||文档简介
&&S​S​D​B0安​装​方​案​:​上​传​人​姚​波
阅读已结束,如果下载本文需要使用
想免费下载本文?
下载文档到电脑,查找使用更方便
还剩22页未读,继续阅读
你可能喜欢3055人阅读
起因是一个参考ssdb,采用go实现,底层基于leveldb,类似redis的高性能nosql数据库,提供了kv,list,hash以及zset数据结构的支持。我们现在的应用极大的依赖redis,但随着我们用户量越来越大,redis的内存越来越不够用,并且replication可能还会导致超时问题。虽然后续我们可以通过添加多台机器来解决,但是在现有机器配置下面,我们仍希望单台机器承载更多的用户。另外,因为业务的特性,我们其实并不需要将所有的数据放到内存,只需要存放当前活跃用户。经过我们的调研,发现ssdb已经很好的帮我们解决了这个问题,它提供了跟redis一致的接口(当然有些地方还是稍微不同),但是底层采用leveldb进行存储。根据其官网的描述,性能已经接近甚至超越了redis。本着的精神,我决定用go实现一个类似的db,取名为ledisdb,也就是level-redis-db,为啥不用现成的ssdb,我觉得有如下几个原因:go语言开发的快速,这点毋庸置疑,虽然性能上面铁定离c++的代码有差距,但是我能够快速的进行原型搭建并实验。实际上,我在很短的时间里面就开发出了ledisdb,让我后续继续开发有了信心。leveldb的研究,我一直很想将leveldb应用到我们的项目中,作为本机热点数据的首选数据存储方式,通过ledisdb,让我对leveldb的使用有了很多经验。redis的熟悉,虽然我用了很久的redis,但是很多redis的命令仍然需要去查手册,通过实现ledisdb,我更加熟悉了redis的命令,同时,因为要了解这个命令redis如何实现,对redis内部又重新来了一次剖析。在准备开发ledisdb的时候,我就在思索一个问题,我需不需要开发另一个redis?其实这是一个很明确的问题,我不需要另一个redis。ledisdb虽然参考了redis,但为了实现简单,有时候我做了很多减法或者变更,譬如对于zset这种数据结构,我就只支持int64类型的score,而redis的score是double类型的,具体原因后续讲解zset的时候详细说明。所以,我们可以认为,ledisdb是一个基于redis通信协议,提供了多种高级数据结构的nosql数据库,它并不是另一个redis。编译安装因为ledisdb是用go写的,所以首先需要安装go以及配置GOROOT,GOPATH。mkdir $WORKSPACE
cd $WORKSPACE
git clone :siddontang/ledisdb.git /siddontang/ledisdb
cd /siddontang/ledisdb
#构建leveldb,如果已经安装了,可忽略
./build_leveldb.sh
#安装ledisdb go依赖
. ./bootstap.sh
#配置GOPATH等环境变量
. ./dev.sh
go install ./...
具体的安装说明,可以查看代码目录下面的readme。Example使用ledisdb很简单,只需要运行:./ledis-server -config=/etc/ledis.json
ledisdb的配置文件采用json格式,为啥选用json,我在里面有过说明。我们可以使用任何redis客户端连接ledisdb,譬如redis-cli,如下:127.0.0.1:6380& set a 1
127.0.0.1:6380& get a
127.0.0.1:6380& incr a
(integer) 2
127.0.0.1:6380& mset b 2 c 3
127.0.0.1:6380& mget a b c
leveldb因为leveldb是c++写的,所以在go里面需要使用,cgo是一种很好的方式。这里,我直接使用了这个库,并在上面进行了封装,详见。虽然有一个go-leveldb,无奈仍不能用。cgo的性能开销还是有的,这点在我做benchmark的时候就明显感觉出来,不过后续优化的空间很大,譬如将多个leveldb的调用逻辑该用c重写,这样只需要一次cgo就可以了。不过这个后续在考虑。leveldb的一些参数在构建编译的时候是需要调整的,这点我没啥经验,只能google和参考ssdb。譬如下面这几个:+ db/dbformat.h
// static const int kL0_SlowdownWritesTrigger = 8;
static const int kL0_SlowdownWritesTrigger = 16;
// static const int kL0_StopWritesTrigger = 12;
static const int kL0_StopWritesTrigger = 64;
+ db/version_set.cc
//static const int kTargetFileSize = 2 * 1048576;
static const int kTargetFileSize = 32 * 1048576;
//static const int64_t kMaxGrandParentOverlapBytes = 10 * kTargetFileS
static const int64_t kMaxGrandParentOverlapBytes = 20 * kTargetFileS
相关参数的调优,只能等我后续深入研究leveldb了在好好考虑。性能测试任何一个服务端服务没有性能测试报告那就是耍流氓,我现在只是简单的用了redis_benchmark进行测试,测试环境为一台快两年的老爷mac air机器。测试语句:redis-benchmark -n 10000 -t set,incr,get,lpush,lpop,lrange,mset -q
redis-benchmark默认没有hash以及zset的测试,后续我在自己加入。leveldb配置:compression
block_size
write_buffer_size = 64MB
cache_size
redisSET: 42735.04 requests per second
GET: 45871.56 requests per second
INCR: 45248.87 requests per second
LPUSH: 45045.04 requests per second
LPOP: 43103.45 requests per second
LPUSH (needed to benchmark LRANGE): 44843.05 requests per second
LRANGE_100 (first 100 elements): 14727.54 requests per second
LRANGE_300 (first 300 elements): 6915.63 requests per second
LRANGE_500 (first 450 elements): 5042.86 requests per second
LRANGE_600 (first 600 elements): 3960.40 requests per second
MSET (10 keys): 33003.30 requests per second
ssdbSET: 35971.22 requests per second
GET: 47393.37 requests per second
INCR: 36630.04 requests per second
LPUSH: 37174.72 requests per second
LPOP: 38167.94 requests per second
LPUSH (needed to benchmark LRANGE): 37593.98 requests per second
LRANGE_100 (first 100 elements): 905.55 requests per second
LRANGE_300 (first 300 elements): 327.78 requests per second
LRANGE_500 (first 450 elements): 222.36 requests per second
LRANGE_600 (first 600 elements): 165.30 requests per second
MSET (10 keys): 33112.59 requests per second
ledisdbSET: 38759.69 requests per second
GET: 40160.64 requests per second
INCR: 36101.08 requests per second
LPUSH: 33003.30 requests per second
LPOP: 27624.31 requests per second
LPUSH (needed to benchmark LRANGE): 32894.74 requests per second
LRANGE_100 (first 100 elements): 7352.94 requests per second
LRANGE_300 (first 300 elements): 2867.79 requests per second
LRANGE_500 (first 450 elements): 1778.41 requests per second
LRANGE_600 (first 600 elements): 1590.33 requests per second
MSET (10 keys): 21881.84 requests per second
可以看到,ledisdb的性能赶redis以及ssdb还是有差距的,但也不至于不可用,有些差别并不大。至于为啥lrange比ssdb高,我比较困惑。后续的测试报告,我会不断在benchmark文件里面更新。Todo。。。。。。还是一个非常新的项目,比起ssdb已经在生产环境中用了很久,还有很多路要走,还有一些重要的功能需要实现,譬如replication等。欢迎有兴趣的童鞋一起参与进来,在漫漫程序开发路上有一些好基友可是很幸运的。
版权声明:本文为博主原创文章,未经博主允许不得转载。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:164354次
积分:2379
积分:2379
排名:第8582名
原创:52篇
评论:53条
文章:25篇
阅读:53428
(2)(5)(4)(10)(9)(2)(8)(6)(1)(5)(2)(2)(1)(1)(1)(1)(2)(1)(1)(1)(2)(2)(2)(2)ssdb&命令说明
et:说明:设置指定
cmd:set('key', 'value');
setx:说明:设置指定
同时设置存活时间.
cmd:setx('key', 'value', 60); 单位:秒
setnx:说明:当
如果已存在,
cmd:setnx('key', 'value');
get:说明:获取指定
cmd:get('key');
getset:说明:更新
并返回更新前的旧的
cmd:getset('key', 'value');
del:说明:删除指定的
cmd:$ssdb-&del('key');
incr:说明:使
对应的值增加
可以为负数.
如果原来的值不是
整数(字符串形式的整数),
它会被先转换成整数.
cmd:incr('key', 1);
exists:说明:判断指定的
cmd:exists('key');
keys:说明:列出处于区间
(key_start,
key_end] 的
""] 表示整个区间.
最多返回这么多元素
cmd:keys('a', 'z',
scan:说明:列出处于区间
(key_start,
key_end] 的
""] 表示整个
limit 最多返回这么多元素
cmd:scan('a', 'z',
rscan:说明:列出处于区间
(key_start,
key_end] 的
反向顺序.("",
表示整个区间.
cmd:rscan('a', 'z', 10);
multi_set:说明:批量设置一批
key-value.
cmd:multi_set(new
Object[]{"key1","value1","key2","value2"});
multi_get:说明:批量获取一批
对应的值内容.
cmd:multi_get(array('k1', 'k2'));
multi_del:说明:批量删除一批
和其对应的值内容.
cmd:multi_del(array('k1', 'k2'));
hset:说明:设置
对应的值内容.
cmd:hset('h', 'key', 'value');
hget:说明:获取
cmd:hget('h', 'key');
hdel:说明:获取
cmd:hdel('h', 'key');
hincr:说明:使
对应的值增加
可以为负数.
果原来的值不是整数(字符串形式的整数),
它会被先转换成整数.
cmd:hincr('h', 'key', 1);
hexists:说明:判断指定的
是否存在于
cmd:hexists('h', 'key');
hsize:说明:返回
中的元素个数.
cmd:hsize('h');
hlist:说明:列出名字处于区间
(name_start,
name_end] 的
hashmap.("",
""] 表示整
cmd:$ssdb-&hlist('a', 'z', 10);
hkeys:说明:列出
中处于区间
(key_start,
key_end] 的
示整个区间.
cmd:hkeys('h', 'a', 'z', 10);
hgetall:说明:返回整个
cmd:hgetall('h');
hscan:说明:列出
中处于区间
(key_start,
key_end] 的
表示整个区间.
cmd:hscan('h', 'a', 'z', 10);
hrscan:说明:列出
中处于区间
(key_start,
key_end] 的
向顺序.("",
""] 表示整个区间.
cmd:hrscan('h', 'a', 'z', 10);
hclear:说明:删除
cmd:hclear('h');
multi_hset:说明:批量设置
key-value.
cmd:multi_zset('z', array('a' =& 1,'b' =& 2));
multi_hget:说明:批量获取
对应的权重值.
cmd:multi_hget('h', array('k1', 'k2'));
multi_hdel:说明:指删除
cmd:multi_hdel('h', array('k1', 'k2'));
zset:说明:设置
对应的权重值.
cmd:zset('z', 'key', 100);
zget:说明:获取
cmd:zget('z', 'key');
zdel:说明:获取
cmd:zdel('hz, 'key');
zincr:说明:使
对应的值增加
可以为负数.
来的值不是整数(字符串形式的整数),
它会被先转换成整数.
cmd:zincr('z', 'key', 1);
zexists:说明:判断指定的
是否存在于
cmd:zexists('z', 'key');
zsize:说明:返回
中的元素个数.
cmd:zsize('z');
zlist:说明:列出名字处于区间
(name_start,
name_end] 的
""] 表示整个区
cmd:zlist('a', 'z', 10);
zkeys:说明:列出
中处于区间
(key_start+score_start,
score_end] 的
那么对应权重值大于或者等于
score_start
那么对应权重值大于
score_start
且对应权重值等于
score_start
将被返回.也就是说,
(key.score ==
score_start && key & key_start || key.score &
score_start) 区间.("",
""] 表示整个区间.
cmd:zkeys('z', '',
1, 100, 10); zscan:
- zset 的名字.key_start
zkeys().score_start
zkeys().score_end
zkeys().limit
- 最多返回这么
cmd:zscan('z', '',
1, 100, 10); zrscan:
cmd:zrscan('a',
'z', 10); zrank, zrrank:
说明:注意!
本方法可能会非常慢!
请在离线环境中使用.返回指定
中的排序位置(排名),
zrrank 获取是是倒序排名.
cmd:zrank('z',
'k1'); zrange, zrrange:
说明:注意!
越来越大时,
会越慢!根据下标索引区间
[offset, offset +
limit) 获取
zrrange 是反向顺序获取.
cmd:zrange('z', 0,
10); zclear:
cmd:zclear('z');
说明:返回处于区间
[start,end]
cmd:zcount('z', 0,
100); zsum:
[start,end]
cmd:zsum('z', 0,
100); zavg:
[start,end]
cmd:zavg('z', 0,
100); zremrangebyrank:
说明:删除位置处于区间
[start,end]
cmd:zremrangebyrank('z',
1, 2); zremrangebyscore:
说明:删除权重处于区间
[start,end]
cmd:zremrangebyscore('z',
1, 2); multi_zset:
说明:批量设置
key-score.
cmd:multi_zset('z',
array('a' =& 1,'b' =& 2,)); multi_zget:
说明:批量获取
对应的权重值.
cmd:multi_zget('z',
array('k1', 'k2')); multi_zdel:
说明:指删除
cmd:multi_zdel('z',
array('k1', 'k2')); qsize:
说明:返回队列的长度.
cmd:qsize('q');
说明:清空一个队列.
cmd:qclear('q');
说明:返回队列的第一个元素.
cmd:qfront('q');
说明:返回队列的最后一个元素.
cmd:qback('q');
说明:返回指定位置的元素.
0 表示第一个元素,
1 是第二个
-1 是最后一个.
cmd:qget('q', -2);
说明:返回下标处于区域
end] 的元素.
可以是负数
cmd:qslice('q', 0,
-1); qpush:
说明:本函数是
qpush_back()
qpush_front:
说明:往队列的首部添加一个或者多个元素
cmd:qpush_front('q',
'a'); qpush_back:
说明:往队列的尾部添加一个或者多个元素
cmd:qpush_back('q',
'a'); qpop:
说明:本函数是
qpop_front()
qpop_front:
说明:删除并返回队列的第一个元素.
cmd:qpop_front('q');
qpop_back:
说明:删除并返回队列的最后一个元素.
cmd:qpop_back('q');
exec:说明:批量执行一批命令.
批量命令可以减少客户端和服务器之间的交互延时,
能提高性能和响应速度.
cmd: $ssdb-&batch()-&set('a',
1)-&get('a')-&exec();// 或 者
$ssdb-&batch();$ssdb-&set('a',
1);$ssdb-&get('a');$ssdb-&exec();&
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 ssdb 连接不上 的文章

 

随机推荐