Home  >  Article  >  Database  >  SSDB Redis替代品

SSDB Redis替代品

WBOY
WBOYOriginal
2016-06-07 16:36:571713browse

SSDB是一个快速的用来存储十亿级别列表数据的开源 NoSQL 数据库。项目地址:https://github.com/ideawu/ssdbhttp://ssdb.io/ 特性 替代 Redis 数据库, Redis 的 100 倍容量 LevelDB 网络支持, 使用 C/C++ 开发 Redis API 兼容, 支持 Redis 客户端 适合存储集

SSDB是一个快速的用来存储十亿级别列表数据的开源 NoSQL 数据库。 项目地址:https://github.com/ideawu/ssdb http://ssdb.io/

特性

  • 替代 Redis 数据库, Redis 的 100 倍容量
  • LevelDB 网络支持, 使用 C/C++ 开发
  • Redis API 兼容, 支持 Redis 客户端
  • 适合存储集合数据, 如 list, hash, zset...
  • 客户端 API 支持的语言包括: C++、PHP、Python、Cpy、Java、NodeJS、Ruby、Go。
  • 持久化的队列服务
  • 主从复制, 负载均衡

性能

1000请求:
writeseq  :    0.546 ms/op      178.7 MB/s
writerand :    0.519 ms/op      188.1 MB/s
readseq   :    0.304 ms/op      321.6 MB/s
readrand  :    0.310 ms/op      315.0 MB/s
并发:
========== set ==========
qps: 44251, time: 0.226 s
========== get ==========
qps: 55541, time: 0.180 s
========== del ==========
qps: 46080, time: 0.217 s
========== hset ==========
qps: 42338, time: 0.236 s
========== hget ==========
qps: 55601, time: 0.180 s
========== hdel ==========
qps: 46529, time: 0.215 s
========== zset ==========
qps: 37381, time: 0.268 s
========== zget ==========
qps: 41455, time: 0.241 s
========== zdel ==========
qps: 38792, time: 0.258 s
在MacBook Pro 13 (Retina屏幕)上运行。 与redis的比较: 性能数据使用 ssdb-bench(SSDB) 和 redis-benchmark(Redis) 来获取。 ssdb-1

架构

ssdb-2

安装

下载压缩包,解压缩
wget --no-check-certificate https://github.com/ideawu/ssdb/archive/master.zip
unzip master
cd ssdb-master
编译
make
安装(可选)
sudo make install
运行
./ssdb-server ssdb.conf
或者以后台的方式运行
./ssdb-server -d ssdb.conf
ssdb命令行
./tools/ssdb-cli -p 8888
停止ssdb-server
kill `cat ./var/ssdb.pid`

使用

PHP

<?php include_once('SSDB.php');
try{
    $ssdb = new SimpleSSDB('127.0.0.1', 8888);
}catch(Exception $e){
    die(__LINE__ . ' ' . $e->getMessage());
}
$ret = $ssdb->set('key', 'value');
if($ret === false){
    // error!
}
echo $ssdb->get('key');

Python

使用pyssdb
>>> import pyssdb
>>> c = pyssdb.Client()
>>> c.set('key', 'value')
1
>>> c.get('key')
'value'
>>> c.hset('hash', 'item', 'value')
1
>>> c.hget('hash', 'item')
'value'
>>> c.hget('hash', 'not exist') is None
True
>>> c.incr('counter')
1
>>> c.incr('counter')
2
>>> c.incr('counter')
3
>>> c.keys('a', 'z', 1)
['counter']
>>> c.keys('a', 'z', 10)
['counter', 'key']

Ruby

使用ssdb-rb
require "ssdb"
ssdb = SSDB.new url: "ssdb://1.2.3.4:8889"
ssdb.set("mykey", "hello world")
# => true
ssdb.get("mykey")
# => "hello world"
ssdb.batch do
  ssdb.set "foo", "5"
  ssdb.get "foo"
  ssdb.incr "foo"
end
# => [true, "5", 6]

Go

package main
import (
        "fmt"
        "os"
        "./ssdb"
       )
func main(){
    ip := "127.0.0.1";
    port := 8888;
    db, err := ssdb.Connect(ip, port);
    if(err != nil){
        os.Exit(1);
    }
    var val interface{};
    db.Set("a", "xxx");
    val, err = db.Get("a");
    fmt.Printf("%s\n", val);
    db.Del("a");
    val, err = db.Get("a");
    fmt.Printf("%s\n", val);
    db.Do("zset", "z", "a", 3);
    db.Do("multi_zset", "z", "b", -2, "c", 5, "d", 3);
    resp, err := db.Do("zrange", "z", 0, 10);
    if err != nil{
        os.Exit(1);
    }
    if len(resp) % 2 != 1{
        fmt.Printf("bad response");
        os.Exit(1);
    }
    fmt.Printf("Status: %s\n", resp[0]);
    for i:=1; i<len i fmt.printf : resp return>
<h3>ngx_lua</h3>
使用<code style="color: #c7254e;">lua-resty-ssdb</code>
<pre class="brush:php;toolbar:false">lua_package_path "/path/to/lua-resty-ssdb/lib/?.lua;;";
server {
    location /test {
        content_by_lua '
            local ssdb = require "resty.ssdb"
            local db = ssdb:new()
            db:set_timeout(1000) -- 1 sec
            local ok, err = db:connect("127.0.0.1", 8888)
            if not ok then
                ngx.say("failed to connect: ", err)
                return
            end
            ok, err = db:set("dog", "an animal")
            if not ok then
                ngx.say("failed to set dog: ", err)
                return
            end
            ngx.say("set result: ", ok)
            local res, err = db:get("dog")
            if not res then
                ngx.say("failed to get dog: ", err)
                return
            end
            if res == ngx.null then
                ngx.say("dog not found.")
                return
            end
            ngx.say("dog: ", res)
            db:init_pipeline()
            db:set("cat", "Marry")
            db:set("horse", "Bob")
            db:get("cat")
            db:get("horse")
            local results, err = db:commit_pipeline()
            if not results then
                ngx.say("failed to commit the pipelined requests: ", err)
                return
            end
            for i, res in ipairs(results) do
                if type(res) == "table" then
                    if not res[1] then
                        ngx.say("failed to run command ", i, ": ", res[2])
                    else
                        -- process the table value
                    end
                else
                    -- process the scalar value
                end
            end
            -- put it into the connection pool of size 100,
            -- with 0 idle timeout
            local ok, err = db:set_keepalive(0, 100)
            if not ok then
                ngx.say("failed to set keepalive: ", err)
                return
            end
            -- or just close the connection right away:
            -- local ok, err = db:close()
            -- if not ok then
            --     ngx.say("failed to close: ", err)
            --     return
            -- end
        ';
    }
}

C++

#include 
#include 
#include 
#include 
#include "SSDB.h"
int main(int argc, char **argv){
    const char *ip = (argc >= 2)? argv[1] : "127.0.0.1";
    int port = (argc >= 3)? atoi(argv[2]) : 8888;
    ssdb::Client *client = ssdb::Client::connect(ip, port);
    if(client == NULL){
        printf("fail to connect to server!\n");
        return 0;
    }
    ssdb::Status s;
    s = client->set("k", "hello ssdb!");
    if(s.ok()){
        printf("k = hello ssdb!\n");
    }else{
        printf("error!\n");
    }
    delete client;
    return 0;
}
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn