SSDB - A fast NoSQL database for storing big list of data

Posted 麦田里的守望者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SSDB - A fast NoSQL database for storing big list of data相关的知识,希望对你有一定的参考价值。

SSDB is a high performace key-value(key-string, key-zset, key-hashmap) NoSQL database, an alternative to Redis. SSDB is stable, production-ready and is widely used by many Internet companies including QIHU 360. SSDB 是一个 C/C++ 语言开发的高性能 NoSQL 数据库, 支持 KV, list, map(hash), zset(sorted set) 等数据结构, 用来替代或者与 Redis 配合存储十亿级别列表的数据.SSDB 是稳定的, 生产环境使用的, 已经在许多互联网公司得到广泛使用, 如奇虎 360, TOPGAME.

Features

  • LevelDB client-server support, written in C/C++

  • Designed to store collection data

  • Persistent key-value, key-zset, key-map('hashmap') storage

  • Redis clients are supported

  • Client API supports including C++, php, Python, Cpy, Java, nodejs, Ruby, Go(see all)

  • Persistent queue service

  • Replication(master-slave), load balance

  • GUI administration tool(phpssdbadmin)

  • Built-in CLI nagios self-checks

limit

  • 最大 Key 长度200 字节

  • 最大 Value 长度31MB

  • 最大请求或响应长度 31MB

  • 单个 HASH 中的元素数量 9,223,372,036,854,775,807

  • 单个 ZSET 中的元素数量 9,223,372,036,854,775,807

  • 单个 QUEUE 中的元素数量 9,223,372,036,854,775,807

  • 命令最多参数个数 所有参数加起来体积不超过 31MB 大小

PHP client API example

 
   
   
 
  1. <?php

  2. require_once('SSDB.php');

  3. $ssdb = new SimpleSSDB('127.0.0.1', 8888);

  4. $resp = $ssdb->set('key', '123');

  5. $resp = $ssdb->get('key');

  6. echo $resp; // output: 123

More...

Who's using SSDB?

And more...

Documentation

  • View online

  • Contribute to SSDB documentation project

Compile and Install

 
   
   
 
  1. [root@CentOS ~]# yum install -y gcc-c++ autoconf unizp wget

  2. [root@CentOS ~]# wget --no-check-certificate https://github.com/ideawu/ssdb/archive/master.zip

  3. [root@CentOS ~]# unzip master

  4. [root@CentOS ~]# cd ssdb-master

  5. [root@CentOS ~]# make

  6. [root@CentOS ~]# make install

  7. #optional, install ssdb in /usr/local/ssdb

  8. # start master

  9. [root@CentOS ~]# cd /usr/local/ssdb

  10. [root@CentOS ssdb]# ./ssdb-server ssdb.conf

  11. # or start as daemon

  12. [root@CentOS ssdb]# ./ssdb-server -d ssdb.conf

  13. # ssdb command line

  14. [root@CentOS ssdb]# ./ssdb-cli -p 8888

  15. # stop ssdb-server

  16. [root@CentOS ssdb]# ./ssdb-server ssdb.conf -s stop

  17. # for older version

  18. $ kill `cat ./var/ssdb.pid`

See Compile and Install wiki

Performance

Typical performance

Total 1000 requests.

 
   
   
 
  1. writeseq  :    0.546 ms/op      178.7 MB/s

  2. writerand :    0.519 ms/op      188.1 MB/s

  3. readseq   :    0.304 ms/op      321.6 MB/s

  4. readrand  :    0.310 ms/op      315.0 MB/s

SSDB vs Redis

SSDB - A fast NoSQL database for storing big list of data

View full SSDB vs Redis benchmark charts...

Concurrency benchmark

 
   
   
 
  1. ========== set ==========

  2. qps: 44251, time: 0.226 s

  3. ========== get ==========

  4. qps: 55541, time: 0.180 s

  5. ========== del ==========

  6. qps: 46080, time: 0.217 s

  7. ========== hset ==========

  8. qps: 42338, time: 0.236 s

  9. ========== hget ==========

  10. qps: 55601, time: 0.180 s

  11. ========== hdel ==========

  12. qps: 46529, time: 0.215 s

  13. ========== zset ==========

  14. qps: 37381, time: 0.268 s

  15. ========== zget ==========

  16. qps: 41455, time: 0.241 s

  17. ========== zdel ==========

  18. qps: 38792, time: 0.258 s

Run on a 2013 MacBook Pro 13 inch with Retina display.

Architecture

Windows executable

Download ssdb-server.exe from here: https://github.com/ideawu/ssdb-bin

SSDB library for iOS

 
   
   
 
  1. make ios

  2. # ls ios/

  3. include/ libleveldb-ios.a libsnappy-ios.a libssdb-ios.a libutil-ios.a

Drag the static libraies files into your iOS project. Then add ios/include to your iOS project'sHeader Search Paths, which is set in Build Settings.

Links

  • Author's homepage

  • Cpy Scripting Language

  • Google LevelDB

  • Lua ssdb client driver for the ngx_lua

  • Yet another ssdb client for Python

  • SSDB 中文文档

Changes made to LevelDB

See Changes-Made-to-LevelDB wiki

LICENSE

SSDB is licensed under New BSD License, a very flexible license to use.

Authors

@ideawu

Thanks

  • 刘建辉, liujianhui@gongchang.com

  • wendal(陈镇铖), wendal1985@gmail.com, http://wendal.net

SSDB 命令 (略)

参考 http://ssdb.io/docs/zh_cn/commands/index.html

hydrogen-ssdb

Java 编写的 SSDB 客户端

更新

  • 2018-05-06: 修复了从节点恢复时没有被认作是从节点的问题。

  • 2018-02-25: 版本号更新到 1.1.0,添加了 multiGet() 方法,修复了若干方法在多服务器负载均衡上的 BUG。

  • 2017-08-03: 修复了 Cluster 无法恢复的问题,版本号更新到 1.0.1。

  • 2017-06-13: 完成了最后一个基本特性的实现,版本号正式改为 1.0.0。

介绍

hydrogen-ssdb 是一个 Java 编写的 SSDB 客户端,支持多线程并发请求和多服务器的负载均衡(客户端分发请求)。

SSDB 是一个类似 Redis 的 NOSQL 数据库,兼容 Redis 协议,且支持多线程,内存占用小。

hydrogen-ssdb 是一个 SSDB 客户端,具有以下特性:

  1. 易于配置,易于使用;

  2. 支持 SSDB 主从集群与负载均衡;

  3. 当集群中的服务器 down 掉时,能自动识别并跳过该服务器。

【负载均衡的抽象和实现】

hydrogen-ssdb 将负载均衡抽象为 Sharding类,该类负责决定一个请求应该发送给哪台 SSDB 服务器。

在 Sharding中,所有的服务器( Server)被归为多个集群( Cluster), Cluster 是负载均衡的顶层单位。每个 Cluster 包含多个 Server,一个 Server 可以是主服务器,也可以是从服务器(这个必须与 SSDB 实际的主从配置严格一致),但 Cluster 中必须要有主服务器。

hydrogen-ssdb 缺省实现了基于一致性哈希环的负载均衡方式。如果这种方式不适合您的实际情况,您可以自己实现 Sharding的子类,然后通过 SsdbClient的构造方法传入。下面是一个如何使用自定义 Sharding的例子,假设你已经实现了自定义的 MySharding类:

 
   
   
 
  1. MySharding mySharding = ...  // 自定义 Sharding

  2. SsdbClient client = new SsdbClient(mySharding);

下面介绍 hydrogen-ssdb 缺省实现的负载均衡的原理。

【基于一致性哈希环的负载均衡】

【对某些命令的处理】

在多服务器环境下,某些命令会发送给所有的 cluster,然后收集结果,例如 scan() 方法;

还有些命令仅仅在单服务器下执行,例如 multiGet() 方法,当在多服务器下时,它不会执行 multi_get 命令,而是对每个 key 依次调用 get 方法,然后收集结果。

【对单点故障的处理】

在负载均衡当中,每个节点都负责整个一致性哈希环中的一部分(称为哈希段)。当负载均衡当中出现单点故障时,故障节点对应的哈希段将无法执行存取操作,于是有两种处理方式:

  1. 故障节点前面的节点自动接管该哈希段。这种方式适用于将 SSDB 用于缓存,因为缓存丢失是可以重新填充的;

  2. 保留哈希段的故障状态,直到故障节点恢复。这种方式适用于将 SSDB 用于数据库,这样能严格保证一个 key 会保存在对应的节点中。

hydrogen-ssdb 缺省情况下使用第一种方式来处理。如果需要修改,可以以下面的方式:

 
   
   
 
  1. ConsistentHashSharding sharding = (ConsistentHashSharding)ssdbClient.getSharding();

  2. sharding.setSpofStrategy(SPOFStrategy.PreserveKeySpaceStrategy);

【如何添加 Cluster】

对于一致性哈希环,每一个 Cluster 的哈希段都是固定的,所以每添加一个新的 Cluster,都只会给当前的其中 1 个 Cluster 减负,而不是给所有的 Cluster 减负。例如当前有 A、B、C 三个 Cluster,那么当添加一个 D 到 A 和 B 之间,形成 “A-D-B-C” 时,它只会分担 A 的一部分哈希段,B 和 C 的哈希段没有改变,也就是说 B 和 C 的负载没有变化。

ConsistentHashSharding 使用 key 的 MD5 签名的前四个字节作为 hash 值,以尽可能让所有的 key 均匀分布。

由此可知,在添加 Cluster 之前,你需要明确的了解每个 Cluster 当前的负载情况,找到负载最重的 Cluster,将新的 Cluster 加在它后面。

所以, ConsistentHashSharding 的 addCluster() 方法有两个参数,第一个是要添加的 Cluster,第二个是需要被分担负载的 Cluster。

项目依赖

hydrogen-ssdb 依赖于下面两个框架:

  • Apache commons-pool2 (对象池框架)

  • slf4j (日志框架)

使用方法

