1

我有一个视图表与一个临时表连接,并有意启用了以下参数。

hive.auto.convert.join=true;    
hive.execution.engine=tez;

代码片段是,

CREATE TABLE STG_CONVERSION AS    
SELECT CONV.CONVERSION_ID,
       CONV.USER_ID,
       TP.TIME,
       CONV.TIME AS ACTIVITY_TIME,
       TP.MULTI_DIM_ID,
       CONV.CONV_TYPE_ID,
       TP.SV1
FROM VIEWS TP
JOIN  SCU_TMP CONV ON TP.USER_ID = CONV.USER_ID
WHERE TP.TIME <= CONV.TIME;

在正常情况下,两个表都可以有任意数量的记录。
但是,在 SCU_TMP 表中,预计只有 10-50 条记录具有相同的用户 ID。

但在某些情况下,几个用户 ID 在 SCU Temp 表中带有大约 10k-20k 条记录,这会产生叉积效应。
在这种情况下,它将永远运行,只需 1 个映射器即可完成。

有没有办法优化它并优雅地运行它?

4

1 回答 1

2

我能够通过以下查询找到解决方案。

set hive.exec.reducers.bytes.per.reducer=10000
CREATE TABLE STG_CONVERSION AS    
SELECT CONV.CONVERSION_ID,    
       CONV.USER_ID,    
       TP.TIME,    
       CONV.TIME AS ACTIVITY_TIME,    
       TP.MULTI_DIM_ID,    
       CONV.CONV_TYPE_ID,    
       TP.SV1    
FROM (SELECT TIME,MULTI_DIM_ID,SV1 FROM VIEWS SORT BY TIME) TP    
JOIN  SCU_TMP CONV ON TP.USER_ID = CONV.USER_ID    
WHERE TP.TIME <= CONV.TIME;    

问题的出现是因为当单个用户 id 支配表时,该用户的连接通过单个映射器进行处理,该映射器被卡住。

对其进行了两处修改,
1)用子查询替换了表名——在连接之前添加了一个排序过程。
2) 将 hive.exec.reducers.bytes.per.reducer 参数减少到 10KB。

步骤 (1) 中的按时间排序添加了一个 shuffle 阶段,该阶段均匀地分布了早先被用户 ID 倾斜的数据。
减少每个 reducer 参数的字节数会导致数据分布到所有可用的 reducer。

通过这两项改进,10-12 小时的运行时间减少到 45 分钟。

于 2018-05-11T21:55:14.543 回答