SSDB 数据库

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: 原文:SSDB 数据库SSDB数据库   SSDB是一套基于LevelDB存储引擎的非关系型数据库(NOSQL),可用于取代Redis,更适合海量数据的存储。 另外,rocksdb是FB在LevelDB的二次开发版本,因此也存在使用RocksDB作为存储引擎的SSDB版本,可以参考这里。
原文: SSDB 数据库

SSDB数据库

 

SSDB是一套基于LevelDB存储引擎的非关系型数据库(NOSQL),可用于取代Redis,更适合海量数据的存储。

另外,rocksdb是FB在LevelDB的二次开发版本,因此也存在使用RocksDB作为存储引擎的SSDB版本,可以参考这里

 

编译和安装

wget --no-check-certificate https://github.com/ideawu/ssdb/archive/master.zip
unzip master
cd ssdb-master
make
# 将安装在 /usr/local/ssdb 目录下
sudo make install

 

启动服务

# 启动主库
./ssdb-server ssdb.conf

# 或者启动为后台进程
./ssdb-server -d ssdb.conf

# 启动 ssdb 命令行客户端
./tools/ssdb-cli -p 8888

# 停止 ssdb-server
./ssdb-server ssdb.conf -s stop
# 对于旧版本
kill `cat ./var/ssdb.pid`

 

配置文件

ssdb.conf:

work_dir = ./var
pidfile = ./var/ssdb.pid

server:
    ip: 127.0.0.1
    port: 8888
    # bind to public ip
    #ip: 0.0.0.0
    # format: allow|deny: all|ip_prefix
    # multiple allows or denys is supported
    #deny: all
    #allow: 127.0.0.1
    #allow: 192.168
    # auth password must be at least 32 characters
    #auth: very-strong-password

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: sync
        #ip: 127.0.0.1
        #port: 8889

logger:
    level: debug
   # 支持的日志级别有: debug, warn, error, fatal. output: 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: 1000 # yes|no compression: yes

 

一个 ssdb-server 实例占用的内存瞬时(有可能, 而且即使达到, 也只是持续短时间)最高达到(MB):

cache_size + write_buffer_size * 66 + 32

这是对于压缩选项没有开启的情况, 如果 compression: yes, 计算公式是:

cache_size + 10 * write_buffer_size * 66 + 32

你可以调整配置参数, 限制 ssdb-server 的内存占用.

 

 


 

SSDB命令

与Redis类似,SSDB也支持多种数据结构(KV list, hash, soreted set),下面列出了常用命令

 

dbsize           # 返回数据库占用空间,以字节为单位
flushdb           # 清空数据库
info             # 返回服务器信息
auth password      # 验证访问密码

 

KV结构

set key value 

setx key value ttl     # 设置key的同时设置ttl
setnx key value       # 若key已存在,则不设置
multi_set key1 value1 key2 value2 ...

exists key
get key
getset key value           # 更新key,并返回旧value
multi_get key1 key2 ...

keys key_start key_end limit     # 返回指定范围内的key,左开右闭区间(SSDB的key有序存储)
rkeys key_start key_end limit
scan key_start key_end limit
rscan key_start key_end limit

expire key ttl 
ttl key 

del key
multi_del key1 key2 ...

substr key start size         # 返回子串
strlen key

incr key [num]
getbit key offset
setbit key offset val
bitcount key [start] [end]
countbit key start size

 

 

 

hashmap结构

hset name key value
multi_hset name key1 value1 key2 value2 ...

hget name key
multi_hget name key1 key2 ...
hgetall name
hkeys name key_start key_end
hscan key_start key_end limit
hrscan key_start key_end limit

hdel name key            # 删除一个字段
hclear name             # 删除所有字符
multi_hdel name key1 key2 ...

hexists name key
hsize name
hincr name key [num]

hlist name_start name_end limit      # 列出指定范围的所有hash表
hrlist name_start name_end limit

 

 

 

list结构

qpush_front name item1 item2 ...     # 往队头插入新元素
qpush_back name item1 item2 ...      # 往队尾插入新元素

qpop_front name size             # 从队头弹出若干个元素
qpop_back name size            # 从队尾弹出若干个元素
qtrim_front name size            # 从队头移除多个元素
qtrim_back name size           # 从队尾移除多个元素

qfront name                # 返回队头
qback name                # 返回队尾
qsize name                # 返回队长
qget name index              # 返回指定位置元素
qset name index val
qrange name offset limit          # 返回一个切片
qslice name begine end          # 返回一个切片
qclear name

qlist name_start name_end limit
qrlist name_start name_end limit

 

 

 

sorted set结构

zset name key socre
zget name key
zdel name key
zexists name key
zsize name
zincr name key num

 

 

 

导出/导入

SSDB才有LSM模型,也就是说它的key是有序存储的,因此,我们可以导出所有key的数据,也可以导出指定范围内key的数据。

 

