起因

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 git@github.com:siddontang/ledisdb.git src/github.com/siddontang/ledisdb cd src/github.com/siddontang/ledisdb #构建leveldb。假设已经安装了,可忽略
./build_leveldb.sh #安装ledisdb go依赖
. ./bootstap.sh #配置GOPATH等环境变量
. ./dev.sh go install ./...

详细的安装说明,能够查看代码文件夹以下的readme。

Example

使用ledisdb非常easy。仅仅须要执行:

./ledis-server -config=/etc/ledis.json

ledisdb的配置文件採用json格式。为啥选用json。我在使用json作为基本的配置格式里面有过说明。

我们能够使用不论什么redisclient连接ledisdb,譬如redis-cli,例如以下:

127.0.0.1:6380> set a 1
OK
127.0.0.1:6380> get a
"1"
127.0.0.1:6380> incr a
(integer) 2
127.0.0.1:6380> mset b 2 c 3
OK
127.0.0.1:6380> mget a b c
1) "2"
2) "2"
3) "3"

leveldb

由于leveldb是c++写的,所以在go里面须要使用,cgo是一种非常好的方式。

这里,我直接使用了levigo这个库。并在上面进行了封装。详见这里。尽管有一个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 * kTargetFileSize;
static const int64_t kMaxGrandParentOverlapBytes = 20 * kTargetFileSize;

相关參数的调优,仅仅能等我兴许深入研究leveldb了在好好考虑。

性能測试

不论什么一个服务端服务没有性能測试报告那就是耍流氓。我如今仅仅是简单的用了redis_benchmark进行測试,測试环境为一台快两年的老爷mac air机器。

測试语句:

redis-benchmark -n 10000 -t set,incr,get,lpush,lpop,lrange,mset -q

redis-benchmark默认没有hash以及zset的測试。兴许我在自己加入。

leveldb配置:

compression       = false
block_size = 32KB
write_buffer_size = 64MB
cache_size = 500MB

redis

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

ssdb

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

ledisdb

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。。

。。

ledisdb还是一个非常新的项目,比起ssdb已经在生产环境中用了非常久,还有非常多路要走,还有一些重要的功能须要实现,譬如replication等。

欢迎有兴趣的童鞋一起參与进来,在漫漫程序开发路上有一些好基友可是非常幸运的。

版权声明:本文博主原创文章,博客,未经同意不得转载。

