更有效的查询以避免Hive中的OutOfMemoryError

Dic*_*nus 3 performance hadoop hive out-of-memory memory-efficient

我收到java.lang.OutOfMemoryError:Hive中超出了GC开销限制。在搜索中,我发现这是因为该进程所有CPU时间的98%将进行垃圾回收(这意味着什么?)。是我查询中问题的核心吗?为避免此类问题,我是否应该以其他方式写以下内容?

我正在尝试计算在给定时间段内有多少种特定的电话类型具有有效的“使用”状态。有没有办法以不同的方式来做这种逻辑,那会更好?

select count(a.imei)
from
(Select distinct imei
from pingdata
where timestamp between TO_DATE("2016-06-01") AND TO_DATE("2016-07-17")
and ((SUBSTR(imei,12,2) = "04") or (SUBSTR(imei,12,2) = "05")) ) a
join
(SELECT distinct imei
FROM eventdata
where timestamp between TO_DATE("2016-06-01") AND TO_DATE("2016-07-17")
AND event = "Use" AND clientversion like '3.2%') b
on a.imei=b.imei
Run Code Online (Sandbox Code Playgroud)

谢谢

lef*_*oin 5

在加入每个数据集之前对每个数据集应用不重复的方法更为安全,因为加入非唯一键会重复数据。

我建议按to_date(timestamp)字段(yyyy-MM-dd)对数据集进行分区,以根据您的where子句使分区修剪工作(检查它是否起作用)。如果数据集太大并且包含大量数据,则也可以按事件字段进行划分,其中事件<>'使用'。

知道在哪个阶段失败很重要。还要研究异常。如果在映射器上失败,则应优化子查询(如我所述添加分区)。如果在reducer(join)上失败,则应该以某种方式改进join(尝试减少每个reducer的字节数:

set hive.exec.reducers.bytes.per.reducer=67108864; 甚至更少)(如果它在写入器上失败)(OrcWriter,然后尝试通过从imei的substr添加分区到Output表,并在查询结束时“通过substr(imei ...)进行分配,以减轻对reducers的压力)。

或添加基数低且分布均匀的更多列,以在更多的reducer之间平均分配数据:

distribute by substr(imei...), col2
Run Code Online (Sandbox Code Playgroud)

确保分区列在“分发依据”中。这将减少每个reducer写入的文件数量,并有助于摆脱OOM