聊聊RocksDB Compact
| 导语 对于 LevelCompact 策略,RocksDB会根据每一层不同的策略计算出CompactScore,根据CompactScore大小来决定那一层将会优先进行Compact,然后选择Level-N 和Level-(N+1)的文件进行Compact。如何计算CompactScore? 如何选择文件进行Compact?Compact有哪些参数?如何知道RocksDB当前的一个状态?
RocksDB是基于LSM结构的K-V存储引擎,由于数据文件采用Append Only方式写入,而对于过期的数据、重复的数据必然会存在有多份副本,这部分数据通过Compact的方式进行逐步的清理。
那么这里好奇的提出几个问题,由这几个问题引出下文:
- RocksDB是如何进行Compact 的?
- Compact的时候这些文件是如何进行选择的?
- Compact在什么时候、或者什么条件下触发?
- 对于Compact我们能知道哪些信息?通过TRedis怎么查看这部分信息?
- 有哪些参数可以控制或者影响到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_trigger | 4 | 当有4个未进行Compact的文件时,达到触发Compact的条件 |
level0_slowdown_writes_trigger | 20 | 当有20个未进行Compact的文件时,触发RocksDB,减慢写入速度 |
level0_stop_writes_trigger | 24 | 当有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_base | 10485760 | 用于指定Level-1 层总大小,超过这个值满足触发Compact条件 |
max_bytes_for_level_multiplier | 10 | 每一层最大Bytes 乘法因子 |
max_bytes_for_level_multiplier_addtl[2] | 1 | Level-2 层总大小调整参数 |
max_bytes_for_level_multiplier_addtl[3] | 1 | Level-3 层总大小调整参数 |
max_bytes_for_level_multiplier_addtl[4] | 1 | Level-4 层总大小调整参数 |
max_bytes_for_level_multiplier_addtl[5] | 1 | Level-5 层总大小调整参数 |
max_bytes_for_level_multiplier_addtl[6] | 1 | Level-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 得到这些信息:
关于这些参数的解释如下:
列名 | 解释 |
---|---|
Level | Level0~N、或者合计值、或者Int |
Files | SST文件数量/待进行compact的SST文件数 |
Size(MB) | SST文件总大小 |
Score Read(GB) | 代表进行compact的优先级,分数越高越会优先进行compact |
Rn(GB) | 进行compact时,读当前层文件的大小 |
Rnp1(GB) | 进行compact时,读取下一层文件的大小 |
Write(GB) | compact完成时,写入文件的大小 |
Wnew(GB) | 新产生的数据大小: 写入到Level-(N+1)层的大小 - 从Level-(N+1)层读的大小 |
RW-Amp | 读写放大比例 : 总的读写 / 从Level-N层读的大小 |
W-Amp | 写放大比例: 写入Level-(N+1)层大小/从Level-N层的大小 |
Rd(MB/s) | 读文件速度: (bytes_readn + bytes_readnp1 )/((micros + 1) / 1000000.0) |
Wr(MB/s) | 写文件速度: bytes_written / ((micros + 1) / 1000000.0) |
Rn(cnt) | Files read from level N during compaction between levels N and N+1 |
Rnp1(cnt) | Files read from level N+1 during compaction between levels N and N+1 |
Wnp1(cnt) | Files written during compaction between levels N and N+1 |
Wnew(cnt) | Wnp1 - Rnp1 |
Comp(sec) | Compact 累计耗时:micros / 1000000.0 |
Comp(cnt) | Compact累计的次数 |
Avg(sec) | 平均每次Compact耗时 |
Stall(sec) | level0_slowdown 耗时 |
Stall(cnt) | level0_slowdown 累计次数 |
Avg(ms) | 平均每次Stall耗时 |
RecordIn | Compact 进行时,所有Level-N,Level-(N+1) 输入的entries数 |
RecordDrop | Compact 进行时: RecordIn - 输出到Level-(N+1) |
聊聊RocksDB Compact的更多相关文章
- 大容量类Redis存储--Pika介绍
嘉宾介绍 大家好,首先自我介绍一下,我是360 web平台-基础架构组的宋昭,负责大容量类redis存储pika的和分布式存储Bada的开发工作,这是我的github和博客地址,平时欢迎指正交流^^ ...
- RocksDB解析
0. 存储引擎基础 存储引擎的基本功能和数据结构 一个存储引擎需要实现三个基本的功能: write(key, value) ...
- Rocksdb Compaction原理
概述 compaction主要包括两类:将内存中imutable 转储到磁盘上sst的过程称之为flush或者minor compaction:磁盘上的sst文件从低层向高层转储的过程称之为compa ...
- Rocksdb引擎记录格式
Rocksdb是一个kv引擎,由facebook团队基于levelDB改进而来,Rocksdb采用LSM-tree存储数据,良好的读写特性以及压缩特性使得其非常受欢迎.此外,Rocksdb引擎作为插件 ...
- RocksDB介绍:一个比LevelDB更彪悍的引擎
关于LevelDB的资料网上还是比较丰富的,如果你尚未听说过LevelDB,那请稍微预习一下,因为RocksDB实际上是在LevelDB之上做的改进.本文主要侧重在架构上对RocksDB对LevelD ...
- NoSQL: Cassandra, HBase, RocksDB
转自: http://www.linkedin.com/pulse/nosql-cassandra-hbase-rocksdb-siddharth-anand I've had the pleasur ...
- rocksdb学习笔记
rocksdb是在leveldb的基础上优化而得,解决了leveldb的一些问题. 主要的优化点 1.增加了column family,这样有利于多个不相关的数据集存储在同一个db中,因为不同colu ...
- 承接上一篇,whale系统开篇,聊聊用户认证
写在前面 上次老猫和大家说过想要开发一个系统,从简单的权限开始做起,有的网友表示还是挺支持的,但是有的网友嗤之以鼻,认为太简单了,不过也没事,简单归简单,主要的还是个人技术的一个整合和实战. 没错,系 ...
- 聊聊Unity项目管理的那些事:Git-flow和Unity
0x00 前言 目前所在的团队实行敏捷开发已经有了一段时间了.敏捷开发中重要的一个话题便是如何对项目进行恰当的版本管理.项目从最初使用svn到之后的Git One Track策略再到现在的GitFlo ...
随机推荐
- 二、Windows基础数据类型
六.Windows Data Types 简介: 6.1.这些数据类型都是C语言数据类型的再次的进行包装. 6.2.因为考虑到如果使用的是C中的基础数据类型可能无法表示,想表示的精准的含义. 6.3. ...
- js原型链部分详细使用说明案例
1. 'index.html'文件 ```html <!DOCTYPE html> <html lang="en"> <head> <me ...
- 学习笔记:javascript 窗口对象(window)
1.窗口对象属性 属性 描述 closed 返回窗口是否已被关闭. defaultStatus 设置或返回窗口状态栏中的默认文本. document 对 Document 对象的只读引用.请参阅 Do ...
- [笔记]机器学习(Machine Learning) - 00.目录/大纲/写在之前
目录会根据我的学习进度而更新,给自己列一个大纲以系统地看待整个学习过程. 学习资料来源 学习的是Coursera上吴恩达(Andrew Ng)老师的机器学习视频(课程传送门,最近在"最强大脑 ...
- Ajax,纯Js+Jquery
AJAX:Asynchronous Javascript and xml 异步,Js和Xml 交互式网页开发 不刷新页面,与服务器交互 详情请参照Jquery工具指南用在浏览器端的技术,无刷新,通过X ...
- 【2017-05-21】WebForm跨页面传值取值、C#服务端跳转页面、 Button的OnClientClick属性、Js中getAttribute和超链接点击弹出警示框。
一.跨页面传值和取值: 1.QueryString - url传值,地址传值 优缺点:不占用服务器内存:保密性差,传递长度有限. 通过跳转页面路径进行传值,方式: href="地址?key= ...
- 【PHP】PHP从入门到精通(一)——想学习PHP的小伙伴的福利来了!
PHP从精通到入门 (一)PHP简介和基本知识 PHP(外文名:PHP: Hypertext Preprocessor,中文名:"超文本预处理器")是一种通用开源脚本语言.语法吸 ...
- MyBatis 3 User Guide Simplified Chinese.pdf
MyBatis 3 用户指南 帮助我们把文档做得更好… 如果你发现了本文档的遗漏之处,或者丢失 MyBatis 特性的说明时,那么最好的方法就 是了解一下这个遗漏之处然后把它记录下来. 我们在 wik ...
- DOM4J介绍与代码示例
DOM4J是dom4j.org出品的一个开源XML解析包.Dom4j是一个易用的.开源的库,用于XML,XPath和XSLT.它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JA ...
- itmacy_我的博客
开通博客的第一天,并不希望自己以后像写流水账一样来写自己的博客,而是希望每一篇博客,无论是转载还是原创,都是经过深思熟虑,并且有意义的...