hadoop内的各种join

今天决定把之前准备放到单台服务器上做的一个算法拿到hadoop里面完成。但是这个算法有两个重点:多次表关联和多次排序。之前用hadoop基本就是清洗数据,hive基本上也是sum和排序问题。由于业务上每个表都比较均匀,所以,一直都是join就ok。
但是最近这个项目,需要从外部导入两个数据量很小的文件,有数据倾斜,于是开始考虑效率问题了。
看了很多别人的博客后,做如下理解:

  1. reduce join
    不需要额外的操作,只需要在map读入两个文件时,给每条数据打给flag,表示是file1的数据还是file2的数据,并将join条件字段作为key,这样,reduce的时候,相同的key在combine过程进入同一个value list,然后在reducer中对同一个key的file1的数据和file2的数据做做笛卡尔积。reduce side join相对简单一些,但是效率低一些。
    个人感觉效率低的原因在两方面,一是,map没有起到太大作用,对所有数据都输出了(这个原因比较轻微),二是,对同一个key的file1和file2做笛卡尔乘积的时候,双重循环,遍历两个表,效率太低了。
    reduce side join在hive中对应join。

  2. map side join
    在map端就将两个表join了。总所周知,map端只能读一个line,没有办法同时读两个表的数据,map side join常用于一个file数据较少的情况下,将数据量小的file读入到TaskTacker中,存为hashmap结构,以join条件为key,大的file以line的形式读入,并查询hashmap,然后连接输出。
    map side join在hive中对应mapjoin。

  3. semi join
    reduce join和map join各有长短,前者效率较低,后者更针对倾斜的数据,对两个file都大的数据,内存有点捉急。感觉semi join就是结合两者的长,弥补各自的短。
    semi join在map中将两个file中相对较小的file的join key取出来,假设是file1,放到第三个文件中file3,这样,file1的数据在file3中全部存在,因此不用过滤,而数据量较大的file2需要通过file3做过滤,将file3中不存在的join key筛除。然后,同样对两个file的数据打flag,后面的就跟reduce join一样了。
    个人觉得这对两个file间能join到一起的数据占比较小的情况,优势特别明显,进入reduce的数据量会小很多。
    感觉,对于join后数据量小,但两个原始表数据大,在一个main中用两个mapreduce job会不会更好呢?比如,第一个job做semi join中,file1和file3的关联后,reduce直接输出到file4,然后,第二个job再对file2和file4做map side join。

hadoop小白的个人理解,如有理解失误的地方,请告知,谢谢。

你可能感兴趣的:(hadoop,hadoop)