本文主要介绍 RocksDB 的部署与基本使用

RocksDB 部署

OverView

RocksDB 库提供了一个持久的键值存储库。键和值是任意字节数组。键值在键值存储区内根据用户指定的比较器函数排序。

该库由 Facebook 数据库工程团队维护,基于谷歌 Sanjay Ghemawat 和 Jeff Dean 的 LevelDB。

本概述提供了一些使用 RocksDB 的简单示例。关于创建 RocksDB 的初衷,请参阅 Dhruba Borthakur 在 2013 年 Data @ Scale 会议上的介绍性演讲。

RocksDB 编译安装

  1. RocksDB 对编译器版本有要求,要求编译器能支持C++17
     git clone https://github.com/facebook/rocksdb.git
     cd rocksdb
     # 编译成调试模式
     make
     # 编译成发布模式
     make static_lib
    
  2. 压缩库,rocksdb 支持多种压缩模式。 Ubuntu
     # gflags
     sudo apt-get install libgflags-dev
     # snappy
     sudo apt-get install libsnappy-dev
     # zlib
     sudo apt-get install zlib1g-dev
     # bzip2
     sudo apt-get install libbz2-dev
     # lz4
     sudo apt-get install liblz4-dev
     # zstandard
     sudo apt-get install libzstd-dev
    

    CentOS

     # gflags
     git clone https://github.com/gflags/gflags.git
     cd gflags
     git checkout v2.0
     ./configure && make && sudo make install
     # snappy
     sudo yum install snappy snappy-devel
     # zlib
     sudo yum install zlib zlib-devel
     # bzip2
     sudo yum install bzip2 bzip2-devel
     # lz4
     sudo yum install lz4-devel
     # ASAN (optional for debugging)
     sudo yum install libasan
     # zstandard
     sudo yum install libzstd-devel
    

RocksDB 基本使用

  1. 基本接口 Alt text
    Status Open(const Options& options, const std::string& dbname, DB** dbptr);
    Status Get(const ReadOptions& options, const Slice& key, std::string* value);
    Status Get(const ReadOptions& options, ColumnFamilyHandle* column_family, const Slice& key, std::string* value);
    Status Put(const WriteOptions& options, const Slice& key, const Slice& value);
    Status Put(const WriteOptions& options, ColumnFamilyHandle* column_family, const Slice& key, const Slice& value);
    // fix read-modify-write 将 读取、修改、写入封装到一个接口中
    Status Merge(const WriteOptions& options, const Slice& key, const Slice& value);
    Status Merge(const WriteOptions& options, ColumnFamilyHandle* column_family, const Slice& key, const Slice& value);
    // 标记删除,具体在 compaction 中删除
    Status Delete(const WriteOptions& options, const Slice& key);
    Status Delete(const WriteOptions& options, ColumnFamilyHandle* column_family, const Slice& key, const Slice& ts);
    // 针对从来不修改且已经存在的key; 这种情况比 delete 删除的快;
    Status SingleDelete(const WriteOptions& options, const Slice& key);
    Status SingleDelete(const WriteOptions& options, ColumnFamilyHandle* column_family,  const Slice& key);
    // 迭代器会阻止 compaction 清除数据,使用完后需要释放;
    Iterator* NewIterator(const ReadOptions& options);
    Iterator* NewIterator(const ReadOptions& options, ColumnFamilyHandle* column_family)
    
  2. 代码示例
#include <cstdio>
#include <string>

#include "rocksdb/db.h"
#include "rocksdb/slice.h"
#include "rocksdb/options.h"

using ROCKSDB_NAMESPACE::DB;
using ROCKSDB_NAMESPACE::Options;
using ROCKSDB_NAMESPACE::PinnableSlice;
using ROCKSDB_NAMESPACE::ReadOptions;
using ROCKSDB_NAMESPACE::Status;
using ROCKSDB_NAMESPACE::WriteBatch;
using ROCKSDB_NAMESPACE::WriteOptions;

// rocksdb存储路径
std::string kDBPath="/home/tmp/rocksdb_simple"

int main()
{
    DB* db;
    Options options;
    options.IncreaseParallelism();
    //文件夹没有数据就创建
    Options.create_if_missing=true;
    // 打开数据库,加载数据到内存
    Status s=DB::Open(options,kDBPath,&db);
    assert(s.ok());
    // 写key-value
    s=db->Put(WriteOptions(),"key01","value");
    assert(s.ok());

   std::string value;
    s=db->get(ReadOptions(),"key01",&value);
    assert(s.ok());
    assert(value=="value");
    // 管道,原子方式更新
    {
        WriteBatch batch;
        batch.Delete("key01");
        batch.Put("key02",value);
        s=db->Write(WriteOptions(),&batch);
    }
    s=db->Get(ReadOptions(),"key01",&value);
    assert(s.IsNotFound());
    s=db->Get(ReadOptions(),"key02",&value);
    assert(value=="value");

    {
        PinnableSlice pinnable_val;
        // 列族方式读取
        db->Get(ReadOptions(),db->DefaultColumnFamily(),"key02",&pinnable_val);
        assert(pinnable_val=="value");
    }

    {
        std::string string_val;
        PinnableSlice pinnable_val(&string_val);
        // 列族方式读取
        db->Get(ReadOptions(),db->DefaultColumnFamily(),"key02",&pinnable_val);
        assert(pinnable_val=="value");
        assert(pinnable_val.IsPinned() || string_value == "value");
    }

    PinnableSlice pinnable_val;
    s=db->Get(ReadOptions(),db->DefaultColumnFamily(),"key01",&pinnable_val);
    assert(s.IsNotFound()");

    pinnable_val.Reset();
    db->Get(ReadOptions(),db->DefaultColumnFamily(),"key02",&pinnable_val);
    assert(pinnable_val=="value");
    pinnable_val.Reset();

    delete db;

    return 0;
}

编译

g++ simple.cc -o simple -std=c++17 ../librocksdb.a -I../include -lpthread -ldl -lrt -lsnappy -lgflags -lz -lbz2 -llz4 -lzstd

相关文档

  • https://rocksdb.org/docs/getting-started.html
  • https://github.com/facebook/rocksdb