接网站开发哪里好,网站建设排名优化公司,免费旅游网站模板,网站后台上传附件前言
StarRocks 中每次数据摄入都会生成一个新的数据版本#xff0c;而查询时需要将所有版本数据进行合并才能获得一个正确的结果#xff0c;如果历史数据版本太多#xff0c;那么查询时需要读取的文件数也会很多#xff0c;造成查询效率低下。因而 StarRocks 存在内部任务…前言
StarRocks 中每次数据摄入都会生成一个新的数据版本而查询时需要将所有版本数据进行合并才能获得一个正确的结果如果历史数据版本太多那么查询时需要读取的文件数也会很多造成查询效率低下。因而 StarRocks 存在内部任务定期将历史数据版本进行整合消除重复数据记录我们称之为 Compaction。
Compaction 是为了将不同版本的数据文件进行整合合并成大文件的动作减少系统中小文件数量进而提升查询效率。相比于存算一体表StarRocks 存算分离实现了新的 Compaction 调度机制表现为
Compaction 调度由 FE 发起BE执行。FE 按照 Partition 为单位来发起 Compaction 任务Compaction 会生成一个新版本也走导入的写数据、commit、publish version 这套完整流程
本文旨在描述 StarRocks 存算分离表 Compaction 基本实现原理帮助开发和运维人员能更好地理解并根据实际需要调整 Compaction 相关配置以在实践中取得更好地效果。
背景介绍
前面说过每次导入都会在 FE 内生成一个新版本而该版本被标记在 Partition 之上。一旦导入事务成功提交便会更新 Partition 的可见数据版本号Partition 的数据版本号单调递增。
需要注意的是一个 Partition 内可能存在多个 Tablet这些 Tablet 都共享相同的数据版本号即使一次导入可能只涉及其中部分 Tablet一旦导入事务成功提交Partition 下所有的 Tablet 的版本都会相应地得到提升。 例如上图中Partition X 内含 Tablet 1 ~ N当前的可见版本为12一旦产生新的导入事务 New Load Txn且该事务成功提交那么 Partition X 的可见版本就变成了 13。
基本框架
StarRocks 存算分离表 Compaction 由两个角色组成调度者Compaction Scheduer和执行者Compaction Executor。调度者通过 RPC 发起 Compaction 任务Compaction Job而执行者负责执行 Compaction Job。在 StarRocks 存算分离中FE 作为 Compaction Scheduler而 BE 或者 CN 都作为 Compaction Executor。每个 Compaction Excutor 内都存在一个线程池专门用于执行 Compaction Job。 Compaction Scheduer 调度
FE 上存在一个周期性运行线程 Compaction Scheduer负责调度发起所有的 Compaction Task。FE 以 Partition 为调度的基本单位。
FE 上掌握了每个 Partition 的 Compaction Score 信息该信息用来表示 Partition 内所有 Tablet 的需要进行 Compaction 的优先级Compaction Score 越高表示 Partition 需要合并的紧急程度越高。
每次 Compaction Scheduer 线程运行时会挑选出当前 Compaction Score 最高的 Partition并为这些 Partition 构造 Compaction Task。当然Compaction Scheduer 也会控制每次最多发起的 Compaction Task 数量。
构造 Compaction Task 的逻辑相对比较简单对于每个 PartitionScheduler 会获得其所有的 Tablet然后为每个 CN 构造一个 Compaction TaskTask 内包含需要在该 CN 上执行 Compaction 任务的 Tablet 列表然后发送 Task 给 CN 节点。
整个流程如下图所示 在上图中FE 上存在两个 Partition 需要执行 Compaction分别为 Partition X 和 Partition Y。Partition X 内含4个 Tablet1 ~ 4而 Partition Y 内含3个 Tablet5~7。
Scheduer 通过计算发现
Partition X 内Tablet-2 和 Tablet-4 位于相同的 CN-1而 Tablet-1 和 Tablet-3 位于相同的 CN-2于是为 Partition X 构造了两个 Compaction TaskTask-1 与 Task-2其中 Task-1 内包含 Tablet-2 和 Tablet-4而 Task-2 内包含 Tablet-1 和 Tablet-3。 Partition Y 内Tablet-5 和 Tablet-7 位于相同的 CN-1而 Tablet-6 位于另外一个CN-2于是为 Partition Y 也构造了两个 Compaction TaskTask-3 与 Task-4其中 Task-3 内包含 Tablet-5 和 Tablet-7而 Task-4 内包含 Tablet-6。 最终每个 Task 被发往自己所属的 CN。 Compaction Executor 执行 Task
前面说过FE 的 Compaction Scheduler 生成 Compaction Task并发往 CN / BE 节点。CN / BE 节点上存在专有线程池来处理这些 Task且线程池数量可配置即将支持动态配置。每个线程会从 Compaction Task 任务队列中获取下一个要被执行的 Task。所谓 Compaction其本质是将多个数据文件进行整理合并删除其中的重复记录并形成一个更大的数据文件。如下图所示 例如上图中version 1 和 version 2 数据文件进行 Compaction 后消除了 version 1 中的旧版本数据id 2, value 11, id 5, value 30最终生成了新的数据版本文件 version 3。 Compaction 后的数据清理
目前 StarRocks 存算分离表使用了数据多版本技术整体上的存储结构如下图所示 上图中共产生了三次数据导入事务其中
Load Txn 1: 在事务数据写入阶段生成了新数据文件 file 1 file 2且该事务提交后生成了 Tablet Meta V1其中记录该版本可见的文件列表为 {file-1, file-2}Load Txn 2: 在事务数据写入阶段生成了新数据文件 file 3 file 4。在提交时根据前一个版本即 Tablet Meta V1然后加上本次导入事务生成的新数据文件file-3 file-4生成了新的 Tablet Meta V2因此该版本可见的文件列表为 {file-1, file-2, file-3, file-4}Load Txn 3: 在事务写入阶段产生了新数据文件 file 5。该事务提交时根据前一个版本即 Tablet Meta V2然后加上本次导入事务生成的新数据文件file-5产生了新的 Tablet Meta V3因此该版本的可见文件列表为 {file-1, file-2, file-3, file-4, file-5}
除了用户导入事务产生了新的数据版本在存算分离表中系统后台 Compaction 任务也会产生新数据版本。Compaction 的目的有二: 1). 将多个版本的小文件合并为大文件减少查询时的随机 IO 次数2). 消除重复数据记录减少数据总量。在存算分离表中每次 Compaction 也会产生一个全新的版本。依然以上面为例假如在上面 Txn 3 之后新的事务 Txn 4 为一次 Compaction 任务并且将 file1 ~ file4 这4个文件合并成为 file-6那么该事务提交时生成的新版本 Tablet Meta V4 内记录的文件列表为 {file-5, file-6}。 观察上例并思考可知如果系统在运行过程中一直不会进行 Compaction。那么系统中的数据文永远也无法被删除。试想上例中我们可以将 Tablet Meta V1Tablet Meta V2 文件删除但我们无法删除 file-1、file-2、file-3 以及 file-4因为这些文件依然被 Tablet Meta V3 所引用。但有了数据合并Compaction后情况就变得不一样了。上例中由于发生了一次 Compaction上图中的 Compact Txn 4将 file-1、file-2、file-3、file-4 合并生成了新文件 file-6 并生成了新的 Tablet Meta V4由于 file-1 至 file-4 中的内容已经在 file-6 中存在因而一旦版本 V1、V2、V3 不再被访问file-1 至 file-4 便可以被安全删除。此时的数据版本情况如下图所示 因此综合上面的讨论我们可以发现只有在 Compaction 完成后原始的数据文件方可被删除。因而判断数据文件能否安全删除的最直观的规则是该数据文件不再被任何 Tablet Meta 所引用。