RocksDB之Column Families(列族)与 LSM Tree

2023-10-27

 1. Column Families

        列族(Column Families)是rocksdb3.0提出的一个机制,用于对同一个数据库的记录(键值对)进行逻辑划分。默认情况下所有的记录都会存储在一个默认列族里:

ROCKSDB_NAMESPACE::kDefaultColumnFamilyName

列族具有的属性
        1)可以跨列族进行原子写,弥补了rocksdb在单个进程内只能操作一个数据库的问题。
        2)在不同的列族,提供数据库的一致性视图。
        3)可以对列族进行独立配置。
        4)动态添加和drop列族。

1)列族的配置

        ColumnFamilyOptions用于配置列族;

        DBOptions用于数据库粒度的配置;

        Options继承了ColumnFamilyOptions, DBOptions,因此Options可以执行上述两种配置。

2)主要操作

       每个列族通过句柄类ColumnFamilyHandle进行操作,包括列族的创建和销毁都要使用ColumnFamilyHandle完成。
        创建列族,下列代码就创建了一个名为"new_cf"的列族:

ColumnFamilyHandle *handl;
db->CreateColumnFamily(ColumnFamilyOptions(), "new_cf", &handl);
db->DestroyColumnFamilyHandle(handl);

        使用列族,基于列族打开数据库,和常规的方式不同。具体来说,如果我们以读写模式打开数据库,则必须要给open传入所有的列族,否则open方法会返回Status::InvalidArgument()。

每个列族通过ColumnFamilyDescriptor表示,这个类包含了{列族名,ColumnFamilyOptions}。

下列代码通过读写模式打开了一个包含所有列族的数据库:

vector<ColumnFamilyDescriptor> colume_families;
colume_families.push_back(ColumnFamilyDescriptor(ROCKSDB_NAMESPACE::kDefaultColumnFamilyName, ColumnFamilyOptions()));
colume_families.push_back(ColumnFamilyDescriptor("new_cf"), ColumnFamilyOptions())
vector<ColumnFamilyHandle *> cf_handles;
Status s = db->open(DBOptions(), DB_PATH, colume_families, &cf_handles, &db);

       如果使用只读模式打开数据库,那么可以只传入我们需要读取的列族,不过默认的列族是必须要传入给open函数的

// open db read only
column_families.push_back(ColumnFamilyDescriptor("new_cf", ColumnFamilyOptions()));
column_families.push_back(ColumnFamilyDescriptor(kDefaultColumnFamilyName, ColumnFamilyOptions()));
s = DB::OpenForReadOnly(DBOptions(), kDBPath, column_families, &handles, &db);
assert(s.ok());
s = db->Get(ReadOptions(), handles[0], Slice("key2"), &value1);
assert(s.ok());

3) WriteBatch

       通过WriteBatch我们可以原子的操作不同的列族,例如可以通过handles[0]去删除handles[1]插入的键值对{"key": "value"}

  // put and get from non-default column family
  s = db->Put(WriteOptions(), handles[1], Slice("key"), Slice("value"));
  assert(s.ok());
  std::string value;
  s = db->Get(ReadOptions(), handles[1], Slice("key"), &value);
  assert(s.ok());

  // atomic write
  WriteBatch batch;
  batch.Put(handles[0], Slice("key2"), Slice("value2"));
  batch.Put(handles[1], Slice("key3"), Slice("value3"));
  batch.Delete(handles[0], Slice("key"));
  s = db->Write(WriteOptions(), &batch);
  assert(s.ok());

4) 原理和实现

        简单的说,不同的列族是共享WAL的,但是memtable和SST file是隔离的。

2. LSM Tree

       rocksdb基本可以认为就是对LSM Tree的实现,因此LSM Tree对于rocksdb是非常重要的。

LSM Tree的设计可以参考论文:

1996, The Log-Structured Merge-Tree (LSM-Tree)
2014, A Comparison of Fractal Trees to Log-Structured Merge (LSM) Trees
2017, WiscKey: Separating Keys from Values in SSD-conscious Storage, TOS
2019, LSM-based Storage Techniques: A Survey

