剪枝的同时别减掉了性能

剪枝的同时别减掉了性能

“随着维度数目的增加,Cuboid 的数量会爆炸式地增长。为了缓解 Cube 的构建压力,Apache Kylin 引入了一系列的高级设置,帮助用户筛选出真正需要的 Cuboid。这些高级设置包括聚合组(Aggregation Group)、联合维度(Joint Dimension)、层级维度(Hierachy Dimension)和必要维度(Mandatory Dimension)等。”

正如上述官方文档提到的,在维度过多时,合理的使用聚合组能解决 Cube 膨胀率过大的问题。听起来那么美好,但是,不合理的聚合组设置将对性能产生灾难性影响。

剪枝原理

Apache Kylin 的主要工作就是为源数据构建 N 个维度的 Cube,实现聚合的预计算。从理论上说,构建 N 个维度的 Cube 就会生成 2^N 个 Cuboid。

所以,只要降低最终 Cuboid 的数量,就可以减小膨胀率,达到对 Cube 剪枝的效果。

image_name

构建一个 4 个维度(A,B,C, D)的 Cube,就需要生成 16 个Cuboid。

image_name

那么问题来了,如果这 4 个维度(A,B,C, D),能够根据某业务逻辑找出一个隐藏的规律,即:当进行聚合时,用户仅仅关注维度 AB 组合和维度 CD 组合(即只会通过维度 A 和 B 或者 C 和 D 进行聚合,而不会通过 A 和 C、B 和 C、A 和 D、B 和 D 进行聚合),那么就可以通过设置聚合组,使生成的 Cuboid 数目从 16 个缩减成 8 个(大大降低 Cube 膨胀率),如图 2 所示。

image_name

上面这段内容来自 Kylin 公众号的 【技术帖】Apache Kylin 高级设置:聚合组(Aggregation Group)原理解析 这篇文章中,值得对聚合组还不太了解的同学读一读。

但是,这里好像完全没有提到用于过滤数据(而不是聚合)的维度字段,应该怎么处理?

问题产生

某年某月某日,某业务人员突然发现某张报表的打开速度极其缓慢,并上报给系统管理人员。随后,通过对该报表产生的 SQL 进行筛查,发现了如下一条嫌疑重大的 SQL 语句,拖慢了整个报表的打开速度。

select "A","B",sum("VALUE")
from test_agg_group
where "D" = 1
group by 1,2;

Kylin 日志信息:

==========================[QUERY]===============================
Query Id: 7fe300c2-211c-9429-eebf-b4cc57bfd679
SQL: select "A","B",sum("VALUE")
from test_agg_group
where "D" = 1
group by 1,2;
User: ADMIN
Success: true
Duration: 4.891
Project: 0000_reserved
Realization Names: [CUBE[name=test_agg_group]]
Cuboid Ids: [15]
Total scan count: 1000000
Total scan bytes: 51000000
Result row count: 100000
Accept Partial: true
Is Partial Result: false
Hit Exception Cache: false
Storage cache used: false
Is Query Push-Down: false
Is Prepare: false
Trace URL: null
Message: null
==========================[QUERY]===============================

因为这是在测试环境(数据量不大)执行的 SQL,所以执行时间为 4.891 秒,生产环境真实的 SQL 执行时间已超过 40 秒,Total scan count 为千万级。但是问题出现的原理和线上是一样的。

问题定位

对于这种极慢的 SQL,我通常会观察日志信息中的 Total scan count 与 Result row count 数值差异是否巨大。

如果差异极大(例如上述 SQL 的差异已经达到 10 倍),那就意味着该条 SQL 扫描了很多不会被作为最终结果的无用数据。

此时我发现只要删掉那个 where 条件就可以很快的得到响应:

select "A","B",sum("VALUE")
from test_agg_group
group by 1,2

Kylin 日志信息:

==========================[QUERY]===============================
Query Id: 2a9d7422-7268-2805-f1ac-a0fc544602c9
SQL: select "A","B",sum("VALUE")
from test_agg_group
group by 1,2
User: ADMIN
Success: true
Duration: 0.628
Project: 0000_reserved
Realization Names: [CUBE[name=test_agg_group]]
Cuboid Ids: [12]
Total scan count: 100000
Total scan bytes: 4900000
Result row count: 100000
Accept Partial: true
Is Partial Result: false
Hit Exception Cache: false
Storage cache used: false
Is Query Push-Down: false
Is Prepare: false
Trace URL: null
Message: null
==========================[QUERY]===============================

很明显,相比原 SQL,查询的响应时间就提升了好几个数量级。值得注意的是,Total scan count 也从原来的 100w 降到了 10w。

如果是一个传统 RDBMS 的 DBA 看到这一幕,一定会感到疑惑,添加了 where 条件的 SQL 扫描的行数竟然比没有 where 条件的 SQL 扫描的行数更多,简直不可思议。

问题根源

看到这里,有人可能已经逐渐忘记了标题。

回到这个 Cube 上看一看,它教科书般的使用了聚合组进行剪枝操作,完美的将 AB 和 CD 分到了两个聚合组中,将膨胀率降低了一半。

image_name

因此,当我们以 AB 维度进行聚合 D 维度进行过滤,Kylin 在搜索哪些行满足 D=1 这个条件时,就无法通过图 3 的方式进行搜索了

image_name

因为不会有任何一个 Cuboid(大约 10w 行)像上面这样包含 ABD 三个维度和预计算好的值。所以最终 Kylin 会扫描下面这个 Cuboid (即包含 ABCD 四个字段的 Cuboid,大约有 100w 行)来获取最终数据。

image_name

这是一个在聚合组设置不当 且 运气还很差的情况下才能触发的问题。

运气差在哪?

  1. C 字段的基数非常大
  2. D 字段的基数非常小
image_name

通过查看 SQL 执行的日志信息我们也能看到。当以 D 字段为过滤条件时,只能使用包含 ABCD 四个字段的 Cuboid 进行扫描。

但是 C 字段的基数非常大,所以该 Cuboid 的行数也就非常多。同时, C 字段并没有进行筛选,使用了基数非常小的 D 字段进行了筛选(一共 1000w 行,D字段有 500w 行是 1,500w 行是 2)。

最终导致要扫描完 Cuboid ABCD 的 100w 行才能得到计算结果。

那么如果筛选字段不是 D 而是 C,我们尝试下估算下需要扫描多少行呢?

select "A","B",sum("VALUE")
from test_agg_group
where "C" = 100000
group by 1,2

Kylin 日志信息:

==========================[QUERY]===============================
Query Id: e304ae37-f7ec-233b-d353-845e2feba908
SQL: select "A","B",sum("VALUE")
from test_agg_group
where "C" = 100000
group by 1,2
User: ADMIN
Success: true
Duration: 0.806
Project: 0000_reserved
Realization Names: [CUBE[name=test_agg_group]]
Cuboid Ids: [15]
Total scan count: 2
Total scan bytes: 102
Result row count: 2
Accept Partial: true
Is Partial Result: false
Hit Exception Cache: false
Storage cache used: false
Is Query Push-Down: false
Is Prepare: false
Trace URL: null
Message: null
==========================[QUERY]===============================

仅需要扫描个位数的行即可,因为 C 字段基数大,包含的重复值很少。而且我们可以看到,这条 SQL 和最初的 SQL 都是用了 Cuboid Id 为 15 的 Cuboid 进行查询,也就是包含了 ABCD 四个字段的 Cuboid。

image_name

而仅用了 AB 两个字段,不使用 CD 中任何一个字段进行筛选的 SQL 使用了 Cuboid Id 为 12 的 Cuboid。

image_name

总结

分聚合组时,哪怕用户仅仅关注维度 AB 组合和维度 CD 组合,但用户会可能用 D 作为过滤条件来查询 AB 组合,就一定要保证 ABD 要分到同一个聚合组当中。

当然了,如果字段的基数不像例子中这么极端,聚合组随便怎么分对性能影响应该都不大。但是,如果哪天墨菲定律突然上线,希望大家能想起本文。

image_name
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,423评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,147评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,019评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,443评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,535评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,798评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,941评论 3 407
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,704评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,152评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,494评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,629评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,295评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,901评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,978评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,333评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,499评论 2 348