1、使用ssdb-cli 命令行客户端

导出整个数据库:

# backup current database into file backup.ssdb
ssdb 127.0.0.1:8888> export backup.ssdb

 

按照 Key 区间导出数据库(交互模式)

ssdb 127.0.0.1:8888> export -i backup.ssdb
input KV range[start, end]:
  start(inclusive, default none): a
    end(inclusive, default none): z
input HASH range:
  start(inclusive, default none):
    end(inclusive, default none):
input ZSET range:
  start(inclusive, default none):
    end(inclusive, default none):
input QUEUE range:
  start(inclusive, default none):
    end(inclusive, default none):

命令 export -i backup.ssdb 将导出区间 [a, z] 内的 KV, 所有的 HASH, ZSET, QUEUE.

 

导入命令:

# import backup.ssdb into current database
ssdb 127.0.0.1:8888> import backup.ssdb

import 命令会把数据库中的相同 key 给替换。

 

 

2、SSDB 另一个专门用于导出工具是 ssdb-dump,用法如下:

./tools/ssdb-dump ip port output_folder

目录 output_folder 必须不存在, 因为 ssdb-dump 会创建这个目录. 导出之后, 这个目录里将有两个子目录, data 目录里包含着数据, 还有一个空的 meta 目录.

如果想从导出的目录恢复数据,可以将 output_folder 目录拷贝到你的服务器上面,然后修改你的 ssdb.conf 配置文件, 将 work_dir 指向 output_folder 目录, 然后重启 ssdb-server。

 

 

 

限制

最大 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 大小

 

 


 

Replication

Redis的主从复制在主库挂了的时候就无法再写入数据了,而SSDB不但支持主-从结构,还支持多主结构。

 

主-从配置

#server1:

replication:
    slaveof:

 

#server2:

replication:
    slaveof:
        id: svc_1
        # sync|mirror, default is sync
        type: sync
        ip: 127.0.0.1
        port: 8888

 

主-主配置

#server1:

replication:
    slaveof:
        id: svc_2
        # sync|mirror, default is sync
        type: mirror
        ip: 127.0.0.1
        port: 8889

 

#server2:

replication:
    slaveof:
        id: svc_1
        # sync|mirror, default is sync
        type: mirror
        ip: 127.0.0.1
        port: 8888

 

 

多主配置

在一组一共包含 n 个实例的 SSDB 实例群中, 每一个实例必须 slaveof 其余的 n-1 个实例.

replication:
    slaveof:
        id: svc_1
        # sync|mirror, default is sync
        type: mirror
        ip: 127.0.0.1
        port: 8888
    slaveof:
        id: svc_2
        # sync|mirror, default is sync
        type: mirror
        ip: 127.0.0.1
        port: 8889
    # ... more slaveof

 

监控

info命令可以返回SSDB服务状态:

ssdb 127.0.0.1:8899> info
binlogs
    capacity : 10000000
    min_seq  : 1
    max_seq  : 74
replication
    client 127.0.0.1:55479
        type     : sync
        status   : SYNC
        last_seq : 73
replication
    slaveof 127.0.0.1:8888
        id         : svc_2
        type       : sync
        status     : SYNC
        last_seq   : 73
        copy_count : 0
        sync_count : 44

 

binlogs,当前实例的写操作状态:

  • capacity: binlog 队列的最大长度
  • min_seq: 当前队列中的最小 binlog 序号
  • max_seq: 当前队列中的最大 binlog 序号

 

