SSDB

SSDB 是一个 C/C++ 语言开发的高性能 NoSQL 数据库, 支持 zset(sorted set), map(hash), kv, list 等数据结构, 用来替代或者与 Redis 配合存储十亿级别的列表数据. SSDB 同时也被国内外业界的众多互联网企业所使用, 如 QIHU 360, TOPGAME, 汽车之家, 比亚迪等.

项目主页: https://github.com/ideawu/ssdb
SSDB 文档: http://ssdb.io/docs/zh_cn/
谁在用 SSDB: http://ssdb.io/docs/zh_cn/users.html
官方QQ群: 170983373

2014开源中国开源世界高峰论坛, 中国开源优秀项目奖项目

SSDB 的主要特点:

  • 支持 zset, map/hash, list, kv 数据结构, 可替代 Redis
  • 特别适合存储大量集合数据, 支持丰富的数据结构: key-value, key-map, key-zset, key-list.
  • 使用 Google LevelDB 作为存储引擎
  • 支持主从同步, 多主同步
  • 客户端支持 PHP, C++, Python, Lua, Java, Ruby, nodejs, Go 等
  • 内存占用极少
  • 图形化界面管理工具(phpssdbadmin)

PHP API

<?php
require_once('SSDB.php');
$ssdb = new SimpleSSDB('127.0.0.1', 8888);
$resp = $ssdb->set('key', '123');
$resp = $ssdb->get('key');
echo $resp; // output: 123

PHP API 文档: http://ssdb.io/docs/zh_cn/php/

SSDB vs Redis

SSDB vs Redis

SSDB 架构

Views: 157866