in-place/out-of-place

        数据的存储方式,可以分为两种:in-place update和out-of-place update,LSM Tree是out-of-place update的方式,而in-place update的典型代表是B+树。

        in-place update的方式,进行数据的写入/修改/删除操作时,是会对硬盘上的已有数据进行修改的,例如写入新数据时,为了维护B+树的结构,可能需要进行节点的分裂,另外,为了维护B+树的结构,写入的数据可能分布在不同的位置,会有比较多的随机io。

        out-of-place update的意思,就是说进行数据的写入/修改/删除操作时,并不对硬盘上的已有数据进行修改,而是先在内存中进行记录(写入/修改就记录数据内容,删除就记录需要删除的key),在达到一定的数据量后,生成一个新的文件,所以硬盘中可能同时存在新的和旧的数据(一般kv存储要求key是唯一的,新写入key0 value1后,旧的key0 value0应当失效,删除掉旧的数据,或者使其无法被读取出来)。为了避免占用的硬盘空间不停上升,以及存在重复数据导致的搜索效率下降,需要定期/不定期的处理重复数据,LSM Tree的处理方法是执行compaction,即选择一些文件进行合并,删除重复的数据后,生成新的不包含重复内容的文件。由于写入和compaction时,写入的都是完整的文件,所以随机io很少,都HDD和SSD来说是比较友好的。但是由于存在compaction操作,一个数据可能被重复读写多次,所以会造成执行io的数据量比实际写入的数据量要大几倍甚至几十倍,也就是写放大问题。

compaction

        compaction是LSM Tree进行数据维护的核心工作,compaction的执行主要分为两种策略:Leveling Merge Policy和Tiering Merge Policy。

参考链接:https://blog.csdn.net/xuhaitao2

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RocksDB之Column Families(列族)与 LSM Tree 的相关文章

