文章目录
hash
hash算法是指对于key计算出hash值,基于hash值识别相同key,从而进行归类、聚合等操作。
内存hash
类似于JAVA HashMap的实现方式,处理hash碰撞的多种算法等。
此类算法要求所有数据都位于内存当中,所以适用于小数据量的场景。
external hash
算法思想:1. 先基于hash函数h1,遍历所有的数据进行hash分区。每个分区具有一个缓冲区,满则溢写到磁盘上。2. 遍历所有分区,对于一个分区,加载其对应的所有文件,基于hash函数h2,执行普通hash算法,输出结果。
算法要求每个分区的所有数据可以保存在内存当中。第一步的hash分区保证了相同key的数据肯定位于一个分区,所以每个分区可以独立的处理。此类算法可以处理海量数据的hash运算。
sort
内存sort
快速排序、归并排序等算法。
此类算法要求所有数据都位于内存当中,所以适用于小数据量的场景。
external sort
算法思路:1. 遍历所有的数据,插入一个内存缓冲区,满则对缓冲区中的数据进行排序,并溢写到磁盘上。2. 对磁盘上所有的排序文件进行顺序加载,执行归并排序。
此类算法可以处理海量数据的sort运算。
shuffle
注意shuffle指的是分区的实现方式,分区按照实现效果可分为hash分区和range分区。
hash shuffle
hash shuffle即是基于external hash的思想进行shuffle。
算法实现:1. 为每个分区设置一个缓冲区。遍历所有数据按照hash值插入对应缓冲区。缓存区满则溢写到磁盘上。2. 按照分区合并磁盘上的所有文件,生成一个总数据文件和一个分区索引文件或者多个分区数据文件。
根据数据hash值生成的方式可以实现hash分区以及range分区。如果按照数据key的范围大小生成的hash值则最终可生成range分区。按照普通hash函数生成hash值,则生成hash分区。
sort shuffle
sort shuffle即是基于external sort的思想进行shuffle。
算法实现:(1)设置一个缓冲区,遍历所有数据插入缓冲区。缓存区满则溢写到磁盘上,溢写之前对数据进行排序。(2)执行归并排序算法,合并磁盘上的所有文件,生成一个排序数据文件和分区索引文件。
根据数据排序的方式可以实现hash分区以及range分区。如果按照数据key的hash值对应的分区id排序,则最终可生成hash分区;如果按照数据key的大小进行排序,则最终可生成range分区。
综上,sort shuffle只使用一个内存缓冲区,更简单且对内存的控制更精确,是更好的选择。
分布式sort首先进行range分区,再进行分区局部排序。
aggregate
hash aggregate
hash aggregate即是基于hash算法进行聚合操作。
既可以使用基于全内存的哈希表实现,也可以基于external hash算法处理海量数据的的聚合。
sort aggregate
sort aggregate即是基于排序算法,先对数据进行排序,再进行聚合操作。数据排序之后,key相同的数据排在一起,则只需要依次遍历排序之后的数据即可进行聚合。
排序算法既可以使用普通内存的排序算法,也可以使用external sort。
对于海量数据,external sort aggregate要比external hash aggregate效果更好,所以sort aggregate更经常用于处理大数据量的agg,hash aggregate用于小数据量的agg。
分布式aggregate
首先进行进行分区,各分区上再进行hash aggregate或者sort aggregate。
join
nested loop join
算法思路:双重循环,遍历outer table的每条记录,查找inner table对应的记录。
优化算法:Block Nested Loop Join、Index Nested Loop Join
hash join
算法思路:(1)遍历较小的表的所有记录,基于join key构建哈希表,放置于内存中。(2)遍历较大的表的所有记录,查找哈希表有无对应的记录,有则输出join row。
hash join即可以基于内存的hash算法,也先基于external hash算法。
基于external hash算法:(1)先对两个数据表进行hash分区 (2)对每一个分区的数据,执行上述算法流程。
sort merge join
算法思路:(1)对两个数据集按照join key进行排序。(2)遍历两个排序数据集,类似于归并排序的方式,寻找key相同的记录对。
sort算法可以使用内存排序算法,也可以使用external sort。
对于海量数据,sort merge join的效果好于hash join。
分布式join
首先进行进行分区,各分区上再进行hash join或者sort merge join。
或者使用brocast join。
总结
- sort和hash是多个算法中的重要组成部分。两者均具有纯内存的算法和内存+磁盘的算法。且面对大数据量的场景下,sort的性能更有优势。
- 基于内存+磁盘的sort和hash算法,对应了hash shuffle和sort shuffle的方法。spark shuffle时必须将数据写入文件,因为spark的调度基于stage,所以必须保存上一阶段的数据。这既保证数据的不丢失,且提高了资源的利用率(不需要耗费内存保存数据,且下一stage的任务可延迟调度)。
- aggregate和join均可以基于hash和sort两种方式实现,且基于external的算法,均可处理大数据量的场景。
- 分布式aggregate和join的原理实际上和基于external的实现基本相似。因为基于external的实现的第一步实际上就是分区,单机的算法是一次处理每个分区的数据,分布式算法是并行的处理每个分区的数据。