433 Responses to "SSDB"

  • ssdb的网络协议是否考虑扩展一下?增加一个无符号整形作为位图存储的flag,get时一起返回。可以让client开发者设置一些标识用于在处理时提高性能,如val是否经过了压缩?val的类型?像memcached通信协议一样。 Reply
    @notime8888: 是否可以考虑 multi_set, multi_get 呢? 一次处理两个 key, 其中一个是 val, 另一个是 meta. Reply
    @ideawu: 上述方案对性能还是有影响的。而且本身的mset和mget,存储的空间直接double了。没关系,只是提提建议。ssdb本身已经很棒了 Reply
    @ideawu: 是个办法,谢谢ideawu。还有一个问题,如果直接把一个整形转换成字节存入rocksdb,那么incr方法是不起作用的。测试发现只能把字符串类型的数字存入才可以incr,这和rocksdb本身的存储方式有关吧? Reply
    @notime8888: 是的, incr 只能操作字符串形式的整数, 这是 ssdb 做的限制, 不是 rocksdb 或者 leveldb 的限制. Reply
  • SSDB在调用leveldb.put时,WriteOptions是什么,是每一条变更同步刷新到磁盘还是由系统合并写入 Reply
    @xtjsxtj: 或者在SSDB中能设置这个选项吗 Reply
  • 楼主开发的应用,配置文件都很有性格,喜欢用tab来格式化。 Reply
    @deeka: 必须滴, 不认同的同学可以把键盘上的TAB键扣掉. 哈哈. Reply
  • Hi,你好:
    由于对ssdb不是很了解,对于文档上说的有关备份方面不是很理解,还请帮忙解答,主要有一下几点:
    1.备份用在线备份ssdb-dump备份时,会比原来数据小,这个程序是怎么进行处理的?
    2. 备份直接把原来的目录全部拷贝,是否可以行?用不用把服务停掉?
    3.现在有没有好一点备份的方法?现在用ssdb-dump备份时非常慢(100M左右)。

    还请帮忙解答一下,谢谢。 Reply
    @alan: Hi,

    1. 这个不影响, dump 时会把一些过期的数据从硬盘清除.
    2. 要先停服务再拷贝目录
    3. 你可以在 ssdb-cli 执行 compact 命令. Reply
  • 为什么我看到的ssdb-bench里面的std::map<std::string, Data *>::iterator it = ds->begin();这个it从来不++啊,这样不每次循环都是同一个key? Reply
    @cultdust: 谢谢反馈, 已经 fix. Reply
  • 请教博主,我在做测试的时候,随机插入了200w的数据,然后采用zrange和 zrrange 的性能差距挺大的,我想知道是不是我配置错误了?是不是有可以优化的地方?

    另外,zrange的排序方式是可配置的吗?

    ssdb 127.0.0.1:8888> zrange feed:event:set 0 0
    key score
    ————————-
    0 result(s) (0.031 sec)
    ssdb 127.0.0.1:8888> zrrange feed:event:set 0 0
    key score
    ————————-
    0 result(s) (0.476 sec) Reply
    @Gz: 测试数据生成完毕后, 在 ssdb-cli 执行一次 compact 命令. Reply
  • hi,libssdb github上有一个pull request,麻烦看下是否可以接受。
    hdel一个不存在的key返回0,而不是返回-1。 Reply
  • PHP API接口里 如果出错则返回 false。 假如返回结果是false,能不能获取到出错的信息? Reply
    @Vink: 用 $ssdb->last_resp 看看. Reply
    @ideawu: 看了下PHP的接口 貌似没有类似redis中lrem的方法? 那怎么从队列中移除一个值? Reply
    @Vink: 已经加入了 qtrim_front, qtrim_back 命令! Reply
    @Vink: 目前只有 qpop_front, qpop_back, 可以一次弹出多个元素. qtrim_front 和 qtrim_back 即将加上. Reply
    @ideawu: ssdb-dump支持密码选项吗? 为什么按 ssdb-dump host port -p output_folder 和 ssdb-dump host port -p password output_folder 都是输出 output_folder[-p] exists! 呢? 但是实际上output_folder对应的目录并不存在 Reply
    @Vink: ssdb-dump host port output_folder 没有 -p 选项
  • ideawu,你好。ssdb接口中是否可以考虑提供批量删除功能,例如指定key范围则删除对应所有数据,这样避免多次调用接口,方便且更高效。在实际业务中还是有很多这样的需求。 Reply
    @wyt: 你好, 我个需求我也看到了. 麻烦你到 github 提一个 issue, 多谢! Reply
    @ideawu: scan和rscan对于海量key的范围检索性能如何?有相关测试吗?如果没有的话,可以提供算法复杂度的参考吗?

    我这里有一个按照日期作为KEY存储的需求,大约10亿条数据,年增量10亿,每条数据平均4K,需要用时间范围检索,不知道SSDB性能和扩展性如何。 Reply
    @ideawu: ok Reply
  • 配置了3主模式,用简单的set命令,发现master3和其他亮点数据不同步。操作序列如下:
    master1> set a 10
    master3> get a
    10
    master3> set a 20
    master1> get a
    10

    ########## master1.conf

    # ssdb-server config

    # relative to path of this file, must exist
    work_dir = ./
    pidfile = ./ssdb.pid

    server:
    ip: 127.0.0.1
    port: 8001

    replication:
    binlog: yes
    # Limit sync speed to *MB/s, -1: no limit
    sync_speed: -1
    slaveof:
    # to identify a master even if it moved(ip, port changed)
    # if set to empty or not defined, ip:port will be used.
    id: svc_2
    # sync|mirror, default is sync
    type: mirror
    ip: 127.0.0.1
    port: 8002
    id: svc_3
    # sync|mirror, default is sync
    type: mirror
    ip: 127.0.0.1
    port: 8003


    logger:
    level: debug
    # level: info
    output: ./log/log.txt
    rotate:
    size: 1000000000

    leveldb:
    # in MB
    cache_size: 500
    # in KB
    block_size: 32
    # in MB
    write_buffer_size: 64
    # in MB
    compaction_speed: 200
    # yes|no
    compression: no


    ########## master2.conf

    # ssdb-server config

    # relative to path of this file, must exist
    work_dir = ./
    pidfile = ./ssdb.pid

    server:
    ip: 127.0.0.1
    port: 8002

    replication:
    binlog: yes
    # Limit sync speed to *MB/s, -1: no limit
    sync_speed: -1
    slaveof:
    # to identify a master even if it moved(ip, port changed)
    # if set to empty or not defined, ip:port will be used.
    id: svc_1
    # sync|mirror, default is sync
    type: mirror
    ip: 127.0.0.1
    port: 8001
    id: svc_3
    type: mirror
    ip: 127.0.0.1
    port: 8003



    logger:
    level: debug
    # level: info
    output: ./log/log.txt
    rotate:
    size: 1000000000

    leveldb:
    # in MB
    cache_size: 500
    # in KB
    block_size: 32
    # in MB
    write_buffer_size: 64
    # in MB
    compaction_speed: 200
    # yes|no
    compression: no


    ########## master3.conf

    # ssdb-server config

    # relative to path of this file, must exist
    work_dir = ./
    pidfile = ./ssdb.pid

    server:
    ip: 127.0.0.1
    port: 8003

    replication:
    binlog: yes
    # Limit sync speed to *MB/s, -1: no limit
    sync_speed: -1
    slaveof:
    # to identify a master even if it moved(ip, port changed)
    # if set to empty or not defined, ip:port will be used.
    id: svc_1
    # sync|mirror, default is sync
    type: mirror
    ip: 127.0.0.1
    port: 8001
    id: svc_2
    type: mirror
    ip: 127.0.0.1
    port: 8002



    logger:
    level: debug
    # level: info
    output: ./log/log.txt
    rotate:
    size: 1000000000

    leveldb:
    # in MB
    cache_size: 500
    # in KB
    block_size: 32
    # in MB
    write_buffer_size: 64
    # in MB
    compaction_speed: 200
    # yes|no
    compression: no


    请教这是怎么回事? Reply
    @jiang: 你好, 配置有问题, 应该是多个 slaveof. Reply

« [7][8][9][10][11][12][13][14][15] » 11/19

Leave a Comment