聊聊RocksDB Compact

导语 对于 LevelCompact 策略,RocksDB会根据每一层不同的策略计算出CompactScore,根据CompactScore大小来决定那一层将会优先进行Compact,然后选择Level-N 和Level-(N+1)的文件进行Compact。如何计算CompactScore? 如何选择文件进行Compact?Compact有哪些参数?如何知道RocksDB当前的一个状态?

 

RocksDB是基于LSM结构的K-V存储引擎,由于数据文件采用Append Only方式写入,而对于过期的数据、重复的数据必然会存在有多份副本,这部分数据通过Compact的方式进行逐步的清理。 
那么这里好奇的提出几个问题,由这几个问题引出下文:

  1. RocksDB是如何进行Compact 的?
  2. Compact的时候这些文件是如何进行选择的?
  3. Compact在什么时候、或者什么条件下触发?
  4. 对于Compact我们能知道哪些信息?通过TRedis怎么查看这部分信息?
  5. 有哪些参数可以控制或者影响到Compact

由于我们的TRedis底层采用RocksDB存储引擎进行持久化,底层数据文件采用分层的方式管理,故这里讨论的Compact 基于Level Compact 。

数据怎么来?我们调用TRedis接口进行写数据时,数据会先写入到内存中的Memtable里边,当Memtable写满后会写入下一个Memtable,Memtable采用Skiplist结构以此保证数据按照Key的字典序进行排序,同时这个Memtable会被后台线程刷到磁盘文件–Level-0,当Level-0文件个数达到一定数量,Compact线程可能会进行Compact,由此产生Level-1,当Level-1文件总大小达到一定大小后, Compact线程可能会进行Compact,由此产生Level-2,…….

RocksDB对每一层的处理规则不太一样,由于Level-0层的数据直接由Memtable dump得到,从而不能保证Level-0层的每个文件Key的范围不能有交集,故对Level-0层的会进行特殊处理,而对于Level-1+层处理规则一样。

Level-0 层的文件在不停的从Memtable 中dump出来,那么何时才会把这些Level-0层的文件合并到Level-1 ? 
RocksDB对对每一层进行打分,分数从0~1000000,这个分数的大小决定了进行Compact 的优先级,分数越大,越先进行Compact。

那么这个分数如何计算出来?

  • 如果是Level-0层,会先算出当前有多少个没有进行Compact 的文件个数numfiles, 然后根据这个文件的个数进行判断,当numfiles<20 时,Score = numfiles/4;当24>numfiles>=20时,Score = 10000;当 numfiles>=24时,Score = 1000000
相关参数说明
level0_file_num_compaction_trigger4当有4个未进行Compact的文件时,达到触发Compact的条件
level0_slowdown_writes_trigger20当有20个未进行Compact的文件时,触发RocksDB,减慢写入速度
level0_stop_writes_trigger24当有24个未进行Compact的文件时,触发RocksDB停止写入文件,此时会尽快的Compact Level-0层文件
  • 如果是Level-1+层,会去计算每一层未进行Compact文件的总Size,然后再和这一层的”容量值”做对比,得到一个比值,这个值就是该层的 CompactScore ,也就是说对于Level-1+层,Compact 触发条件是看这一层文件的大小而不是个数。Score = level_bytes / MaxBytesForLevel(level)

对于Level-1+层,每一层的最大Bytes 是如何计算出来的?

Level-1 层 文件总大小由 max_bytes_for_level_base 参数控制,而 Level-2 层的大小通过: Level_max_bytes[N] = Level_max_bytes[N-1] * max_bytes_for_level_multiplier^(N-1)*max_bytes_for_level_multiplier_additional[N-1] 计算得出:

参数说明
max_bytes_for_level_base10485760用于指定Level-1 层总大小,超过这个值满足触发Compact条件
max_bytes_for_level_multiplier10每一层最大Bytes 乘法因子
max_bytes_for_level_multiplier_addtl[2]1Level-2 层总大小调整参数
max_bytes_for_level_multiplier_addtl[3]1Level-3 层总大小调整参数
max_bytes_for_level_multiplier_addtl[4]1Level-4 层总大小调整参数
max_bytes_for_level_multiplier_addtl[5]1Level-5 层总大小调整参数
max_bytes_for_level_multiplier_addtl[6]1Level-6 层总大小调整参数
if (i > 1) {level_max_bytes[i] = MultiplyCheckOverflow(MultiplyCheckOverflow(level_max_bytes[i - 1],max_bytes_for_level_multiplier),max_bytes_for_level_multiplier_additional[i - 1]);} else {level_max_bytes[i] = max_bytes_for_level_base;}

在进行Compact的时候,会选择哪些文件进行Compact操作呢?

对于Level-0层文件,RocksDB总是选择所有的文件进行Compact操作,因为Level-0层的文件之间,可能会有key范围的重叠。 
对于Level-N (N>1)层的文件,会先按照文件大小排序(冒泡排序),选出最大的文件,并计算这个文件Key 的起止范围,通过这个范围查找Level-N+1层文件,把选出的Level-N 文件和Level-N+1 文件做为输入,并且在Level-N+1新建一个或多个SST文件作为输出。 
可以通过设置max_background_compactions 大于1 来使用并行Compact,不过这个并行Compact 不能作用到Level-0层。

  // Find the compactions by size on all levels.
for (int i = 0; i < NumberLevels() - 1; i++) {double score = vstorage->CompactionScore(i);level = vstorage->CompactionScoreLevel(i);
assert(i == 0 || score <= vstorage->CompactionScore(i - 1));
if ((score >= 1)) {
c = PickCompactionBySize(mutable_cf_options, vstorage, level, score);
if (c == nullptr ||
ExpandWhileOverlapping(cf_name, vstorage, c) == false) {delete c;
c = nullptr;} else {
break;}}}

如何查看RocksDB内部状态?

一般情况下内部状态会定时dump出来存放到LOG文件里,这个时间可以通过:stats_dump_period_sec 来控制这个dump内部状态的频率,如果是TRedis V1.2.9 版本以上可以通过 rocksprop rocksdb.cfstats 得到这些信息:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/463350.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android入门逆引手册 - 12 评分条(RatingBar)的使用

这里介绍评分条android.widget.RatingBar类的使用。 ● 评分&#xff08;星&#xff09;的最大数的设置&#xff0c;调用setNumStars()方法。● 现在的评分的设置&#xff0c;调用setRating()方法。 例程源码(Java)[java]RatingBar ratingBar (RatingBar)findViewById(id.rati…

数据库事务的四大特性以及事务的隔离级别

本篇讲诉数据库中事务的四大特性&#xff08;ACID&#xff09;&#xff0c;并且将会详细地说明事务的隔离级别。 如果一个数据库声称支持事务的操作&#xff0c;那么该数据库必须要具备以下四个特性&#xff1a; ⑴ 原子性&#xff08;Atomicity&#xff09; 原子性是指事务包含…

程序员面试的一些注意点

一、前言 自己即将踏上求职的征程&#xff0c;所以整理一篇有关于程序员面试的小窍门&#xff0c;帮助自己和正在求职、即将求职的一些小伙伴跳过一些坑。 二、简历制作1. 不要放头像普通人大概率都不是帅哥美女&#xff0c;所以不想让外观成为评判标准的就不要放照片上去了。2…

如何解决数据倾斜问题?

转载&#xff1a;https://blog.csdn.net/Mr_HHH/article/details/89399518 今天在工作中遇到了数据倾斜的问题&#xff0c;一条SQL执行了8小时才执行完&#xff0c;看计划是先join再做distinct&#xff0c;卡在了join上&#xff0c;数据量比较大&#xff0c;并且重复数据比较多…

白盒测试不是测试,更不高级

测试不仅仅是软件概念&#xff0c;但白盒测试仅仅是软件概念。 上面这句话足以说明白盒测试不是测试&#xff0c;至少不等同于测试。 认为白盒测试更牛逼的一个常用论据是白盒测试需要对代码本身更高的熟悉程度&#xff0c;但说这样的话的人往往没有搞清楚测试究竟需要什么样的…

剑指Offer题解(Python版)

https://blog.csdn.net/tinkle181129/article/details/79326023# 二叉树的镜像 链表中环的入口结点 删除链表中重复的结点 从尾到头打印链表 斐波那契数列 跳台阶 变态跳台阶 矩形覆盖 把字符串转换成整数 平衡二叉树 和为S的连续正数序列 左…

Paypal 在线支付接口应用从零开始,第2节,[支付API原理及流程]

今天看看Paypal支付流程和简单的认证原理,我画了一张图.应该能表达这两点意思了我们的站点名字,为了好理解,暂且就定为西狐的网站吧.点此查看清晰原图恩,理论知识很重要哈,先把这图理解了,下一步我们编程使用沙盒测试就很简单了.如果想更多研究一下还可直接查看Paypal官方提供的…

C语言指针深度理解

指针是&#xff23;语言中广泛使用的一种数据类型。 运用指针编程是&#xff23;语言最主要的风格之一。利用指针变量可以表示各种数据结构&#xff1b; 能很方便地使用数组和字符串&#xff1b; 并能象汇编语言一样处理内存地址&#xff0c;从而编出精练而高效的程序。指针极大…

PLSQL DEVELOPER 使用技巧

为什么80%的码农都做不了架构师&#xff1f;>>> 1、右键菜单 在PL/SQL Developer&#xff08;下面简称PLD&#xff09;中的每一个文本编辑窗口&#xff0c;如SQL Window&#xff0c;Command Window和Porgram Window&#xff0c;右键点击某个对象名称&#xff0c;会…

为什么不能同时用const和static修饰成员函数?

const修饰的函数: 表示在该函数体内不能修改成员的值&#xff0c;会在函数中添加一个隐式的参数const this*. static修饰的函数没有this指针&#xff0c;与const的用法冲突。 但可以使用static和const修饰成员。 例子如下&#xff1a; class Singleton { public: stati…

对于一颗完全二叉树,要求给所有节点加上一个pNext指针,指向同一层的相邻节点;如果当前节点已经是该层的最后一个节点,则将pNext指针指向NULL;给出程序实现,并分析时间复杂度和空间复杂度。

typedef struct TNode { int data; TNode* left; TNode* right; TNode* next; }; //时间复杂度为O(n)&#xff0c;空间复杂度为O(n) void addNext(TNode* root) { if (!root) { return; } queue<TNode*> q; q.push(root); while (!q.empty()) { int levelL…

T-SQL DML学习笔记

1. select 语句的基本结构是 select -->From-->where group By Having Order By 2. Exists 条件 Exists 后面括号内的条件语句如果为真的话 这此次查询继续 &#xff0c;如Exists跟的条件语句没有查询到数据则前面语句块的查询不再执行下去 select province…

反射--Class获得

/* Java提供3种方式获得Class对象 * * 不同应用场景&#xff0c;需要不同的方式获得Class对象 * * 方式&#xff1a; * 1.通过字符串&#xff08;全限定类名&#xff09;获得 * 格式&#xff1a;Class clazz Class.forName("字符串"); * 全限定类名&#xff1a;包名…

Android Drawable绘图学习笔记

如何获取 res 中的资源 数据包package&#xff1a;android.content.res 主要类&#xff1a;ResourcesAndroid SDK中的简介&#xff1a;Class for accessing an application’s resources.Class for accessing an application’s resources. This sits on top of the asset mana…

在类中调用delete this问题

转载&#xff1a;https://blog.csdn.net/kuimzzs/article/details/81517451 很多时候&#xff0c;一些定义在类内的变量的生命周期在类外并不是很好的掌控&#xff0c;这样就很容易造成内存泄漏得到问题 比如以下代码&#xff1a; class Test { public: void foo(); pri…

C++中对多态的理解

1 多态&#xff1a;是指类中具有相似功能的不同函数&#xff0c;使用同一个名称来实现&#xff1b;是对类的行为再抽象&#xff1b;多态是通过重载函数和虚函数来实现的。 2 继承讨论的是类与类的层次关系&#xff0c;多态则是考虑在不同层次的类中&#xff0c;以及在同一个类…

C#.NET中的事件2

/** Created by SharpDevelop. * User: noo * Date: 2009-8-17 * Time: 15:34 * * 事件2 */usingSystem ;usingSystem .Windows .Forms ;classTest { staticvoidMain()//入口函数{ Form frmnewForm ();//新建一窗体frm.Text "我的窗体"; …

HTML学习之基础

HTML是网页的标记语言不是编程语言&#xff0c;有一些标记段组成。大小写不敏感&#xff0c;可以用常用的编辑器软件编写用浏览器打开即可 有不同的版本<!DOCTYPE html> <meta charset"utf-8">在<title>前为了能正常显示中文。 超链接&#xff1a;…

linux最基础的几个指令

cd 切换目录使用 pwd 显示当前目录路径 ls 列出目录内容 跟参数 -a 显示所有文件和目录 -A 显示所有文件包括隐藏-l 使用详细格式列出-d 显示目录名称而非内容-i 显示文件和目录的inode号-Z 显示文件和目录的上下文-R 子目录显示touch 创建文件或者改变文件时间 touch 2…

Advapi 登录类型8的错误

登录类型8&#xff1a;网络明文&#xff08;NetworkCleartext&#xff09; 这种登录表明这是一个像类型3一样的网络登录&#xff0c;但是这种登录的密码在网络上是通过明文传输的&#xff0c;WindowsServer服务是不允许通过明文验证连接到共享文件夹或打印机的&#xff0c;据我…