Max compute 计算长尾问题优化| 学习笔记

开发者学堂课程【SaaS 模式云数据仓库系列课程 —— 2021数仓必修课Max compute 计算长尾问题优化】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/55/detail/1043


Max compute 计算长尾问题优化

内容简介

一、 长尾现象与原因

二、 优化思路与解决方案

一、 长尾现象与原因

提交到 fuxi compute 上的任务都是由一个或多个 fuxi job 来完成的;每一个fuxi job 由一个或多个 fuxi task 来完成;每一个 fuxi task 会由一个或 N 个 fuxi instance 来完成。

以下将介绍如何查看是否发生了长尾且发生在什么阶段。

Log view 是排查问题的重要工具和手段。一般会逐一点击每个 task ,在页面的下端会显示出这个 task 下所有 instance 的运行情况,这个情况里面包括它的运行时间起始终止时间。

如果上面写的是 long tails 那就说明发生了长尾。因为在这个任务执行完之后,系统会对每一个 instance 的时间做统计,求出一个平均值。

如果某些 instance 执行的时间是这个平均值的3倍或3倍以上,就认为发生了长尾,这个发生长尾的 instance 拖延了整个任务,让整个任务不能及时完成。

发生长尾的原因如下:

以下 Circle 就是一个 group by,然后求 count 。其实就是一个简单的 Word count 的实际场景的例子。实际这个执行计划里面会用到两个 task:map、reduce。

为了分析原因,就需要分析整个 Word count 。输入的数据在起始端的时候会被分片,分片的数据进入 map instance 以后会去读每一条记录然后把里面的 Key放在第一个参数位,下一个阶段会再次做排序,之后再把value累加起来,组成一个新的 Key 的 value 值。后半段相同 Key 的这个记录会进入到相同的 reduce Instance 上去。

reduce 根据 P 做操作,最后输出数据。在这整个流程里面,第一个 map 阶段有可能发生长尾,但是在实际应用中这个现象不经常发生,如果真的发生的话可以提供工单,然后进行现场跟踪这个问题。

第2个 shuffle 阶段,相同的 Key 会分配到相同的 reduce 上去处理,如果一旦这个 Key 的 数据非常多,因为 reduce 要处理的事情很多,但他可能就完成的时间就比别人要长,这个时候长尾现象就发生了。

了解了原因以后,再针对实际观察的这些发生长尾的场景来看如何做优化。



二、 优化思路与解决方案

场景一 Group By 长尾

group by ,这个语句经常使用,做 group by 时就像 worker 的例子一样,一般来说是一个 Mmap 的 task 加一个 reduce task ,发生长尾的地方往往是在shuffle dispatch 的位置,解决方法就是不要让相同的多数量的有相同体的数量都分发到一个 reduce 上,将它打散就能解决了这个问题。

系统提供了一个参数,这个参数会在做 shuffle 的时候,在算法里面会加入一个随机的因素,这样的话就会更加均匀的把数据分发到 reduce 上。

中间的那个 reduce 做把热点 Key 给打散,但是使用这个参数有几个需要注意的地方就是它仅仅是对 group by 才有效,而且如果说长尾并不是很严重,用这种方法的话会发现最终消耗时间会更长。所以是否开启这个参数跟用户自己的数据的内容规模大小都有关系,并不是说发生 group by 发生的长尾就必须要开启这个参数。

场景二 count distinct

在计算商品购买的时候,经常会用到这种语句,但是如果这个场景里面固定的特殊值比较多,也会发生长尾。可以不用 distinct ,因为 distinct 可以用 group by来改写,用 group by 改写以后再用那个参数来查看有没有优化的作用。先做一个group by ,然后再求。

第一次执行是26秒当执行改写成 Goodbye 了以后变成了30多秒。时间是变长了的。初衷是为了避免使用 distinct,使用 group by 改造并且还开启了参数,所以充分说明如果长尾不是很严重,然后这个分区也不是很多,p 也不是很多,那是否要开启这个参数是值得商榷的。

如果真的是产生了很多长尾,然后又用 group by 改造也不能解决问题,经常使用的一种方法就是先用 Where 先过滤掉这个特殊值,然后执行完 count 以后再加上特殊值的个数。所有的优化的场景要去根据用户自己具体的场景数据的结构类型规模来进行具体的分析。

场景三 动态分区

在动态分区的这个场景里面非常有可能发生长尾。这个语句就是一个动态分区写入的语句。如果说在 map 阶段 map instance ,有N个 map instance,目标分区有 M 个,那么很有可能就会产生 N 乘以 N 个小文件。

小文件过多的话会给后续的查询带来很多的问题。

所以说系统针对这种情况是做了优化的,它会尽可能的避免小文件过多的产生,查看这个执行计划会发现,当执行这个语句的时候,开始上面有2个参数,一个是long position Time ,这是这张表的分区,然后还有一个值是一个0到10的一个数,也就是说系统为了避免小文件的产生开启了 reshuffle, reshuffle 会在shuffle dispatch 的时候减少了 reduce 的个数,个数确实减少了小文件的产生,但是这个任务花了 3分钟并且有长尾的现象发生,两全其美的方法就是如果手动的把 reshuffle 这个开关给关掉,这个开关系统是默认打开的,如果一旦禁用掉的话,这个任务效果是很明显的,所以说如果的目标分区不多建议先关闭,关闭以后等任务执行完成以后再手动的执行 merge ,去减少小文件。​

场景四 Join 长尾

每一个 John 也会被解释器解释成一个 map reduce 的任务,map 端会把周围两边的数据都读出来,然后在 reduce 上在做的操作。

在产生长尾的问题的时候, map join 原理就是把 John 这 个操作从 reduce 上移到了那个端去做,每一个 map instance 都拥有小表所有的内容,它就在map上说中文就好了,不需要再到 reduce 上去做,但是如果说一个 map instance 能存下小表所有的记录,这个单机的内存得足以容纳得下这么多数据。

可以尝试着用分而治之的方法,刚才说到了长尾的原因无非就是热点体太多发送到一个 instance 上的数据太多,导致他运行的时间太长。把热点找出来或者是说把热点体 Key 的范围给找出来。分开来做。

第一步可以先做一个 group by 和 order by ,把业务数据里面最常用的 item 给找出来,并且把信息放到一张临时表里,找出了这些热点 item 之后,一般它的数据不会太多。

Limit 100 只是一个参考值,这个值需要根据自己的业务数据然后调常用整去分析看一下最常用的这些 item 大概是利率是多少,把它筛选出来。

在第二步中把常用的 item 做关联生成一个临时表。并且把这一部分常用的 item跟另外一张表做好关联以后写到了结果表中,第三步的时候再把非 item 取出来,然后做关联。

最后一步把2个部分的 result 合并到一起。

上一篇:GitScrum :为开发团队而生的开源应用


下一篇:ie6(或者其他浏览器)使用dialog弹框访问(交互数据)服务器失败(artdialog -v5.0.4)