随机推荐

  • 【跑实验07】RuntimeError: Argument #6: Padding size should be less than the corresponding input dimension

    最近在尝试跑实验的时候 我们的部分代码为 patch h 28 patch w 28 feat dim 768 transform T Compose T GaussianBlur 9 sigma 0 1 2 0 T Resize patc
  • 暗黑战神学习笔记

    暗黑战神游戏开发游戏学习笔记 第一章 初始场景与UI界面制作 光照系统 有哪些参数可以设置光源 1 点光源 2 window界面下的LightSetting 光照系统的优化方法 Animation系统 第二章 UI逻辑框架与配置文件 第三章
  • 【线性代数】从矩阵分块的角度理解矩阵乘法

    一 矩阵分块法介绍 概念 例 二 使用矩阵分块法计算矩阵的积 1 分块矩阵计算的数学步骤 使用Numpy计算例1 import numpy as np A np mat 1 0 0 0 0 1 0 0 1 2 1 0 1 1 0 1 B n
  • C++智能指针——auto_ptr详解

    前言 从之前智能指针的介绍中可以了解到智能指针主要作用是管理内存 避免内存泄漏和悬垂指针 之前介绍的不管是智能指针与引用计数详解还是智能指针与句柄详解 其核心就是通过一个类来管理被new出来的对象 具体的技术就是靠引用计数 auto ptr
  • Android Studio系列:安装并使用JetBrains Mono字体

    下载jetbrains mono字体 https www jetbrains com lp mono 解压 打开JetBrainsMono 2 242 fonts ttf 全选 然后安装 重启Android studio 一定要重启 然后选
  • 做SLAM实验时g2o的安装问题cmake的版本问题及git下载历史版本代码方法总结

    博主之前跑了ORBSLAM2做了相关实验 半年没碰之后 又重新来弄发现 WTF g2o用不了 cmake版本过低无法编译 直接修改CMakeLists txt文件还不行 好吧 我屈服了 升级cmake吧 升级到了3 2爽歪歪腰不酸了腿也利索
  • STM32使用HAL库BH1750光照度传感器

    开发环境 单片机 STM32F103C8T6 光照度传感器 BH1750 IDE KEIL STM32CUBEMX 单片机配置 1 STM32CUBEMX BH1750代码 1 头文件 BH1750 光照数据计算 LUX LUX 读取数据
  • JS与PHP通过RSA加密传输密码

    JS与PHP通过RSA加密传输密码 第一次写加密传输时网上看了一些博客将如何实现的 但实际过程中碰到了一些麻烦 一直没成功 现在搞定了来总结一下以便以后参考 实现主要都是参考http www ohdave com rsa 提供的开源代码及d
  • 算法—二叉树递归遍历

    测试的二叉树的结构 root lfb1 rtb1 rtb2 控制台输出的遍历结果 从根节点开始 前序遍历此二叉树 root lfb1 rtb1 rtb2 从根节点开始 中序遍历此二叉树 lfb1 root rtb1 rtb2 从根节点开始
  • 思考:语义过程

    2020 06 14 我有点明白泛化过程的含义了 当时也在阿里的那个文章中看到过 就是说 现在很多机器学习的泛化能力差在网络安全方面 泛化能力 我的理解就是 如果是想模型硬性的记住一些东西 那他就没有泛化能力 但是如果你能够有一些泛化能力
  • 【AIGC】一款离线版的AI智能换脸工具V2.0分享(支持图片、视频、直播)

    随着人工智能技术的爆发 AI不再局限于大语言模型 在图片处理方面也有非常大的进步 其中AI换脸也是大家一直比较感兴趣的 但这个技术的应用一直有很大的争议 今天给大家分享一个开源你的AI换脸工具2 0 只需要一张所需脸部的图像 无需数据集 无
  • Java使用GDAL

    在使用Java处理图像时使用Gdal 为了保持软件在Windows Linux的通用性 本文着重介绍Windows和Linux环境的gdal配置 为了简便期间 使用gdal 2 2 3 一 Windows Windows下gdal配置比较简
  • Android混淆机制

    java代码的混淆 常见的混淆的方式有两种 Proguard 免费 和 DexGuard 要钱 Proguard 与 DexGuard 的关系 DexGuard 是基于 ProGuard 的 这就是为什么它是如此的原因很容易升级到DexGu
  • css 实现文字渐变以及文字颜色流动

    文字渐变需要了解以下属性 background image 背景色 background clip 此属性规定背景的绘制区域 有四个值 border box 背景被裁剪到边框盒 padding box 背景被裁剪到内边距框 content
  • 【C语言】32个关键词

    目录 一 auto 二 short 三 int 四 long 五 float 六 double 七 char 八 struct 九 union 十 enum 十一 typedef 十二 const 十三 unsigned 十四 signed
  • linux top命令VIRT,RES,SHR,DATA的含义

    VIRT virtual memory usage 虚拟内存1 进程 需要的 虚拟内存大小 包括进程使用的库 代码 数据等2 假如进程申请100m的内存 但实际只使用了10m 那么它会增长100m 而不是实际的使用量 RES residen
  • 165.比较版本号

    165 比较版本号 给你两个版本号 version1 和 version2 请你比较它们 版本号由一个或多个修订号组成 各修订号由一个 连接 每个修订号由 多位数字 组成 可能包含 前导零 每个版本号至少包含一个字符 修订号从左到右编号 下
  • AOD相关机制

    AOD的概念 AOD 即A lways O n D isplay 是android一种低功耗的显示模式的一种应用 他能保证屏幕某块区域一直亮 该应用开启时绘制的频率会低于正常的频率 由于AOD现实的不是和正常的亮屏之后显示的一样 只 会显示
  • LuCI 支持多语言,并设置简体中文为默认语言

    安装LuCI语言包 LuCI gt Modules gt Translations gt English en Chinese zh cn Taiwanese zh tw 修改源配置文件 feeds luci modules luci ba
  • RocksDB之Column Families(列族)与 LSM Tree

    1 Column Families 列族 Column Families 是rocksdb3 0提出的一个机制 用于对同一个数据库的记录 键值对 进行逻辑划分 默认情况下所有的记录都会存储在一个默认列族里 ROCKSDB NAMESPACE