继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Recluster Table | RFC 解读

Databend
关注TA
已关注
手记 43
粉丝 3
获赞 5

背景

Databend Clustering 的设计受到 Snowflake Data Clustering 和 Oracle Attribute Clustering 的启发。

注:这里的 Clustering 是分组、聚类的意思,下文将译为聚类。

聚类后的表会根据表中某一组列的值,以某种顺序存储数据。聚类有利于分区的消除(partition elimination)和文件碎片整理(file defragmentation)。默认情况下,数据是按照自然维度存储在表中的。因此,需要根据聚类键(cluster key)对表进行重聚类。另一方面,即使表已经聚类过,数据得到有效地组织,但如果不断地写入新的数据,聚类情况会随着时间的推移而变差。因此,有必要增加重聚类(recluster)操作。

设计

如果计划了解更详细的原理和图景,请参考 探索 Snowflake auto clustering 设计 一文。

执行全表排序的成本非常高,尤其是对于不断有新数据流入的表。为了在高效剪枝和低成本之间取得平衡,只需要对表进行粗略排序而不是完全排序。因此,在观测指标 一节中引入了两个指标来确定表是否已经有效聚类。重新聚类的目的是为了减少重叠 "overlap"和深度 "depth"

为了避免对同一份数据进行多次搅动,这里将数据块划分到不同的层(level),就像 LSM 树一样。那么重聚类就与 LSM 树的压缩操作类似。层表示该块中的数据被聚类的次数。重聚类操作是在同一层上进行的。

pub struct ClusterStatistics {
    ... ...
    pub level: i32,
}

重聚类操作的工作流程可以划分为两个任务:块选择(Block Selection)和块合并(Block Merge)。

语法

alter table [if exists] tbl_name recluster [final] [where condition]

如果指定 "final",那么优化将会反复执行直到该表的聚类程度足够好。否则,重聚类的工作流程将只会运行一次。

观测指标

  • "overlap"与指定块重叠的块数。
  • "depth"在同一点重叠的块数。这些点是从聚类值域范围中的最小值和最大值中收集的。

块选择

新流入的数据的初始层是第 0 层(level 0)。我们首先要关注的就是这些较新的数据,换句话说,选择操作优先在第 0 层执行。这样做的优点是可以减少写放大。1.计算每个点的深度和重叠的块数,汇总得到 "avg_depth" 。这个算法已经反映在 system$clustering_information 中,这里不再进行复述。avg_depth 的理想结果是 1 。为了实现粗略排序,需要定义一个阈值(threshold)或者是一个比率(ratio)("threshold = blocks_num * ratio")。只要 "avg_depth" 不大于该阈值。就认为这一层中的块的聚类程度足够好,那么我们将对下一层执行块选择。2.选择深度最大的点范围(一个或多个)并选择该范围所覆盖的区块作为下一次块合并的对象集。如果存在不止一个的深度最大的范围,那么在块合并过程中,可能会出现多组块并行的情况。

Tip:

  • 聚类键(cluster key)可能会在表中存在数据的时候创建/变更,故而可能存在一些没有按聚类键进行排序的块。目前计划是在重聚类过程中暂时忽略这些块。
  • 如果某个块的聚类键只有一个值(最大值和最小值相等,达到一个不变的状态)且行数 “row_num” 为 “1_000_000” ,那么重聚类时,将其所处层数设为 -1 并过滤掉。
  • 需要考虑选定的块的总大小,以免在排序时遇到内存溢出(out of memory, OOM)。

块合并

接下来就需要对收集到的块进行排序和合并。当合并后的块超过某个确定的阈值("1_000_000" 行)之后,就会进一步拆分成多个块。新生成的块放入下一层。然后,我们需要组织块并生成新的段和快照,最后更新表的元信息。如果在此期间有新的 DML 执行,当前的工作流将无法提交(commit),并返回错误。具体的处理流程仍然需要进一步的讨论。选择和合并操作会重复进行,直到表的聚类程度足够好。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP