目录
参数配置的关系
struct Options : public DBOptions, public ColumnFamilyOptions
struct ColumnFamilyOptions : public AdvancedColumnFamilyOptions
ImmutableDBOptions 就是不可变的一些参数
BlockBasedTableOptions 与上面没有关系,构建block cache的时候用
在 AdvancedColumnFamilyOptions 里面有个
TablePropertiesCollectorFactories table_properties_collector_factories
注意上面的TablePropertiesCollectorFactories 其实是一个vector 里面每个元素都是TablePropertiesCollectorFactory
ImmutableCFOptions 里面也有
Options::TablePropertiesCollectorFactories table_properties_collector_factories;
CompactOnDeletionCollector的作用
关于 NewCompactOnDeletionCollectorFactory
其实NewCompactOnDeletionCollectorFactory 只是一个方法,它返回了 CompactOnDeletionCollectorFactory 类。
而上面这个类的CreateTablePropertiesCollector方法返回了最终的 CompactOnDeletionCollector。
CompactOnDeletionCollector 就是一个sst的信息收集器,继承自 TablePropertiesCollector。
它的核心所用就是就是判断一个sst是否应该被标记为待合并。
他有三个参数
size_t sliding_window_size,
size_t deletion_trigger,
double deletion_ratio
具体来说就是,就是两个规则
- 如果连续sliding_window_size个key里面有超过deletion_trigger个key都是删除,那就认为这个sst可以标识为被删除。
- 如果整个stt里面删除key的数量除以总key的数量超过deletion_ratio,那就认为这个sst可以标识为被删除。
CompactOnDeletionCollector的内部实现
对于规则1的实现是在CompactOnDeletionCollector::AddUserKey里面
核心逻辑就是把sliding_window_size分成128个小段,当处理了sliding_window_size个key之后,128段也走完了,就把第1段的数据抛弃掉,接着处理第129段数据。
(上面的描述很差劲,但是代码就是这么个语义,sliding_window_size的语义就是一个滑动窗口,上文说的每个段就是滑动窗口里面的滑动窗口)
对于规则2的实现是在CompactOnDeletionCollector::Finish
这个比较简单,就不说了。
CompactOnDeletionCollector的外部调用
CompactOnDeletionCollector 本身的逻辑已经清楚了,那谁来调用它呢?
在AdvancedColumnFamilyOptions里面有一个 table_properties_collector_factories
我们要引入CompactOnDeletionCollectorFactory特性的时候,把它加到table_properties_collector_factories里面即可。
在GetIntTblPropCollectorFactory函数里面,会把我们设定的factory包装成一个个UserKeyTablePropertiesCollectorFactory,然后放到ColumnFamilyData的int_tbl_prop_collector_factories_里。
在构建sst的BuildTable方法里,传入了int_tbl_prop_collector_factories_
之后传递的逻辑大家自己看吧。
每次调用BlockBasedTableBuilder::Add方法内部都会调用NotifyCollectTableCollectorsOnAdd方法,最终调用到CompactOnDeletionCollector::AddUserKey方法
那CompactOnDeletionCollector的最终逻辑结构:是否需要标记待compact呢?
TableBuilder里面有个NeedCompact方法,sst写完之后,会调用 NeedCompact,把CompactOnDeletionCollector的结果写到FileMetaData里面的 marked_for_compaction。
如何影响compact源文件的选择
在VersionStorageInfo::ComputeCompactionScore 里面ComputeFilesMarkedForCompaction会记录哪一层的哪些文件被标记了marked_for_compaction。
之后就是LevelCompactionBuilder::SetupInitialFiles 里面的PickFilesMarkedForCompaction
另外这里大家可以注意到,在PickFilesMarkedForCompaction里,是覆盖了上层的start_level_inputs->files的。
如何影响compact源文件的选择 大家可以参考 拙作
谈谈RocksDB的Compaction1