AICon上海|与字节、阿里、腾讯等企业共同探索Agent 时代的落地应用 了解详情
写点什么

Apache Kylin 权威指南(六):Cuboid 剪枝优化

  • 2020-04-18
  • 本文字数:3380 字

    阅读完需:约 11 分钟

Apache Kylin权威指南(六):Cuboid剪枝优化

编者按:本文节选自华章科技大数据技术丛书 《Apache Kylin 权威指南(第 2 版)》一书中的部分章节。

Cuboid 剪枝优化

维度的组合

由之前的章节可以知道,在没有采取任何优化措施的情况下,Kylin 会对每一种维度的组合进行聚合预计算,维度的一种排列组合的预计算结果称为一个 Cuboid。如果有 4 个维度,结合简单的数学知识可知,总共会有 24=16 种维度组合,即最终会有 24=16 个 Cuboid 需要计算,如图 1 所示。其中,最底端的包含所有维度的 Cuboid 称为 Base Cuboid,它是生成其他 Cuboid 的基础。



图 1 四维 Cube


在现实应用中,用户的维度数量一般远远大于 4 个。假设用户有 10 个维度,那么没做任何优化的 Cube 总共会存在 210=1024 个 Cuboid,而如果用户有 20 个维度,那么 Cube 中总共会存在 220=1048576 个 Cuboid!虽然每个 Cuboid 的大小存在很大差异,但是仅 Cuboid 的数量就足以让人意识到这样的 Cube 对构建引擎、存储引擎来说会形成巨大的压力。因此,在构建维度数量较多的 Cube 时,尤其要注意进行 Cube 的剪枝优化。

检查 Cuboid 数量

Apache Kylin 提供了一种简单的工具供用户检查 Cube 中哪些 Cuboid 最终被预计算了,将其称为被物化(materialized)的 Cuboid。同时,这种工具还能给出每个 Cuboid 所占空间的估计值。该工具需要在 Cube 构建任务对数据进行一定的处理之后才能估算 Cuboid 的大小,具体来说,就是在构建任务完成“Save Cuboid Statistics”这一步骤后才可以使用该工具。


由于同一个 Cube 的不同 Segment 之间仅是输入数据不同,模型信息和优化策略都是共享的,所以不同的 Segment 中被物化的 Cuboid 是相同的。因此,只要 Cube 中至少有一个 Segment 完成了“Save Cuboid Statistics”这一步骤的构建,那么就能使用如下的命令行工具去检查这个 Cube 中的 Cuboid 的物化状态:


bin/kylin.sh org.apache.kylin.engine.mr.common.CubeStatsReader CUBE_NAME
CUBE_NAME 想要查看的Cube的名称
复制代码


该命令的输出如图 2 所示。



图 2 CubeStatsReader 的输出


在该命令的输出中,会依次打印出每个 Segment 的分析结果,不同 Segment 的分析结果基本趋同。在上面的例子中 Cube 只有一个 Segment,因此只有一份分析结果。对于该结果,自上而下来看,首先能看到 Segment 的一些整体信息,如估计 Cuboid 大小的精度(hll precision)、Cuboid 的总数、Segment 的总行数估计、Segment 的大小估计等。


Segment 的大小估算是构建引擎自身用来指导后续子步骤的,如决定 mapper 和 reducer 数量、数据分片数量等的依据,虽然有的时候对 Cuboid 的大小的估计存在误差(因为存储引擎对最后的 Cube 数据进行了编码或压缩,所以无法精确预估数据大小),但是整体来说,对于不同 Cuboid 的大小估计可以给出一个比较直观的判断。由于没有编码或压缩时的不确定性因素,因此 Segment 中的行数估计会比大小估计来得更加精确一些。


在分析结果的下半部分可以看到,所有的 Cuboid 及其分析结果以树状的形式打印了出来。在这棵树中,每个节点代表一个 Cuboid,每个 Cuboid 的 ID 都由一连串 1 或 0 的数字组成,数字串的长度等于有效维度的数量,从左到右的每个数字依次代表 Cube 的 Rowkeys 设置中的各个维度。如果数字为 0,则代表这个 Cuboid 中不存在相应的维度,如果数字为 1,则代表这个 Cuboid 中存在相应的维度。


除了最顶端的 Cuboid 之外,每个 Cuboid 都有一个父 Cuboid,且都比父 Cuboid 少了一个“1”。其意义是这个 Cuboid 是由它的父节点减少一个维度聚合得来的(上卷,即 roll up 操作)。最顶端的 Cuboid 称为 Base Cuboid,它直接由源数据计算而来。Base Cuboid 中包含了所有的维度,因此它的数字串中所有的数字均为 1。


