map-side join:
map-side join顾名思义就是join的动作在map阶段完成, 不必动用reducer. 但是要用上map-side join必须满足的条件是两个join的表, 必须有一个足够小. 小到可以使用 Hadoop的 DistributedCache 功能把小表缓存到各个执行节点上去. 而大表使用各个mapper来和分布缓存中的小表做具体的join.
默认小于25Mb的表就会被视为小表, 并进行map-side join.
set hive.mapjoin.smalltable.filesize;
而是否开启map-side join的优化, 则取决于:
set hive.auto.convert.join;
如果在join的两张表中都设置过Bucket, 且Bucket number一致或是倍数关系, 那么还可以进一步优化, 只要小表的最大的bucket不超过阈值(默认25Mb)就可以使用map-side join了, 每次只把一个Bucket放入分布式缓存, 并去大表相应的Bucket中找匹配的记录来完成 join.
reduce-side join:
当join的表都没有满足size要求后(或者没有开启hive.auto.convert.join), 就不能使用 map-side join, 系统就会执行reduce-side. 这种join方式性能相比map-side颇低.
它的作法是将要join的列(若在几列上join的话就把几列合并为一列)作为mapper的键值对的key, 同时增加一个Tag列用于标记数据的来源(左表还是右表), 将相同的key的数据传入同一个reducer做笛卡尔积.
reduce-side join的优化方式是将小表join列上值 通过分布式缓存, 放到各个节点上去, 在map阶段对大表进行一次filter. 如果小表join列上值 都太大的话, 就用BloomFilter来做 filter. 对于一个值, 如果BloomFilter返回false, 那么它必定不在筛选范围之内.
参考链接:
http://blog.sina.com.cn/s/blog_6fccaaeb0102vx87.html
https://www.cnblogs.com/shudonghe/p/3260201.html
http://www.cnblogs.com/ggjucheng/archive/2013/01/03/2842821.html