基本使用方法

 
   
   
 
  1. SsdbClient client = new SsdbClient(host, port);

  2. client.set("key", "value");

  3. System.out.println(client.get("key"));   // output "value"

  4. client.close();    // 应用结束时需要调用 close() 方法,也可以配置在 Spring 的 destroy-method 中

配置主从服务器

 
   
   
 
  1. List<Server> servers = Arrays.asList(

  2.        new Server("192.168.1.180", 8888, true),  // 主服务器

  3.        new Server("192.168.1.180", 8889, false)  // 从服务器

  4. );

  5. SsdbClient client = SsdbClient.fromSingleCluster(servers);

  6. client.set("name", "hydrogen-ssdb");    // 写入请求一定会发送给主服务器

  7. System.out.println(client.get("name")); // 读取请求会随机发送给任意一台服务器

配置负载均衡

 
   
   
 
  1. Sharding sharding = new ConsistentHashSharding(Arrays.asList(

  2.        new Cluster(new Server("192.168.1.180", 8888), 100),  // 100 和 200 这两个参数指的是权重,

  3.        new Cluster(new Server("192.168.1.180", 8889), 200)   // 权重越大的 Cluster 所保存的 key 越多。

  4. ));

  5. SsdbClient ssdbClient = new SsdbClient(sharding);

Spring XML 配置

 
   
   
 
  1. <!-- 单个 SSDB 服务器的配置,其他几个类似的构造方法在此略去 -->

  2. <bean id="singleServerSsdbClient" class="com.hyd.ssdb.SsdbClient" destroy-method="close">

  3.    <constructor-arg name="host" value="192.168.1.180"/>

  4.    <constructor-arg name="port" value="8888"/>

  5. </bean>

  6. <!-- 自定义 Sharding -->

  7. <bean id="custShardingClient" class="com.hyd.ssdb.SsdbClient" destroy-method="close">

  8.    <constructor-arg name="sharding">

  9.        <bean class="com.hyd.ssdb.AjiaSharding"/>

  10.    </constructor-arg>

  11. </bean>

  12. <!-- 多台 SSDB 主从服务器的配置 -->

  13. <bean id="ssdbServer1" class="com.hyd.ssdb.conf.Server">

  14.    <property name="host" value="192.168.1.180"/>

  15.    <property name="port" value="8888"/>

  16.    <property name="master" value="true"/>

  17. </bean>

  18. <bean id="ssdbServer2" class="com.hyd.ssdb.conf.Server">

  19.    <property name="host" value="192.168.1.180"/>

  20.    <property name="port" value="8889"/>

  21.    <property name="master" value="false"/>

  22. </bean>

  23. <bean id="singleClusterSsdbClient" class="com.hyd.ssdb.SsdbClient"

  24.      factory-method="fromSingleCluster" destroy-method="close">

  25.    <constructor-arg name="servers">

  26.        <list value-type="com.hyd.ssdb.conf.Server">

  27.            <ref bean="ssdbServer1"/>

  28.            <ref bean="ssdbServer2"/>

  29.        </list>

  30.    </constructor-arg>

  31. </bean>

  32. <!-- 多台 SSDB 负载均衡的配置(每个 Cluster 一台服务器) -->

  33. <bean id="ssdbCluster1" class="com.hyd.ssdb.conf.Cluster" factory-method="fromSingleServer">

  34.    <constructor-arg name="server" ref="ssdbServer1"/>

  35. </bean>

  36. <bean id="ssdbCluster2" class="com.hyd.ssdb.conf.Cluster" factory-method="fromSingleServer">

  37.    <constructor-arg name="server" ref="ssdbServer2"/>

  38. </bean>

  39. <bean id="shardingSsdbClient" class="com.hyd.ssdb.SsdbClient"

  40.      factory-method="fromClusters" destroy-method="close">

  41.    <constructor-arg name="clusters">

  42.        <list value-type="com.hyd.ssdb.conf.Cluster">

  43.            <ref bean="ssdbCluster1"/>

  44.            <ref bean="ssdbCluster2"/>

  45.        </list>

  46.    </constructor-arg>

  47. </bean>

使用注意

线程安全

SsdbClient 对象包含了对整个负载均衡的拓扑结构的处理,所以对于每一个由多个 SSDB 服务器组成的负载均衡架构,只需创建一个 SsdbClient 对象即可。另外 SsdbClient 是线程安全的,所以可以让任意多个线程访问。

误用导致内存占用过高

因为一个 SsdbClient 对象可能包含一个或多个连接池(每个连接池对应一个 SSDB 服务器),因此请不要创建大量的 SsdbClient 对象,这样完全没有必要,也会使得内存很容易被用光。


以上是关于SSDB - A fast NoSQL database for storing big list of data的主要内容,如果未能解决你的问题,请参考以下文章

ssdb、minio性能测试c

大数据学习总结记录—SSDB

SSDB 一个高性能的支持丰富数据结构的 NoSQL 数据库, 用于替代 Redis.

SSDB VS redis

全内存的redis用习惯了?那能突破内存限制类似redis的nosql产品ssdb呢?

SSDB高可用方案