2012-07-08 13 views
9

約30列と約400,000レコードを選択して別のテーブルに挿入するHiveクエリがあります。 SQL節に1つの結合があります。これは内部結合にすぎません。パフォーマンスチューニングaハイブクエリ

Java GCのオーバーヘッドの上限を超えたため、クエリが失敗します。

奇妙なのは、結合節を削除してテーブルからデータを選択すると(ちょっと高いボリューム)、クエリが正常に動作するということです。

私はハイブにはかなり新しいです。なぜこの結合がメモリ例外を引き起こしているのか理解できません。

これらの問題が発生しないようにHiveクエリをどのように記述するかについて、私は注意すべきことがありますか?なぜ誰かがこの問題を引き起こすかもしれない理由を説明することができますが、より大きいデータ量と同じ数の列を選択することはできません。

これについてのご意見をお待ちしています。 ありがとう

答えて

6

レスポンスマークに感謝します。とても有難い。

結局、私は結局、結合ステートメントのテーブルの順序が違いを見出しました。最適なパフォーマンスとメモリ管理のためには、最後の結合が最大のテーブルである必要があります。

ジョインステートメントでテーブルの順序を変更することで問題が解決されました。

は、上記のご説明は、同様に非常に有用であるhttp://hive.apache.org/docs/r0.9.0/language_manual/joins.html

で最後の最大の表を参照してください。多くのありがとう

+5

本当に解決策ではなく正しい答えを感謝する独自の解決策を受け入れる代わりに、彼の解決策に同意するならば、Mark Groverの回答を「受け入れる」必要があります。上記のコメントに –

+0

+1しかし、私は彼が新しいので、彼はここでどのように動作するか分からなかったかもしれないと思う。 –

34

Hiveのバージョンと構成によっては、質問に対する回答が異なる場合があります。 正確なクエリを2つのテーブルのcreateステートメントおよびそれらのサイズの見積もりと共有することができれば、より簡単になります。

問題をよりよく理解するために、Hiveで「通常の」内部結合がどのように機能するかについて説明します。

ハイブは、MapReduceの中で参加する:ここで

は、MapReduceのにコンパイルされるインナーはハイブに参加する方法を簡単に説明します。一般的には、次のような結合問合せを持つ2つのテーブルT1およびT2を持っている場合:

、t1が以下の内容を持っている
SELECT 
    t1.key, t1.value, t2.value 
FROM 
    t1 
    JOIN 
    t2 (ON t1.key = t2.key); 

、t2は次のような内容がある
k_1 v1_1 
k_2 v1_2 
k_3 v1_3  

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に格納されていると仮定すると、その内容はファイル分割に分割されます。マッパーはファイル分割を入力としてテーブルのキー列としてキーを出力し、テーブルのvalue列とフラグ(レコードがどのテーブルかを表す、つまりt1またはt2)を合成した値を出力します。 。 T2の間

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

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

は今、これらのうち放出されるレコードが同じキーを持つすべてのレコードをまとめてグループ化に送られ、シャッフル相を経るT1の場合

減速機。各reduce操作のコンテキストは、1つのキーと、そのキーに対応するすべての値を含むリストです。実際には、1つの減速器がいくつかの減速操作を実行する。

上記の例では、我々は次のグループになるだろう。ここでは

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>> 

は減速に何が起こるかです。値のリスト内の値のそれぞれについて、値が異なる表に対応する場合、減算器は乗算を実行します。

k_1では、t2からの値はなく、何も出力されません。

K_2ために、値の乗算が放出される - K_2、v1_2、V2_2(各テーブルからの1つの値があるので、1×1 = 1)

K_3については、値の乗算が放出される - K_3、v1_3 、v2_3(各テーブルから1つの値があるので、1x1 = 1)

k_4の場合、t1の値はなく、何も出力されません。 したがって、内部結合から期待した結果が得られます。

私はどうしますか?

  1. データに歪みが存在する可能性があります。換言すれば、減速器がデータを取得すると、キーに対応する値のリストが非常に長くなり、エラーが生じる。 問題を緩和するには、JVMで使用可能なメモリを増やしてみてください。これを行うには、mapred.child.java.optsをhive-site.xmlに-Xmx512Mのような値に設定します。 Hiveシェルでset mapred.child.java.opts;を実行すると、このパラメーターの現在の値を照会できます。

  2. "通常の"結合の代替方法を試すことができます。マップ結合。上記のジョインの説明は、レデューサーで結合が行われる通常のジョインに適用されます。あなたが使用しているHiveのバージョンによって、Hiveは通常の結合をマップ結合に自動的に変換することができます。これは(結合がマップフェーズで行われるため)高速です。最適化を有効にするには、hive.auto.convert.jointrueに設定します。このプロパティは、truehive.auto.convert.joinの設定に加えて

  3. Hive 0.7に導入された、あなたはまた、truehive.optimize.skewjoinを設定することができます。これは、1に記載されているデータの問題のスキューを回避します。

関連する問題