暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MyTopling 分布式 Compact(三):PropertiesCollector

原创 Topling 2022-11-23
402

一、背景

MyTopling 是基于 ToplingDB 的 MySQL,分叉自 MyRocks,ToplingDB 则分叉自 RocksDB,兼容 RocksDB 接口,从而 MyTopling 可以复用 MyRocks 的大部分成果。

ToplingDB 和 MyTopling 目前都已经开源。

ToplingDB 的一个重要功能是 分布式 Compact(文档),去年我们实现了 托管Todis 的 分布式 Compact 支持。同样是基于 ToplingDB,分布式 Compact 自然也是 MyTopling 的重要功能。

系列文章:MyTopling 分布式 Compact(一):从多线程到多进程

系列文章:MyTopling 分布式 Compact(二):CompactionFilter

二、PropertiesCollector 介绍

在稍微复杂点的 RocksDB 应用中,都少不了使用 CompactionFilter,相对而言,PropertiesCollector 比 CompactionFilter 露脸的机会要少一些。

在 MyRocks 中,PropertiesCollector 的具体实现是Rdb_tbl_prop_coll,用来在 Flush/Compact 过程中来收集 SST 的统计信息,MyTopling 通过 ToplingDB 的 Web 可视化系统对此信息可视化如下:

原版 MyRocks 未保存 name 字段,这里的 name 字段是 MyTopling 新增的,我们为此还向 MyRocks 提交了一个 Pull Request: properties_collector: (un)materialize: add missing m_name

这个文件所属的 table 是 TPCC 的 bmsql_stock ,其主键是联合键 (s_w_id, s_i_id),上图中的 distinct per prefix 就是在该 SST 文件中,该 index_id=2170(对应 bmsql_stock) 的 cardinality,即 s_w_id 只有 2 个不同的值,而 (s_w_id, s_i_id) 联合键有 31003 个不同的值(与总行数 rows 相同)。

CREATE TABLE `bmsql_stock` (
  `s_w_id` int NOT NULL,
  `s_i_id` int NOT NULL,
  `s_quantity` int DEFAULT NULL,
  `s_ytd` int DEFAULT NULL,
  `s_order_cnt` int DEFAULT NULL,
  `s_remote_cnt` int DEFAULT NULL,
  `s_data` varchar(50) DEFAULT NULL,
  `s_dist_01` char(24) DEFAULT NULL,
  `s_dist_02` char(24) DEFAULT NULL,
  `s_dist_03` char(24) DEFAULT NULL,
  `s_dist_04` char(24) DEFAULT NULL,
  `s_dist_05` char(24) DEFAULT NULL,
  `s_dist_06` char(24) DEFAULT NULL,
  `s_dist_07` char(24) DEFAULT NULL,
  `s_dist_08` char(24) DEFAULT NULL,
  `s_dist_09` char(24) DEFAULT NULL,
  `s_dist_10` char(24) DEFAULT NULL,
  PRIMARY KEY (`s_w_id`,`s_i_id`));
复制

所以,和 Rdb_compact_filter 一样,Rdb_tbl_prop_coll 在执行过程中也需要访问数据字典。

三、Rdb_tbl_prop_coll 怎么支持分布式 Compact

原版 RocksDB 也有跟 ToplingDB 分布式 Compact 类似的东西,叫做 RemoteCompaction(Experimental),不支持插件化的 PropertiesCollector 。

ToplingDB 从一开始就通过 SidePlugin 来管理所有的 DB 配置信息,PropertiesCollector 就是其中之一,所以,在 MyTopling 中,我们只需要修改一点代码,将 Rdb_tbl_prop_coll_factory 和相应的序列化方法注册到 SidePlugin 体系即可,在 MyTopling 分布式 Compact(二):CompactionFilter 中我们以 CompactionFilter 为例,在架构上对此进行了详细阐述。在 Rdb_tbl_prop_coll 这里,我们深入一点细节,对整个流程进行一个梳理:

在 DB 结点上,Rdb_tbl_prop_coll 通过指针直接访问 ddl_manager 全局变量,在 Compact Worker 结点,脱离了 DB,没有相应的 ddl_manager(该全局对象仍然存在,但是个无效对象)。

我们对代码的修改方式依然是“微创手术法”,在 MyRocks 内部接口上,关键修改非常微小:

原本 MyRocks 辗转将全局变量 ddl_manager 的地址传给 Rdb_tbl_prop_coll,然后在 compact 过程中调用m_ddl_manager->safe_find,MyTopling 在此处改为调用 m_find_key_def

当然,麻烦的地方肯定不在这里,而是在 Compact Worker 结点上,find_key_def 怎么工作,整个 Rdb_tbl_prop_coll 又怎么“虚拟化”成象是在 DB 上一样执行的。

首先,Rdb_tbl_prop_coll_factory_SerDe 的准备工作:

DeSerialize 和 Serialize 执行的操作相对应,在 Compact Worker 上:

在 DB 上,DeSerialize 是在 Compact 即将结束时调用:

这其中每个环节都非常简单,甚至简单到“明显没有 Bug”。

其中的 DEBG 和 TRAC 都是最开始一股脑从 Todis 中的 CompactionFilter 拷过来的,实际上从未开启过。

上面有两个函数 write_key_def_rngread_key_def_all,这是是 MyTopling 为支持分布式 Compact 中传输数据字典而新增的,这里面的代码就不是那么“明显没有 Bug”了。好在使用了 topling-zip 中的序列化框架,使得代码简洁清晰了很多,Rdb_tbl_prop_coll_factory_SerDe 的 Serialize/DeSerialize 也用到了该序列化框架。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论