本文主要是介绍RocksDB的安装以及基本接口的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
RocksDB的安装以及基本接口的使用
- 一、简介
- 二、编译安装
- 三、基本接口及使用
- 四、RocksDB高级功能的使用
- 五、完整编程示例
- 总结
一、简介
RocksDB 是 Facebook 的一个实验项目,目的是希望能开发一套能在服务器压力下,真正发挥高速存储硬件性能的高效数据库系统。RocksDB是一个存储引擎,不提供网络服务,只专注于具体的存储。这是一个 C++ 库,允许存储任意长度二进制 KV 数据。支持原子读写操作。
RocksDB 依靠大量灵活的配置,使之能针对不同的生产环境进行调优,包括直接使用内存,使用 Flash,使用硬盘或者 HDFS。 支持使用不同的压缩算法,并且有一套完整的工具供生产和调试 使用。
历史:RocksDB 大量复用了 levedb 的代码,并且还借鉴了许多 HBase 的设计理念。原始代码从 leveldb 1.5 上fork 出来。同时 RocksDB 也借用了一些 Facebook 之前就有的理念和代码。
RocksDB 应用场景非常广泛;比如支持 redis 协议的 pika 数据 库,采用 RocksDB 持久化 Redis 支持的数据结构;MySQL 中支 持可插拔的存储引擎,Facebook 维护的 MySQL 分支中支持 RocksDB。
所有的数据库需求都可以转化为key-value数据库。RocksDB可以调优(基于配置项)、测试。
RocksDB具有以下优势:
- 高性能:RocksDB使用了一些优化技术,例如基于内存和磁盘的排序、压缩以及多线程并发等,使其在读写操作方面都表现出极高的性能。
- 可靠性:RocksDB支持多种数据格式,可以自动检测和修复损坏的数据。同时也提供了数据备份和恢复功能。
- 易用性:RocksDB简单易用,在数据库的创建、打开、写入和查询方面提供了简单而有效的API接口,并且还提供了大量示例代码以帮助用户快速上手。
- 可扩展性:RocksDB支持分布式存储,并可以通过sharding或replication来实现水平扩展。
基于以上优点,RocksDB适合应用于以下场景:
-
网络服务器:作为后端存储服务,支持快速读写操作和高并发访问;
-
分布式系统:作为分布式系统中的数据存储引擎,支持高可靠性和水平扩展;
-
互联网广告系统:作为广告检索引擎中的索引存储组件,快速响应请求;
-
移动设备应用:作为移动应用的本地存储引擎,支持快速读写操作和数据备份等功能。
二、编译安装
(1)下载和安装RocksDB源代码。对编译器版本有要求,要求编译器能支持C++17。
git clone https://github.com/facebook/rocksdb.git
cd rocksdb
# 编译成调试模式
make
# 编译成发布模式
make static_lib
(2)安装依赖库:需要先安装一些必要的依赖库,如snappy、gflags、zlib等压缩库。rocksdb 支持多种压缩模式。
ubuntu:# rocksdb 支持多种压缩模式
# 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
(3)配置环境变量:将RocksDB的库路径添加到LD_LIBRARY_PATH环境变量中,以便程序可以正确地链接和加载库文件。
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
(4)测试是否成功,执行以下命令测试:
cd rocksdb/
make check
如果所有测试都通过,则表示RocksDB已经成功安装。
三、基本接口及使用
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)
RocksDB的基本接口可以分为以下几个部分:
- 打开数据库:使用rocksdb::DB::Open()函数打开数据库,返回一个rocksdb::DB对象。示例:
#include <rocksdb/db.h>rocksdb::DB* db;
rocksdb::Options options;
options.create_if_missing = true; // 如果数据库不存在,则创建
rocksdb::Status status = rocksdb::DB::Open(options, "/path/to/db", &db);
if (!status.ok()) {// 处理错误
}
- 写入数据:使用rocksdb::DB::Put()函数写入数据,需要指定键值对的key和value。示例:
std::string key = "my_key";
std::string value = "my_value";
rocksdb::Status status = db->Put(rocksdb::WriteOptions(), key, value);
if (!status.ok()) {// 处理错误
}
- 读取数据:使用rocksdb::DB::Get()函数读取数据,需要指定要读取的key,并将value保存在一个std::string类型的变量中。如果找不到该key,则返回NotFound状态。示例:
std::string key = "my_key";
std::string value;
rocksdb::Status status = db->Get(rocksdb::ReadOptions(), key, &value);
if (status.IsNotFound()) {// 处理未找到key的情况
} else if (!status.ok()) {// 处理其他错误
} else {// 成功读取到了value
}
- 删除数据:使用rocksdb::DB::Delete()函数删除数据,需要指定要删除的key。示例:
std::string key = "my_key";
rocksdb::Status status = db->Delete(rocksdb::WriteOptions(), key);
if (!status.ok()) {// 处理错误
}
- 批量写入数据:使用rocksdb::WriteBatch类可以实现批量写入多个键值对。示例:
rocksdb::WriteBatch batch;
batch.Put("key1", "value1");
batch.Put("key2", "value2");
batch.Delete("key3");
rocksdb::Status status = db->Write(rocksdb::WriteOptions(), &batch);
if (!status.ok()) {// 处理错误
}
- 遍历数据:使用rocksdb::Iterator类可以遍历整个数据库中的所有键值对。示例:
// 创建迭代器,并将其设置到第一个键值对的位置
rocksdb::Iterator* it = db->NewIterator(rocksdb::ReadOptions());
for (it->SeekToFirst(); it->Valid(); it->Next()) {std::cout << it->key().ToString() << ": " << it->value().ToString() << std::endl;
}
if (!it->status().ok()) {// 处理错误
}
delete it;
四、RocksDB高级功能的使用
RocksDB是一种高性能的键值存储引擎,支持各种高级功能。
- 压缩。RocksDB支持多种压缩算法,包括LZ4、Snappy和Zlib。在创建数据库时,可以通过Options设置压缩算法和压缩级别。
示例代码:
rocksdb::Options options;
options.compression = rocksdb::kSnappyCompression;
options.compression_level = 6;
rocksdb::DB* db;
rocksdb::Status status = rocksdb::DB::Open(options, "/path/to/db", &db);
- 列族。列族是将数据按照逻辑分组的方式,在RocksDB中可以更好地管理数据。每个列族有自己的选项和元数据,可以单独进行配置。
示例代码:
rocksdb::ColumnFamilyHandle* cfh;
rocksdb::ColumnFamilyOptions cf_options;
cf_options.compression = rocksdb::kSnappyCompression;
cf_options.compression_level = 6;
std::vector<rocksdb::ColumnFamilyDescriptor> column_families;
column_families.push_back(rocksdb::ColumnFamilyDescriptor(rocksdb::kDefaultColumnFamilyName, rocksdb::ColumnFamilyOptions()));
column_families.push_back(rocksdb::ColumnFamilyDescriptor("my_cf", cf_options));
std::vector<rocksdb::ColumnFamilyHandle*> handles;
rocksdb::DB* db;
rocksdb:Status status = rocksdb:DB:Open(rocksbd:Options(), "/path/to/db", column_families, &handles, &db);
- 过滤器。RocksDB支持布隆过滤器和前缀过滤器,可以大幅提升查询效率。在创建数据库时,可以通过Options设置过滤器类型和参数。
示例代码:
rocksdb::BlockBasedTableOptions table_options;
table_options.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10));
rocksdb::Options options;
options.table_factory.reset(rocksdb::NewBlockBasedTableFactory(table_options));
rocksdb::DB* db;
rocksdb::Status status = rocksdb::DB::Open(options, "/path/to/db", &db);
- 后台压缩。RocksDB支持后台压缩,即在后台线程中对SST文件进行压缩操作。这样可以避免在写入时造成的性能下降。在创建数据库时,可以通过Options设置后台压缩选项。
示例代码:
rocksdb::Options options;
options.compaction_style = rocksdb::kCompactionStyleUniversal;
options.max_background_compactions = 2;
options.max_background_flushes = 1;
options.compaction_options_universal.max_size_amplification_percent = 50;
rocksdb::DB* db;
rocksdb:Status status = rocksbd:DB:Open(options, "/path/to/db", &db);
- 内存管理。RocksDB支持多种内存管理方式,包括TBB、jemalloc和libc等。可以根据实际需求进行选择和配置。
示例代码:
rocksdb::Cache* cache = rocksdb::NewLRUCache(1000000);
rocksdb::Options options;
options.block_cache = cache;
options.use_fsync = true;
rocksdb::DB* db;
rocksdb:Status status = rocksbd:DB:Open(options, "/path/to/db", &db);
- 多线程读写。RocksDB支持多线程读写,可以通过设置选项来开启并发读写。
示例代码:
rocksdb::Options options;
options.allow_concurrent_memtable_write = true;
options.enable_write_thread_adaptive_yield = true;
options.write_thread_max_yield_usec = 1000 * 1000;
rocksdb::DB* db;
rocksbd:Status status = rocksbd:DB:Open(options, "/path/to/db", &db);
五、完整编程示例
#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-values=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
总结
RocksDB是一个高性能的键值存储库,其基本接口相对简单,主要包括打开数据库、写入数据、读取数据、删除数据、批量写入数据和遍历数据等操作:
- 打开数据库:
使用rocksdb::DB::Open()
函数打开数据库,需要设置选项和数据库路径。
- 写入数据:
使用rocksdb::DB::Put()
函数写入数据,需要设置写入选项、键和值。
- 读取数据:
使用rocksdb::DB::Get()
函数读取数据,需要设置读取选项和键,返回的值通过函数参数返回。
- 删除数据:
使用rocksdb::DB::Delete()
函数删除数据,需要设置删除选项和键。
- 批量写入数据:
使用rocksdb::WriteBatch
类进行批量写入数据,需要设置写入选项和多个键值对。
- 遍历数据:
使用rocksdb::Iterator
类进行遍历数据,需要设置读取选项,可以按顺序遍历整个数据库或者指定前缀的数据。
需要注意的是,RocksDB支持多种选项设置和配置,例如存储引擎、压缩方式、持久化方式等,可以根据实际需求进行设置。
RocksDB是一个非常高效、稳定、可靠的键值存储库,其基本接口使用方法相对简单,可以方便地进行键值存储和访问操作,适用于需要高性能键值存储的各种场景。
这篇关于RocksDB的安装以及基本接口的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!