🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
**1. group by 产生数据倾斜** 使用 Hive 对数据做一些类型统计的时候遇到过某种类型的数据量特别多,而其他类型数据的数据量特别少。当按照类型进行 group by 的时候,会将相同的group by 字段的 reduce 任务需要的数据拉取到同一个节点进行聚合,而当其中每一组的数据量过大时,会出现其他组的计算已经完成而这里还没计算完成,其他节点的一直等待这个节点的任务执行完成,所以会看到一直 map 100% reduce 99%的情况。 <br/> 解决方法: (1)开启 MapJoin,参考【Hive优化->表的优化->开启Map Join】小节。 (2)或者根据业务,合理调整分组维度。 <br/> **2.当 HiveQL 中包含 count(distinct)时** 如果数据量非常大,执行如 ```sql select a,count(distinct b) from t group by a; ``` 类型的SQL 时,会出现数据倾斜的问题。 <br/> 解决方法: (1)使用 `sum...group by` 代替。如 ```sql select a,sum(1) from (select a, b from t group by a,b) group by a; ``` (2)在业务逻辑优化效果的不大情况下,有些时候是可以将倾斜的数据单独拿出来处理。最后 `union` 回去。 <br/> **3. 当遇到一个大表和一个小表进行 join 操作时** 解决方法:使用 mapjoin 将小表加载到内存中,参考【Hive优化->表的优化->开启Map Join】小节。。 <br/> **4.空值产生的数据倾斜** 遇到需要进行 join 的但是关联字段有数据为空。 <br/> 场景:如日志中,常会有信息丢失的问题,比如日志中的 user_id,如果取其中的 user_id 和 用户表中的 user_id 关联,会碰到数据倾斜的问题。 数据量大时也会产生数据倾斜,如表一的 id 需要和表二的 id 进行关联。 <br/> 解决方法: (1)id 为空的不参与关联; ```sql select * from log a join users b on a.user_id is not null and a.user_id = b.user_id union all select * from log a where a.user_id is null; ``` (2)给空值分配随机的 key 值; ```sql select * from log a left outer join users b on case when a.user_id is null then concat(‘hive’,rand()) else a.user_id end = b.user_id; ``` 一般分配随机 key 值得方法更好一些。 <br/> **5. 通用的一些数据倾斜的处理方法** 合理设置 map 和 reduce 数。