RocksDB的安装以及基本接口的使用

2023-10-17 13:50

本文主要是介绍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. 网络服务器:作为后端存储服务,支持快速读写操作和高并发访问;

  2. 分布式系统:作为分布式系统中的数据存储引擎,支持高可靠性和水平扩展;

  3. 互联网广告系统:作为广告检索引擎中的索引存储组件,快速响应请求;

  4. 移动设备应用:作为移动应用的本地存储引擎,支持快速读写操作和数据备份等功能。

二、编译安装

(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的基本接口可以分为以下几个部分:

  1. 打开数据库:使用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()) {// 处理错误
}
  1. 写入数据:使用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()) {// 处理错误
}
  1. 读取数据:使用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
}
  1. 删除数据:使用rocksdb::DB::Delete()函数删除数据,需要指定要删除的key。示例:
std::string key = "my_key";
rocksdb::Status status = db->Delete(rocksdb::WriteOptions(), key);
if (!status.ok()) {// 处理错误
}
  1. 批量写入数据:使用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()) {// 处理错误
}
  1. 遍历数据:使用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是一种高性能的键值存储引擎,支持各种高级功能。

  1. 压缩。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);
  1. 列族。列族是将数据按照逻辑分组的方式,在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);
  1. 过滤器。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);
  1. 后台压缩。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);
  1. 内存管理。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);
  1. 多线程读写。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是一个高性能的键值存储库,其基本接口相对简单,主要包括打开数据库、写入数据、读取数据、删除数据、批量写入数据和遍历数据等操作:

  1. 打开数据库:

使用rocksdb::DB::Open()函数打开数据库,需要设置选项和数据库路径。

  1. 写入数据:

使用rocksdb::DB::Put()函数写入数据,需要设置写入选项、键和值。

  1. 读取数据:

使用rocksdb::DB::Get()函数读取数据,需要设置读取选项和键,返回的值通过函数参数返回。

  1. 删除数据:

使用rocksdb::DB::Delete()函数删除数据,需要设置删除选项和键。

  1. 批量写入数据:

使用rocksdb::WriteBatch类进行批量写入数据,需要设置写入选项和多个键值对。

  1. 遍历数据:

使用rocksdb::Iterator类进行遍历数据,需要设置读取选项,可以按顺序遍历整个数据库或者指定前缀的数据。

需要注意的是,RocksDB支持多种选项设置和配置,例如存储引擎、压缩方式、持久化方式等,可以根据实际需求进行设置。

RocksDB是一个非常高效、稳定、可靠的键值存储库,其基本接口使用方法相对简单,可以方便地进行键值存储和访问操作,适用于需要高性能键值存储的各种场景。
在这里插入图片描述

这篇关于RocksDB的安装以及基本接口的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/225809

相关文章

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

使用Python实现操作mongodb详解

《使用Python实现操作mongodb详解》这篇文章主要为大家详细介绍了使用Python实现操作mongodb的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、示例二、常用指令三、遇到的问题一、示例from pymongo import MongoClientf

SQL Server使用SELECT INTO实现表备份的代码示例

《SQLServer使用SELECTINTO实现表备份的代码示例》在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误,在SQLServer中,可以使用SELECTINT... 在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误。在 SQL Server 中,可以使用 SE

使用Python合并 Excel单元格指定行列或单元格范围

《使用Python合并Excel单元格指定行列或单元格范围》合并Excel单元格是Excel数据处理和表格设计中的一项常用操作,本文将介绍如何通过Python合并Excel中的指定行列或单... 目录python Excel库安装Python合并Excel 中的指定行Python合并Excel 中的指定列P

浅析Rust多线程中如何安全的使用变量

《浅析Rust多线程中如何安全的使用变量》这篇文章主要为大家详细介绍了Rust如何在线程的闭包中安全的使用变量,包括共享变量和修改变量,文中的示例代码讲解详细,有需要的小伙伴可以参考下... 目录1. 向线程传递变量2. 多线程共享变量引用3. 多线程中修改变量4. 总结在Rust语言中,一个既引人入胜又可

golang1.23版本之前 Timer Reset方法无法正确使用

《golang1.23版本之前TimerReset方法无法正确使用》在Go1.23之前,使用`time.Reset`函数时需要先调用`Stop`并明确从timer的channel中抽取出东西,以避... 目录golang1.23 之前 Reset ​到底有什么问题golang1.23 之前到底应该如何正确的

详解Vue如何使用xlsx库导出Excel文件

《详解Vue如何使用xlsx库导出Excel文件》第三方库xlsx提供了强大的功能来处理Excel文件,它可以简化导出Excel文件这个过程,本文将为大家详细介绍一下它的具体使用,需要的小伙伴可以了解... 目录1. 安装依赖2. 创建vue组件3. 解释代码在Vue.js项目中导出Excel文件,使用第三

Linux alias的三种使用场景方式

《Linuxalias的三种使用场景方式》文章介绍了Linux中`alias`命令的三种使用场景:临时别名、用户级别别名和系统级别别名,临时别名仅在当前终端有效,用户级别别名在当前用户下所有终端有效... 目录linux alias三种使用场景一次性适用于当前用户全局生效,所有用户都可调用删除总结Linux