发布一个参考ssdb,使用go类似的实现redis高性能nosql:ledisdb的更多相关文章

  1. 发布一个参考ssdb,用go实现的类似redis的高性能nosql:ledisdb

    起因 ledisdb是一个参考ssdb,采用go实现,底层基于leveldb,类似redis的高性能nosql数据库,提供了kv,list,hash以及zset数据结构的支持. 我们现在的应用极大的依 ...

  2. 发布一个参考tornado的高性能c++网络库:libtnet

    libtnet是一个用c++编写的高性能网络库,它在设计上面主要参考tornado,为服务端网络编程提供简洁而高效的接口,非常易于使用. Echo Server void onConnEvent(co ...

  3. 教你一步步发布一个开源库到 JCenter

    今天想来分享下,如何一步步自己发布一个开源库到 JCenter 这方面的博客网上已经特别多了,所以本篇并不打算仅仅只是记录流程步骤而已,而是尽可能讲清楚,为什么需要有这个步骤,让大伙知其然的同时还知其 ...

  4. npm 发布一个全局的指令

    我们经常使用 npm i  -g  xxxx 安装完成一个包之后,就能直接使用对应的指令.例如安装  vue-cli 或者 express 等 那么下面我们自己做一个类似的效果: 首先要对 npm 发 ...

  5. 【转】发布一个基于NGUI编写的UI框架

    发布一个基于NGUI编写的UI框架 1.加载,显示,隐藏,关闭页面,根据标示获得相应界面实例 2.提供界面显示隐藏动画接口 3.单独界面层级,Collider,背景管理 4.根据存储的导航信息完成界面 ...

  6. 如何发布一个自定义Node.js模块到NPM(详细步骤)

    咱们闲话不多说,直接开始! 由于我从没有使用过MAC,所以我不保证本文中介绍的操作与MAC一致. 文章开始我先假定各位已经在window全局安装了Node.js,下面开始进行详细步骤介绍: 本文本着, ...

  7. 利用VS2008发布一个简单的webservice

    一个开发好的webservice,怎样发布出去,供其他电脑访问呢? 本文将介绍如何发布一个简单的webservice,其中的内容都是在网上查看别人文章,自己仿照着做了一遍,因此,难免会发生错误,如果发 ...

  8. nuget服务器搭建,以及如何发布一个Nuget包

    本文章主要介绍如何将本地dll打包成为一个Nuget包,并如何发布到自己的nuget服务器.章节如下 1. 本地dll如何打包,以及版本的更新 2. 在linux上搭建nuget.server 3. ...

  9. 如何发布一个npm包(基于vue)

    前言:工作的时候总是使用别人的npm包,然而我有时心底会好奇自己如何发布一个npm包呢,什么时候自己的包能够被很多人喜欢并使用呢...今天我终于迈出了第一步. 前提:会使用 npm,有 vue 基础, ...

随机推荐

  1. C++11:强类型枚举(enum)

    // C++11之前的enum类型是继承C的,不温不火: // C++11对enum动刀了,加强了类型检查,推出强类型enum类型,眼前一亮 // 使用过QT 的都知道,早就应该这么做了,用的非常爽! ...

  2. OpenJDK 阅读源代码 Java 实现字节流输入类

    Java 的输入输出总是给人一种非常混乱的感觉.要想把这个问题搞清楚.必须对各种与输入输出相关的类之间的关系有所了解. 仅仅有你了解了他们之间的关系.知道设计这个类的目的是什么.才干更从容的使用他们. ...

  3. 微信电脑版(Mac和Windows)安装

    内容简介 1.微信Windows版 2.微信Mac版 3.总结优势 微信电脑版 众所周知,腾讯公司(马化腾先生执掌的巨头公司)开发的超成功App:微信.一经推出便引发业界轰动,使用人数更是直逼QQ. ...

  4. [LeetCode217]Contains Duplicate

    题目:Given an array of integers, find if the array contains any duplicates. Your function should retur ...

  5. flask+gevent+gunicorn+nginx 初试

    1.安装flask pip install flask 2.安装gevent pip install gevent 3.安装gunicorn pip install gunicorn 版本信息例如以下 ...

  6. 探索Windows Azure 监控和自动伸缩系列2 - 获取虚拟机的监控定义和监控数据

    上一篇博文介绍了如何连接Windows Azure: http://www.cnblogs.com/teld/p/5113063.html 本篇我们继续上次的示例代码,获取虚拟机的监控定义和监控数据. ...

  7. 【Android基础】点击Back键退出应用程序

    //第一种方法(弹出对话框) @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-genera ...

  8. POJ 2226 Muddy Fields(最小顶点覆盖)

    POJ 2226 Muddy Fields 题目链接 题意:给定一个图,要求用纸片去覆盖'*'的位置.纸片能够重叠.可是不能放到'.'的位置,为最少须要几个纸片 思路:二分图匹配求最小点覆盖.和放车那 ...

  9. 通过配置Windows 防火墙允许使用TCP/IP协议远程访问数据库

    原文:通过配置Windows 防火墙允许使用TCP/IP协议远程访问数据库 本文适用于:2005.2008.2008R2所有版本 为了可以通过TCP/IP协议远程访问SQLServer数据库,需要做以 ...

  10. 正确lua简单的扩展,可以加速相关C++数据。

    很早的时候,我有一件事纠结.如果,我在这里C++打开界面脚本.使用C++其中一个目标,和.我的程序有很多不同的lua虚拟机.每个虚拟机与一个关联C++对象,它是多线程,那么如何快速应利用这个好时机lu ...