作者:倪涛 MO产品布道师
目录
Part 1.如何处理不均匀数据?
Part 2.Hybrid shuffle
Part 3.Shuffle resue
Part 4.Join reorder
Part 5.总结
在《MO干货|shuffle执行计划解析(上篇)》中,我们分享了shuffle的背景、实现原理等,感兴趣的读者可以通过传送门阅读;今天继续围绕shuffle进行细节解读
Part 1 如何处理不均匀数据?
之前一直用tpch数据集进行举例,但是tpch是一个比较理想的场景,所有数据都是比较均匀分布的。实际生产环境中,很多数据是不均匀分布的。对于不均匀数据,比较简单的做法是使用hash shuffle来保证分桶后的数据是均匀的。由于hash shuffle无法开启colocate优化,因此优化器还是尽可能使用range shuffle,这就需要对数据的分布有比较好的掌握,从而给出更好的分桶算法。
MO的优化器,在计算stats阶段,同时也会根据数据的zonemap来计算数据的分布情况。具体做法是每访问一个zonemap,就假定这个object中的数据在这个zonemap内均匀分布。通过遍历所有的zonemap来计算数据分布,并将计算结果保存在ShuffleRange这个数据结构中。
这里有个细节是对数值类型,假设每个zonemap在自己的min-max区间内数据均匀分布,直接按max从小到大排序。对字符类型,由于每个字符占一个字节,但一个字节的大部分值不会出现在字符串中,对每个zonemap数据均匀分布的假设不成立,所以对每种出现过的字符映射到数字,重新计算每个字符串对应的新值后再按max从小到大排序。
ShuffleRange这个结构里有几个关键的值:
ShuffleRange.Overlap
是一个0到1之间的float64类型变量,表示zonemap之间的重叠度,Overlap越大重叠的部分越多,具体定义为:任意两个zonemap之间重叠的比例的平均值的平方根,取平方根是为了更方便区分重叠度较低的部分数据集。
ShuffleRange.Uniform
是一个0到1之间的float64类型变量,表示数据的平均度,Uniform越大,数据更平均,具体定义为:数据整体平均的密度除以数据最密集处的密度。Uniform接近于1时,考虑直接对整体最大最小值平均划分值来分桶。
ShuffleRange.Result
是一个[]float64,长度为默认分桶数1024,表示相邻两个桶之间的划分值。Result的计算方法为:假设每个zonemap在自己的min-max区间内数据均匀分布,将zonemap排序后计算每一小段的密度并计算划分值。
计算完ShuffleRange之后,优化器会根据overlap,uniform等指标决定是否采用range shuffle。如果数据分布不是很理想,算法无法给出合适的分桶方法,那么只能使用hash shuffle。如果指标合适,说明可以给出合理的分桶方案,则会默认保留1024个桶的分布方法。之后在编译pipeline时,再根据运行时信息,决定实际的分桶数后,重新分出N个桶。限于篇幅具体的算法细节也不再做进一步介绍,感兴趣的同学可以通过MO的源码直接查看相关细节。
Part 2 Hybrid shuffle