应用案例1:求各个部门的总工资
问题分析:MapReduce中join分为:Reduce side join、map side join、semi join等。
- Reduce join:在shuffle阶段进行大量的传输,会造成大量的网络IO效率低下,
- Map side join: 在处理多个小表关联大表时非常有用。
Map side join应用场景: 两个待连接的表, 一个表非常大, 另一个表非常小,以至于小表能够直接放到内存中。我们将小表复制多份,让每个Map Task内存中复制一份(如存放到hash table中),然后只需要扫描大表:对于大表中的每一条记录key/value, 到hashtable中找是否有相同key的记录, 如果有, 则连接后输出即可;
为了支持文件的复制,Hadoop提供了一个类DistributeCache,使用该类的方法如下:
- 用户使用静态方法DistributedCache.addCacheFile()指定要复制的文件,它的参数是文件的URI(如果是HDFS上的文件,可以这样:hdfs://jobtracker:50030/home/XXX/file)。JobTracker在作业启动之前会获取这个URI列表,并将相应的文件拷贝到各个TaskTracker的本地磁盘上。
- 用户使用DistributedCache.getLocalCacheFiles()方法获取文件目录,并使用标准的文件读写API读取相应的文件。
在下面代码中,将会把数据量小的表(部门dept)缓存在内存中,在Mapper阶段对员工部门编号映射成部门名称,该名称作为key输出到Reduce中,在Reduce中计算按照部门计算各个部门的总工资
处理流程图: