Compaction

  • RocksDb的compaction,包含多种compaction Style, Compaction
  • Rocksdb默认采用Level-compaction
  • Manual-Compaction: 为什么需要manual,如何manual,以及影响manual的options设置。
  • compaction的相关option: rocksdb/options.h

Compaction触发时机

  • Options.disable_auto_compaction=true: 关闭rocksdb 的内置Compaction算法。

  • options.periodic_compaction_seconds=数值: 如果提供了CompactionFilter,通过设置非0数值,rocksdb会定期compaction对所有数据执行compactionFilter。执行完compactionFilter中被要求filter过滤掉的数据,会被标记为无效(delete marker),用户会查询不到,但是真正从磁盘上删除只有当发生compaction时才会被删除。如果不设置,默认30天,设置为0表示取消该功能。

  • 系统自动触发compaction: 比如level中文件数据量达到阈值。

  • 手动触发: 客户端主动调用DB::CompactRangeDB::CompactFiles方法会进行compaction. 阻塞时调用,直到compaction完成。nebula中ManualCompaction案例

  • Options::max_background_compactions: L1-LN, 在非0Level上多个compactions可以被并行执行, max_background_compactions控制了最大并行数量。

  • max_subcompactions大于1时,L0->L1, 我们会尝试把L0中数据文件分割开,用多线程合并到L1中。

RocksDb Level-compaction文件组织方式介绍

文件结构
  • rocksdb把磁盘上文件组织为多层,L0中数据是从memtable 中flush过来的
  • L0中的每个文件是有序的,但是非L0是整体有序的,即不仅每个文件有序而且文件之间也是有序的。
  • 非L0上的数据被分片保存在多个不同的sstable文件中
  • L0中key是有重复的,但是非L0中数据的key是没有重复的。所以在非L0中一个key只会包含在一个文件中。Lo中key可能包含在多个文件中。
  • 确定一个key的在该中的位置:先level中所有文件进行二分查找,找到那个file包含这个key,然后在这个file中再次二分查找,找到具体的位置。
  • 不同level中会包含相同的key, 高Level中的数据是旧的。


    非Lo是整体有序的

Compaction目的

  • 为了节省空间(删除无效的数据,合并文件数据,减少文件数量),和提高读性能(文件少了,检查key的效率就快了),会将磁盘上的sst文件定期进行合并compaction。
  • 每个非L0都有指定的文件总大小target_size,compaction就是要是每个非L0的大小维持在target_size之下,不同level的文件数量通常呈指数级增长。
image.png

Compaction

  • 当L0中文件到达level0_file_num_compaction_trigger时,L0中文件将会被Merged到L1中,因为L0中文件是有重叠的key,所以会将L0中所有文件都merge到L1中。


    image.png
  • L1中文件数量或者文件总size超过阈值后,会从L1中至少选择一个文件Merge到L2中key有交叠的文件中


    image.png

    image.png
  • 其它level同理,


    image.png
  • 如果需要,在非L0上多个compactions可以被并行执行, max_background_compactions控制了最大并行数量。

    image.png

  • 但是L0到L1的合并不可以并行操作,可能成为瓶颈,对于这种情况可以设置max_subcompactions大于1,这样,我们会尝试把数据文件分割开,用多线程去执行合并操作。

    L0到L1的多线程加速合并方式

定期compaction

  • 如果compaction filter存在的话,Rocksdb可以确保固定时间后数据都会经过compaction filter,这就是通过options.periodic_compaction_seconds参数控制,设置为0,则屏蔽该特性。如果使用默认值,rocksdb会将该值设置为30天。当进行compaction时,超过30天的数据都有资格去进行compaction(有些文件可能在compaction中会一直没有被选中),而且被compaction到原来的level中。
  • 如果没有compaction filter的compaction,其只会在合并过程中删除老的key,和保证level的文件大小,但是compaction filter的实现更多时为了根据业务逻辑实现对已有数据的删除/更新等操作。

参数设置

关于RocksDB层级关系中有几个相关的参数需要介绍:

