Join:
1.reduce side join:
i.也叫common join,最简单的join方式
ii.在map阶段,map函数同时读取两个文件File1和File2,为了区分两种来源的key/value数据对,对每条数 据打一个标签>(tag),(比如tag=1表示来自文件File1,tag=2表示来自文件File2。reduce阶段,reduce函数 获取key相同的来自File1和File2文件的value list,然后对同一个key,对File1和File2中的数据进行join
iii.具体过程:
a.map分别读取两个表的记录,按分隔符分割出字符,同时给每条记录打上tag(即来源哪个表),分区 后输出给Reducer
b.对每个key的数据,reduce初始化一个ListA存放A数据源的记录,一个ListB存放数据源B的记录, 然后遍历这两个List(双层循环)
进行output.collect(key, new Text(listA.get(i) +listB.get(j)));
2.map side join(hash join):
i.map join,常用的优化方式,主要针对大表连小表的场景
ii.之所以存在map join,是因为在map阶段不能获取所有需要join的字段(即同一个key的字段可能在input split后被分到了不同了map中。map join可以把小表直接存放到内存中,这样小表可以被复制多份,让每 个map task内存中存在一份(如存放到hash table)中,然后只扫描大表;对大表中的每一条key/value记 录,在hash table中查找是否有相同的key的记录,有则连接输出即可
iii.具体过程:
a.使用静态方法DistributedCache.addCacheFile()缓存小表的数据,小表可以存为HashTable,方便 查找。keyJobTracker在作业启动之前会把相应的文件拷贝到各个TaskTracker的本地磁盘上
b.在Map类的setup方法中使用DistributedCache.getLocalCacheFiles()方法获取文件目录并读取文 件
c.在每个map中,获取大表中每条记录的key,再去缓存中取得相同key的记录,合并两记录并输出
String [] big = data.toString.split(“,”);
String small = smallTable.get(big[key]) ;
outKey.set(user);
outValue.set(big[1]);
output.collect(outKey, outValue);
3.SemiJoin
i.SemiJoin,也叫半连接,主要使用形式为left semi join
ii.对于reduce side join,跨机器的数据传输量非常大,成了join操作的一个瓶颈,如果能在map端过滤掉 不会参加join操作的数据,则可以节省网络IO
iii.实现方法:选取一个小表File1,将参与join的key抽取出来,保存到文件File3中,File3文件一般很小,可以 放到内存里。在map阶段,使用DistributedCache将File3复制到各个TaskTracker上,然后将File2中不在 File3中的key对应的记录过滤掉,再发送到Reducer上,这个时候数据量减少了,因此实现了优化。
iv.与其他连接方式不同 left join只会显示主表的字段,不能显示右表的字段,当右表有多个相同key时也不 会进行重复连接。
浙公网安备 33010602011771号