replication,可以有多条 replication 记录. 每一条表示一个连接进来的 slave(client), 或者一个当前服务器所连接的 master(slaveof).

  • slaveof|client ip:port, 远端 master/slave 的 ip:port
  • type: 类型, sync|mirror
  • status: 当前同步状态, DISCONNECTED|INIT|OUT_OF_SYNC|COPY|SYNC,见下面的解释
  • last_seq: 上一条发送或者收到的 binlog 的序号
  • slaveof.id: master 的 id(这是从 slave's 角度来看的, 你永远不需要在 master 上配置它自己的 id)
  • slaveof.copy_count: 在全量同步时, 已经复制的 key 的数量
  • slaveof.sync_count: 发送或者收到的 binlog 的数量.

关于 status:

  1. DISCONNECTED: 与 master 断开了连接, 一般是网络中断
  2. INIT: 初始化状态
  3. OUT_OF_SYNC: 由于短时间内在 master 有大量写操作, 导致 binlog 队列淘汰, slave 丢失同步点, 只好重新复制全部的数据
  4. COPY: 正在复制基准数据的过程中, 新的写操作可能无法及时地同步
  5. SYNC: 同步状态是健康的

 

判断同步状态

binlogs.max_seq 是指当前实例上的最新一次的写(写/更新/删除)操作的序号;

replication.client.last_seq 是指已发送给 slave 的最新一条 binlog 的序号;

所以, 如果你想判断主从同步是否已经同步到位(实时更新), 那么就判断 binlogs.max_seq 和 replication.client.last_seq 是否相等。

 

 


 

SSDB协议

SSDB协议与Redis的文本协议也类似:

 

SSDB数据包的结构:

Packet := Block+ '\n'
Block  := Size '\n' Data '\n'
Size   := literal_integer
Data   := size_bytes_of_data

 

请求:

Request := Cmd Blocks*
Cmd     := Block

请求命令包括: get, set, del, ...

 

响应:

Response := Status Block*
Status   := Block

响应状态码包括: ok, not_found, error, fail, client_error

 

示例:

用 telnet 或者 nc 命令连接到 SSDB 服务器, 然后输入下面的代码(用最后一行空行结束):

3
get
3
key

你将看到类似这样的响应:

2
ok
3
val

 

 

SSDB 协议解析器的C实现:

#include <stdlib.h>
#include <string.h>

int len = buffer->size();
char *ptr = buffer->data();
while(len > 0){
    char *data = (char *)memchr(ptr, '\n', len);
    if(data == NULL){
        break;
    }
    data += 1;
    int num = data - ptr;
    if(num == 1 || (num == 2 && ptr[0] == '\r')){
        // Packet received.
        return OK;
    }
    // Size received
    int size = (int)strtol(ptr, NULL, 10);

    len -= num + size;
    ptr += num + size;
    if(len >= 1 && ptr[0] = '\n'){
        len -= 1;
        ptr += 1;
    }else if(len >= 2 && ptr[0] == '\r' && ptr[1] == '\n'){
        len -= 2;
        ptr += 2;
    }else{
        break;
    }
    // Data received
}

 

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
存储 NoSQL Go
SSDB —— 开源NoSQL数据库 Redis之外的选择
SSDB是一个快速的用来存储十亿级别列表数据的开源 NoSQL 数据库。
807 0
SSDB —— 开源NoSQL数据库 Redis之外的选择
|
2月前
|
关系型数据库 MySQL Java
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
【YashanDB知识库】原生mysql驱动配置连接崖山数据库
|
2月前
|
关系型数据库 MySQL 数据库连接
docker拉取MySQL后数据库连接失败解决方案
通过以上方法,可以解决Docker中拉取MySQL镜像后数据库连接失败的常见问题。关键步骤包括确保容器正确启动、配置正确的环境变量、合理设置网络和权限,以及检查主机防火墙设置等。通过逐步排查,可以快速定位并解决连接问题,确保MySQL服务的正常使用。
366 82
|
7天前
|
负载均衡 算法 关系型数据库
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL集群架构负载均衡故障排除与解决方案
本文深入探讨 MySQL 集群架构负载均衡的常见故障及排除方法。涵盖请求分配不均、节点无法响应、负载均衡器故障等现象,介绍多种负载均衡算法及故障排除步骤,包括检查负载均衡器状态、调整算法、诊断修复节点故障等。还阐述了预防措施与确保系统稳定性的方法,如定期监控维护、备份恢复策略、团队协作与知识管理等。为确保 MySQL 数据库系统高可用性提供全面指导。
|
12天前
|
SQL 关系型数据库 MySQL
大数据新视界--大数据大厂之MySQL数据库课程设计:MySQL 数据库 SQL 语句调优方法详解(2-1)
本文深入介绍 MySQL 数据库 SQL 语句调优方法。涵盖分析查询执行计划,如使用 EXPLAIN 命令及理解关键指标;优化查询语句结构,包括避免子查询、减少函数使用、合理用索引列及避免 “OR”。还介绍了索引类型知识,如 B 树索引、哈希索引等。结合与 MySQL 数据库课程设计相关文章,强调 SQL 语句调优重要性。为提升数据库性能提供实用方法,适合数据库管理员和开发人员。
|
12天前
|
关系型数据库 MySQL 大数据
大数据新视界--大数据大厂之MySQL 数据库课程设计:MySQL 数据库 SQL 语句调优的进阶策略与实际案例(2-2)
本文延续前篇,深入探讨 MySQL 数据库 SQL 语句调优进阶策略。包括优化索引使用,介绍多种索引类型及避免索引失效等;调整数据库参数,如缓冲池、连接数和日志参数;还有分区表、垂直拆分等其他优化方法。通过实际案例分析展示调优效果。回顾与数据库课程设计相关文章,强调全面认识 MySQL 数据库重要性。为读者提供综合调优指导,确保数据库高效运行。
|
4月前
|
关系型数据库 MySQL 数据库连接
数据库连接工具连接mysql提示:“Host ‘172.23.0.1‘ is not allowed to connect to this MySQL server“
docker-compose部署mysql8服务后,连接时提示不允许连接问题解决
|
2月前
|
消息中间件 缓存 NoSQL
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)
缓存与数据库的一致性方案,Redis与Mysql一致性方案,大厂P8的终极方案(图解+秒懂+史上最全)

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等