ToplingDB 分布式 Compact:天然的协同

(一)背景
ToplingDB 是 topling 开发的 KV 存储引擎,fork 自 RocksDB,进行了很多改造,其中一个最重要的功能是分布式 Compact,将 Compact 从 DB 结点转移到由多个 DB 共享的计算集群中执行,实现了降本增效的目的。系列文章:

MyTopling 分布式 Compact(一):从多线程到多进程
MyTopling 分布式 Compact(二):CompactionFilter
MyTopling 分布式 Compact(三):PropertiesCollector
(二)多进程
善战者无赫赫之功,只要选对了方向,后面的事情就自然而然地水到渠成,兵不血刃。

在 分布式 Compact(一) 中,我们将 Compact 服务实现为多进程,为了配合 Compact 服务的多进程架构,我们把 ToplingZipTable 的压缩 Pipeline 也拆分成独立的进程。

(三)Compact 中反查 DB
在一些应用中(例如 pika、kvrocks 等等),CompactionFilter 需要反查 DB(使用 DB::Get) 获取元数据,而在 Compact 服务中,只有 SST,没有 DB 对象,这就使得 CompactionFilter 无法在 Compact 服务中工作。

在 Todis 中,我们通过事先把 CompactionFilter 反查会用到的元数据捞出来,然后在 Compact 服务中访问,代替原本的 DB::Get,为此我们还对 Todis 的数据进行了针对性的编码。

在 kvrocks 中,因为数据的组织方式,无法通过编码在 Compact 服务中有效地代替原本的 DB::Get,所以,只有 metadata 才能支持分布式 Compact。

kvrocks 中各种数据类型的 metadata 保存在一起,如果照搬 todis 的方案,事先捞数据,捞到的元数据很可能 99.9% 都是无用的元数据,例如 compact hash 数据时,事先捞出来的元数据可能大都是 string 数据。
(四)ToplingZipTable 独立的压缩进程
既然 ToplingZipTable 的压缩 Pipeline 已经拆分成独立的进程,那么,我们就可以充分利用这一点:

生成 ToplingZipTable 需要两遍扫描
在第一遍扫描中收集各种统计信息,并且把(解压后的)数据保存到了临时文件中
在第二遍扫描中读取临时文件,压缩数据,生成 ToplingZipTable 的 SST,这一步占了绝大多数的 CPU 消耗
原本这些都是在同一台 Compact 服务器上运行的,如果:

在 DB 服务器上运行第一遍扫描:可以在 CompactionFilter 中执行 DB::Get
在 Compact 服务器上运行第二遍扫描:承接最消耗 CPU 的计算
这个方案确实能以最优雅的方式解决问题,但是相比完全的分布式 Compact 也有缺点:

第一遍扫描仍然要消耗 DB 结点的 CPU
通过网络传输的数据是解压后的数据,要消耗更多的网络带宽
(五)结语
李靖消灭突厥,仅用数千人的军队,3个月就完事,每一件事情,好像都是那么自然而然地就发生了,然后就胜利了。

将 Compact 服务改造成多进程的时候,我们也并没有想着将来要把第一遍和第二遍扫描分离到不同的机器上,而后来事情就自然而然地发生了……

【完】

你可能感兴趣的:(ToplingDB 分布式 Compact:天然的协同)