• 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+ '
    '
    Block  := Size '
    ' Data '
    '
    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, '
    ', len);
        if(data == NULL){
            break;
        }
        data += 1;
        int num = data - ptr;
        if(num == 1 || (num == 2 && ptr[0] == '
    ')){
            // Packet received.
            return OK;
        }
        // Size received
        int size = (int)strtol(ptr, NULL, 10);
    
        len -= num + size;
        ptr += num + size;
        if(len >= 1 && ptr[0] = '
    '){
            len -= 1;
            ptr += 1;
        }else if(len >= 2 && ptr[0] == '
    ' && ptr[1] == '
    '){
            len -= 2;
            ptr += 2;
        }else{
            break;
        }
        // Data received
    }
  • 相关阅读:
    Java_基础_内存管理
    Reflux中文教程——action
    Reflux中文教程——概览
    包含块、层叠上下文、BFC
    DOM编程的性能问题
    JavaScript数据存取的性能问题
    闭包
    JavaScript中的继承
    JavaScript中的静态成员
    JavaScript中的私有属性
  • 原文地址:https://www.cnblogs.com/chenny7/p/4569837.html
Copyright © 2020-2023  润新知