参数 说明 默认值
write_buffer_size 限定Memtable的大小 64MB
level0_file_num_compaction_trigger 限定Level 0层的文件数量 4
target_file_size_base 每一层单个目标文件的大小 64MB
target_file_size_multiplier 每一层单个目标文件的乘法因子 1
max_bytes_for_level_base 每一层所有文件的大小 256MB
max_bytes_for_level_multiplier 每一层所有文件的乘法因子 10
level_compaction_dynamic_level_bytes 是否将Compact的策略改为层级从下往上应用 False
num_levels LSM的层级数量 7
  • 参数target_file_size_base和target_file_size_multiplier用来限定Compact之后的每一层的单个文件大小。target_file_size_base是Level-1中每个文件的大小,Level N层可以用target_file_size_base * target_file_size_multiplier ^ (L -1) 计算。target_file_size_base 默认为64MB,target_file_size_multiplier默认为1。

  • 参数max_bytes_for_level_base和max_bytes_for_level_multiplier用来限定每一层所有文件的限定大小。 max_bytes_for_level_base是Level-1层的所有文件的限定大小。Level N层的所有文件的限定大小可以用 (max_bytes_for_level_base) * (max_bytes_for_level_multiplier ^ (L-1))计算。max_bytes_for_level_base的默认为256MB,max_bytes_for_level_multiplier默认为10。

  • 参数level_compaction_dynamic_level_bytes用来指示Compact的策略改为层级从下往上应用。Target_Size(Ln-1) = Target_Size(Ln) / max_bytes_for_level_multiplier来限定大小:假如 max_bytes_for_level_base是 1GB, num_levels设为6。最底层的实际容量是276GB, 所以L1-L6层的大小分别是 0, 0, 0.276GB, 2.76GB, 27.6GB and 276GB。

更多参考 : RocksDB 的 Compact官网

  • 如果多个level都可以compaction,那么优先选择哪个level?优先选择level中的哪个file?
    RocksDB会对每一层设置一个score,score用来表示进行Compact的优先级,score越大,越需要进行Compact。
  • compaction的参数:compaciton 发生的阈值?level的大小阈值等

如何Compact

Compact操作主要包括两种:将内存中的Immutable Memtable通过Flush转为磁盘上的SST文件,还有一种就是将磁盘上的SST文件,根据相关规则属性由上层向下层的转存。

Immutable Memtable的Flush

Flush的入口在db/db_impl_compaction_flush.ccBackgroundFlush()

当Memtable写满之后被转为Immutable Memtable,RocksDB会将其Flush至Level-0层:

  • 选择所有尚未被Flush的Immutable Memtable保存至mems_

  • 选择第一个Immutable Memtable即mems_[0]的version信息代表这次Flush操作的元信息

  • 调用WriteLevel0Table(),进行Level-0文件的写入

  • 将Memtable中的table_range_del_table_通过BuildTable构造新的SST文件,之后通过Add()插入数据

    • 这里的Table用的是Column Family的option默认设定的的BlockBasedTable,代码在table/block_based_table_builder.cc,通过Add()依次插入SST文件中的Index, Filter, Data各个Block,这部分涉及SST的文件布局,稍后的博文会着重介绍。
  • 将变化的SST文件元信息写入manifest文件

SST文件的Compact

Compact的入口在db/db_impl_compaction_flush.ccBackgroundCompaction(),我们这里依然以Leveled Compaction为例,Compaction的执行函数在CompactionJob::Run():

  • RocksDB会将所有的Level计算出score,经过冒泡排序,首先寻找score最高的Level,如果Level的score大于1,则选择这个Level进行Compaction
  • 选择Level-N中尚未被Compaction的文件PickCompaction()
  • 对于Level-0层文件,RocksDB总是选择所有的文件进行Compact执行操作,因为Level-0层的文件之间,可能会有key范围的重叠
  • 对于Level-N层,通过GetOverlappingInputs()选取Level-N+1中与Level-N中重叠的两部分SST文件
  • RocksDB的CompactionIterator::SeekToFirst()将这两部分文件里所有被删除的且不存在于更高层的Level的key重复的keyCompaction Filter中过滤的key标记为为无效
  • 将所有有效的key写入新的SST文件
  • 合并结束,利用VersionEdit更新VersionSet,更新统计信息
    u
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容