开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情
在前一篇文章juejin.cn/post/717289…我们研究了yugabytedb没有对TTL过期的SST做read file filter,也分析了yugabytedb没有去实现的原因:yugabytedb定位不是时序数据库,对SST的max、min TTL做filter只在有限场景下有用(时序数据库)。那么我们今天想看看关于TTL,yugabytedb做了哪些优化,这些优化是否可以被借鉴,我们从关于TTL 的flag出发,通过源码研究其本质。
--tablet_enable_ttl_file_filter
这个flag是标志是否打开 TTL 功能的文件过期。默认是关闭的。一切没有被默认打开的flag,在我看来应该都是有副作用,可能是性能损失,可能是功能开关。
对于具有default_time_to_live表属性的表,设置一个大小阈值,达到该阈值时文件将不再被考虑进行压缩。超过此阈值的文件仍将被视为过期。如果值为0则禁用。也就是说不需要compaction,而是直接被回收。
理想情况下,rocksdb_max_file_size_for_compaction应该在以合理的频率使数据过期和不创建太多 SST 文件(这会影响读取性能)之间取得平衡。例如,如果存储了 90 天的数据,请考虑将此标志设置为大致相当于一天数据的大小。
看到这个标志被打开后,compaction_file_filter_factory被创建,这个选项在原生rocksdb中是没有的,这里默认使用了DocDBCompactionFileFilterFactory实现。
if (FLAGS_tablet_enable_ttl_file_filter) {
rocksdb_options.compaction_file_filter_factory =
std::make_shared<docdb::DocDBCompactionFileFilterFactory>(retention_policy_, clock());
}
接下来,看看DocDBCompactionFileFilterFactory的实现,DocDBCompactionFileFilterFactory实际是构建了一个DocDBCompactionFileFilter,DocDBCompactionFileFilter将过滤掉任何最大HLC时间低于其max_ht_to_expire的文件并保留任何最大HLC高于该值的文件。table_ttl、history_cutoff和filter_ht都是在过滤器创建时记录的,用于对过滤器进行检查。
class DocDBCompactionFileFilter : public rocksdb::CompactionFileFilter {
public:
DocDBCompactionFileFilter()
rocksdb::FilterDecision Filter(const rocksdb::FileMetaData* file) override;
...
};
基于TTL过期的文件过滤需要从最早的文件到最新的文件进行,以防止与已经过期,但在后来的文件或后来的版本中被引用的墓碑值冲突。
也就是说,过滤SST文件时,如果从较新的文件开始(直接删除),可能会导致后面的过期墓碑或多版本重新生效?
max_ht_to_expire_表示创建过滤器时确定的过期截止时间。
history_cutoff表示删除数据不安全的时间戳。
table_ttl_表示表的当前默认生存时间。
filter_ht表示创建过滤器的时间戳。