每行 Cuboid 的输出除了 0 和 1 的数字串以外,后面还有每个 Cuboid 的具体信息,包括该 Cuboid 行数的估计值、该 Cuboid 大小的估计值,以及该 Cuboid 的行数与其父节点的对比(Shrink)。所有的 Cuboid 的行数的估计值之和应该等于 Segment 的行数估计值。同理,所有的 Cuboid 的大小估计值之和等于该 Segment 的大小估计值。


每个 Cuboid 都是在它的父节点的基础上进一步聚合产生的,因此理论上来说每个 Cuboid 无论是行数还是大小都应该小于它的父 Cuboid。但是,由于这些数值都是估计值,因此偶尔能够看到有些 Cuboid 的行数反而还超过其父节点、Shrink 值大于 100%的情况。在这棵“树”中,可以观察每个节点的 Shrink 值,如果该值接近 100%,说明这个 Cuboid 虽然比它的父 Cuboid 少了一个维度,但是并没有比它的父 Cuboid 少很多行数据。换言之,即使没有这个 Cuboid,在查询时使用它的父 Cuboid,也不会花费太大的代价。


关于这方面的详细内容将在后续 3.1.4 节中详细展开。

检查 Cube 大小

还有一种更为简单的方法可以帮助我们判断 Cube 是否已经足够优化。在 Web GUI 的“Model”页面中选择一个 READY 状态的 Cube,当把光标移到该 Cube 的“Cube Size”列时,Web GUI 会提示 Cube 的源数据大小,以及当前 Cube 的大小与源数据大小的比例,称之为膨胀率(Expansion Rate),如图 3 所示。



图 3 查看 Cube 的膨胀率


一般来说,Cube 的膨胀率应该为 0%~1000%,如果一个 Cube 的膨胀率超过 1000%,Cube 管理员应当开始挖掘其中的原因。通常,膨胀率高有以下几个方面的原因:


  • Cube 中的维度数量较多,且没有进行很好的 Cuboid 剪枝优化,导致 Cuboid 数量极多;

  • Cube 中存在较高基数的维度,导致包含这类维度的每一个 Cuboid 占用的空间都很大,这些 Cuboid 累积造成整体 Cube 体积过大;

  • 存在比较占用空间的度量,如 Count Distinct 这样的度量需要在 Cuboid 的每一行中都保存一个较大的寄存器,最坏的情况会导致 Cuboid 中每一行都有数十千字节,从而造成整个 Cube 的体积过大;


……


因此,遇到 Cube 的膨胀率居高不下的情况,管理员需要结合实际数据进行分析,可灵活地运用本章接下来介绍的优化方法对 Cube 进行优化。

空间与时间的平衡

理论上所有能用 Cuboid 处理的查询请求,都可以使用 Base Cuboid 来处理,就好像所有能用 Base Cuboid 处理的查询请求都能够通过直接读取源数据的方式来处理一样。但是 Kylin 之所以在 Cube 中物化这么多的 Cuboid,就是因为不同的 Cuboid 有各自擅长的查询场景。


面对一个特定的查询,使用精确匹配的 Cuboid 就好像是走了一条捷径,能帮助 Kylin 最快地返回查询结果,因为这个精确匹配的 Cuboid 已经为此查询做了最大程度的预先聚合,查询引擎只需要做很少的运行时聚合就能返回结果。每个 Cuboid 在技术上代表着一种维度的排列组合,在业务上代表着一种查询的样式;为每种查询样式都做好精确匹配是理想状态,但那会导致很高的膨胀率,进而导致很长的构建时间。所以在实际的 Cube 设计中,我们会考虑牺牲一部分查询样式的精确匹配,让它们使用不是完全精确匹配的 Cuboid,在查询进行时再进行后聚合。这个不精确匹配的 Cuboid 可能是 3.1.2 节中提到的 Cuboid 的父 Cuboid,甚至如果它的父 Cuboid 也没有被物化,Kylin 可能会一路追溯到使用 Base Cuboid 来回答查询请求。


使用不精确匹配的 Cuboid 比起使用精确匹配的 Cuboid 需要做更多查询时的后聚合计算,但是如果 Cube 优化得当,查询时的后聚合计算的开销也没有想象中的那么恐怖。以 3.1.2 节中 Shrink 值接近 100%的 Cuboid 为例,假设排除了这样的 Cuboid,那么只要它的父 Cuboid 被物化,从它的父 Cuboid 进行后聚合的开销也不大,因为父 Cuboid 没有比它多太多行的记录。


