大表Join的数据偏斜
MapReduce编程模型下开发代码需要考虑数据偏斜的问题,Hive代码也是一样。数据偏斜的原因包括以下两点: 1. Map输出key数量极少,导致reduce端退化为单机作业。 2. Map输出key分布不均,少量key对应大量value,导致reduce端单机瓶颈。 Hive中我们使用MapJoin解决数据偏斜的问题,即将其中的某个表(全量)分发到所有Map端进行Join,从而避免了reduce。这要求分发的表可以被全量载入内存。 极限情况下,Join两边的表都是大表,就无法使用MapJoin。 这种问题最为棘手,目前已知的解决思路有两种: 1. 如果是上述情况1,考虑先对Join中的一个表去重,以此结果过滤无用信息。这样一般会将其中一个大表转化为小表,再使用MapJoin 。 一个实例是广告投放效果分析,例如将广告投放者信息表i中的信息填充到广告曝光日志表w中,使用投放者id关联。因为实际广告投放者数量很少(但是投放者信息表i很大),因此可以考虑先在w表中去重查询所有实际广告投放者id列表,以此Join过滤表i,这一结果必然是一个小表,就可以使用MapJoin。 2. 如果是上述情况2,考虑切分Join中的一个表为多片,以便将切片全部载入内存,然后采用多次MapJoin得到结果。 一个实例是商品浏览日志分析,例如将商品信息表i中的信息填充到商品浏览日志表w中,使用商品id关联。但是某些热卖商品浏览量很大,造成数据偏斜。例如,以下语句实现了一个innerjoin逻辑,将商品信息表拆分成2个表: select * from ( select w.id, w.time, w.amount, i1.name, i1.loc, i1.cat from w left outer join i sampletable(1 out of 2 on id) i1 ) union all ( select w.id, w.time, w.amount, i2.name, i2.loc, i2.cat from w left outer join i sampletable(1 out of 2 on id) i2 ) ); 以下语句实现了left outer join逻辑: select t1.id, t1.time, t1.amount, coalease(t1.name,t2.name), coalease(t1.loc, t2.loc), coalease(t1.cat, t2.cat) from ( select w.id, w.time,w.amount, i1.name, i1.loc, i1.cat from w left outer join isampletable(1 out of 2 on id) i1 ) t1 left outer join i sampletable(2 out of 2 on id)t2; 上述语句使用Hive的sample table特性对表做切分。 |
更多精彩内容请关注:http://bbs.superwu.cn
关注超人学院微信二维码: