关于mapreduce 两张表的join
1、map端join
map端join用的是分布式文件缓存,将小文件缓存到maptask端,hive默认缓存文件大小为25M,
以join字段作为key,其他字段作为value,保存到hashMap集合里面,然后和输入的一条数据记录进行join操作,
得到join后的结果输出到缓存区进行分区排序操作。
2、reduce端的join
首先map端已经对join字段作为key,其他字段作为value,其中value有对应的表的标记,以用来区别是哪一个表的数据,
如加入前缀 0-value、1-value,输出到了零时文件当中,等待,reducetask的拉取, reducetask拉取到指定分区的数据后,
对相同key的数据进行处理,也即是最后的join操作了。首先先区分开是哪个表的数据,分别保存到两个List集合当中去,
接下来就是取出两个List集合当中的数据进行join了,代码就是两个嵌套for循环将两个集合的数据取出进行拼接成一个新的
value值作为最终join后的结果。
3、hive group by 操作也是一个只有map的 mapreduce,会划分(stage),将分组字段作为key,其他字段作为value作为map端的输出。
以上分析可以得出发生数据倾斜的地方可能是join操作,map端join可以有效避免数据倾斜的影响,但是如果是reduce端join的话,
影响就大了,因为相同key的数据是保存在一个迭代器中的,不同表表的数据是保存到两个List集合中的,如果数据量特别大,可能会
造成OOM的现象,处理时间也很长,log(n*m)的时间复杂度。group by的话,就可能拼接后的key,分组后发生数据倾斜。
4、还有一个就是count(distinct())操作,这也是一个mapreduce,以去重字段作为key,value为NullWritble对象,这里被处理的去重
字段的数据可能有数据倾斜,这就是count(distinct())发生数据倾斜的原因了,最后reduce阶段对key的个数进行累加就是count的值了。