调整Hive查询的性能

时间:2012-07-08 23:25:54

标签: performance exception memory hive

我有一个Hive查询,它选择了大约30列和大约400,000条记录并将它们插入到另一个表中。我在SQL子句中有一个连接,它只是一个内连接。

由于超出了Java GC开销限制,查询失败。

奇怪的是,如果我删除了join子句并只选择表中的数据(稍高的音量),那么查询工作正常。

我对Hive很新。我无法理解为什么这个连接导致内存异常。

关于如何编写Hive查询以便它们不会导致这些问题,我是否应该注意一些事项?任何人都可以解释为什么连接可能会导致此问题,但选择更大量的数据和相同数量的列不会。

欣赏你对此的看法。 感谢

2 个答案:

答案 0 :(得分:35)

根据Hive的版本和您的配置,您的问题的答案可能会有所不同。 如果您可以与两个表的create语句以及它们的大小估计共享您的确切查询会更容易。

为了更好地理解这个问题,让我们来看看Hive中“常规”内连接的工作原理。

Hive加入MapReduce:

以下是如何将Hive中的内部联接编译为MapReduce的简化说明。通常,如果您有两个表t1和t2,其连接查询如下:

SELECT
   t1.key, t1.value, t2.value
FROM
   t1
   JOIN
   t2 (ON t1.key = t2.key);

其中,t1具有以下内容:

k_1    v1_1
k_2    v1_2
k_3    v1_3    

其中,t2具有以下内容:

k_2    v2_2
k_3    v2_3
k_4    v2_4    

我们希望连接结果为

k_2    v1_2    v2_2
k_3    v1_3    v2_3

假设表存储在HDFS上,它们的内容将被拆分为File Splits。映射器将文件拆分为输入,并将密钥作为表的键列发出,值作为表的值列和标志的复合(表示记录来自哪个表,即t1或t2)

对于t1:

k_1, <v1_1, t1>
k_2, <v1_2, t1>
k_3, <v1_3, t1>

对于t2:

k_2, <v2_2, t2>
k_3, <v2_3, t2>
k_4, <v2_4, t2>

现在,这些发出的记录经过洗牌阶段,其中所有具有相同键的记录被组合在一起并发送到reducer。每个reduce操作的上下文是一个键和一个包含与该键对应的所有值的列表。在实践中,一个减速器将执行几个减速操作。

在上面的示例中,我们将获得以下分组:

k_1, <<v1_1, t1>>
k_2, <<v1_2, t1>, <v2_2, t2>>
k_3, <<v1_3, t1>, <v2_3, t2>>
k_4, <<v2_4, t2>>

以下是减速机中发生的情况。对于值列表中的每个值,如果值对应于不同的表,则reducer将执行乘法。

对于k_1,t2没有值,也没有发出任何值。

对于k_2,会发出一个值的乘法 - k_2,v1_2,v2_2(因为每个表中有一个值,1x1 = 1)

对于k_3,发出一个值的乘法 - k_3,v1_3,v2_3(因为每个表中有一个值,1x1 = 1)

对于k_4,t1没有值,也没有发出任何值。 因此,您可以获得内部联接所期望的结果。

好的,我该怎么办?

  1. 您的数据可能存在偏差。换句话说,当reducer获取数据时,对应于某个键的值列表非常长,这会导致错误。 要解决此问题,您可以尝试增加JVM可用的内存。您可以通过在hive-site.xml中将mapred.child.java.opts设置为-Xmx512M之类的值来执行此操作。您可以通过在Hive shell中执行set mapred.child.java.opts;来查询此参数的当前值。

  2. 您可以尝试使用“常规”加入的替代方法,例如地图加入。上面的连接说明适用于常规连接,其中连接发生在reducers中。根据您使用的Hive的版本,Hive可以自动将常规连接转换为更快的地图连接(因为连接发生在地图阶段)。要启用优化,请将hive.auto.convert.join设置为true。此属性是在Hive 0.7

  3. 中引入的
  4. 除了将hive.auto.convert.join设置为true之外,您还可以将hive.optimize.skewjoin设置为true。这将解决1中描述的数据问题的偏差。

答案 1 :(得分:6)

非常感谢Mark的回应。非常感谢。

经过几个小时后,我终于发现join语句中表的顺序有所不同。为了获得最佳性能和内存管理,最后一个连接应该是最大的表。

在连接语句中更改表的顺序解决了问题。

请参阅http://hive.apache.org/docs/r0.9.0/language_manual/joins.html

上的最大表格

上面的解释也很有用。非常感谢