从这个角度来说,Kylin 的核心优势在于使用额外的空间存储预计算的结果,来换取查询时间的缩减。而 Cube 的剪枝优化,则是一种试图减少额外空间的方法,使用这种方法的前提是不会明显影响查询时间的缩减。在做剪枝优化的时候,需要选择跳过那些“多余”的 Cuboid:有的 Cuboid 因为查询样式永远不会被查询到,所以显得多余;有的 Cuboid 的能力和其他 Cuboid 接近,因此显得多余。但是 Cube 管理员不是上帝,无法提前甄别每一个 Cuboid 是否多余,因此 Kylin 提供了一系列简单工具来帮助完成 Cube 的剪枝优化。


图书简介https://item.jd.com/12566389.html



相关阅读


Apache Kylin权威指南(一):背景历史和使命


Apache Kylin权威指南(二):工作原理


Apache Kylin权威指南(三):技术架构


Apache Kylin权威指南(四):核心概念


Apache Kylin权威指南(五):Getting Started


2020-04-18 10:001591

评论

发布
暂无评论
发现更多内容

2022全网最详细的音视频开发学习路线,零基础到项目实战,从小白到音视频专家

Linux服务器开发

音视频 WebRTC ffmpeg 音视频开发 流媒体服务器开发

2022年3月中国数据库排行榜:TiDB “三连降”仍霸榜首,“常胜四将军”得分集体下跌

墨天轮

数据库 TiDB 国产数据库 KingBase gbase8a

Linux之netstat命令

入门小站

Linux

在线YAML转TOML工具

入门小站

工具

java高级用法之:调用本地方法的利器JNA

程序那些事

Java nio 程序那些事 3月月更

ENS 域名终极指南

devpoint

以太坊 eth 3月月更 ens

Redis现网那些坑:用个缓存,还要为磁盘故障买单?

华为云数据库小助手

redis GaussDB GaussDB ( for Redis ) 华为云数据库

高精度轻量级目标检测产业应用,实现多类通信塔识别

百度大脑

一周信创舆情观察(2.28~3.6)

统小信uos

如何打造极速数据湖分析引擎

StarRocks

数据库 数据分析 StarRocks

经验分享 | 如何搭建FAQ/用户培训手册

小炮

运营 客户服务

在充满挑战的时代天翼云以数字化加速市域社会治理现代化

天翼云开发者社区

翻译 | 解读首部 Kubernetes 纪录片

RadonDB

开源 Kubernetes RadonDB

基于云效代码管理的源码漏洞检测是怎样的?

阿里云云效

阿里云 代码 代码管理 源代码 Codeup

上讯信息正式加入openGauss社区

[架构实战营] 模块9设计

Vincent

「架构实战营」

星际营23期开始招募 门槛高,但是优秀项目可获得全额奖学金,敢来挑战吗?

创业邦

VuePress 博客优化之增加 Valine 评论功能

冴羽

JavaScript 前端 vuepress 博客搭建 Alogia

Flutter ChartSpace:通过跨端 Canvas 实现图表库

字节跳动终端技术

flutter 字节跳动 前端 canvas 图表库

天翼云发布云原生关系型数据库TeleDB for openGauss

天翼云开发者社区

华为云大数据轻模式体验:忘掉底层烦恼,专注数据开发

华为云开发者联盟

大数据 Serverless 数据湖 数据开发 华为云

Linux curl命令详解

学神来啦

云计算 Linux 运维 curl

东方电机打造大国重器 携手天翼云挺起智能制造新脊梁 智能制造的力量 东方电机的数字化前行之路

天翼云开发者社区

【51单片机】点亮LED灯(四种形式)

謓泽

3月月更

写给20几岁的程序员

shellc

财富 35岁

恒源云(GpuShare)_医学图像分割:MT-UNet

恒源云

深度学习 机器翻译 transform

极速体验|使用 Erda 微服务观测接入 Jaeger Trace

尔达Erda

云计算 微服务 云原生 PaaS 分布式架构

详细解读阿里云开源PolarDB总体架构和企业级特性

阿里云数据库开源

数据库 阿里云 polarDB

以数字化为引领天翼云助力中安公司应急管理云平台上线

天翼云开发者社区

人脸识别闸机惊艳美国运动员背后的黑科技是如何实现的?

天翼云开发者社区

不为人知的网络编程(十四):拔掉网线再插上,TCP连接还在吗?一文即懂!

JackJiang

网络编程 TCP/IP TCP协议 即时通讯IM

Apache Kylin权威指南(六):Cuboid剪枝优化_架构_Apache Kylin核心团队_InfoQ精选文章