2012-07-08 28 views
9

我有一個Hive查詢選擇約30列和約400,000條記錄並將它們插入到另一個表中。我有一個加入我的SQL子句,這只是一個內部聯接。調整Hive查詢的性能

由於超出了Java GC開銷限制,查詢失敗。

奇怪的是,如果我刪除join子句並從表中選擇數據(稍高一點),那麼查詢就可以正常工作。

我是Hive的新手。我不明白爲什麼這個連接導致內存異常。

有什麼我應該知道的關於我如何編寫Hive查詢,以便它們不會導致這些問題?任何人都可以解釋爲什麼連接可能會導致此問題,但選擇更大的數據量和相同數量的列不會。

欣賞你對此的看法。 謝謝

回答

6

非常感謝Mark的迴應。非常感激。

很多小時後,我終於發現,join語句中表的順序有所不同。爲了獲得最佳性能和內存管理,最後的連接應該是最大的表。

更改聯接語句中我的表的順序解決了問題。

見最大的表最後在http://hive.apache.org/docs/r0.9.0/language_manual/joins.html

上述你的解釋是非常有用的。許多謝謝

+5

嘿,如果您同意他的解決方案,而不是接受您自己的解決方案,那麼您應該「接受」Mark Grover的答案,這不是真正的解決方案,而是正確答案的讚賞。 – 2014-02-12 13:55:34

+0

+1以上評論。但我認爲,因爲他是新來的,他可能沒有意識到事情在這裏工作。 – 2014-09-29 16:20:03

34

根據Hive的版本和您的配置,您的問題的答案可能會有所不同。 如果您可以分享您的確切查詢以及兩張表的創建報表並估計它們的大小,那將更容易。

爲了更好地理解問題,我們來看看「常規」內部聯接如何在Hive中工作。

蜂巢參加的MapReduce:

這裏是在蜂巢內如何加入一個簡單的描述被編譯到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上,它們的內容將被拆分成文件拆分。映射器將文件分割爲輸入,並將鍵作爲表的鍵列發出,並將該值作爲表的值列與標誌的組合(表示記錄來自哪個表,即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> 

現在,這些發射出的記錄經過洗牌階段,所有使用相同的按鍵記錄被組合在一起,並送往減速器。每個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(因爲從每個表中的一個值,1×1 = 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. 您可以嘗試使用「常規」加入的替代方法,例如,地圖加入。以上連接的解釋適用於加入發生在縮減器中的常規連接。根據您使用的Hive的版本,Hive可以自動將常規連接轉換爲更快的映射連接(因爲連接發生在映射階段)。要啓用優化,請將hive.auto.convert.join設置爲true。此屬性,而Hive 0.7

  3. 介紹除了設置hive.auto.convert.jointrue,你也可以設置hive.optimize.skewjointrue。這將解決數據問題中出現的歪斜。