0

次の形式のハイブ クエリを実行しています。

INSERT OVERWRITE LOCAL DIRECTORY ...
SELECT /*+ MAPJOIN(...) */ * FROM ...

のためMAPJOIN、結果には削減フェーズは必要ありません。マップ フェーズでは約 5000 人のマッパーを使用し、ジョブを完了するのに約50 分かかります。この時間のほとんどは、これらの 5000 個のファイルをローカル ディレクトリにコピーするのに費やされていることがわかりました。

これを最適化するために、2 番目のマップ削減ジョブを強制するために (結果が既に明確であることは事前にわかっているため、実際に結果が変わるわけではありません)に置き換えSELECT * ...ました。SELECT DISTINCT * ...最初の map reduce ジョブは前と同じで、5000 のマッパーと 0 のレデューサーを使用します。2 番目のマップ削減ジョブには、5000 のマッパーと 3 のレデューサーが含まれています。この変更により、コピーするファイルが 5000 個ではなく 3 個になり、クエリにかかる時間は合計で約20 分になりました。

実際には必要ないのでDISTINCTDISTINCT?

4

1 に答える 1

1

クエリを別の SELECT でラップし、おそらく役に立たない WHERE 句を使用して、ジョブを確実に開始するようにします。

INSERT OVERWRITE LOCAL DIRECTORY ...
SELECT *
FROM (
    SELECT /*+ MAPJOIN(...) */ *
    FROM ..
) x
WHERE 1 = 1

明日機会があればこれを実行し、うまくいかない場合は回答のこの部分を削除します。あなたが私の前にそれを取得する場合は、素晴らしいです。

別のオプションは、ファイル名と行番号の仮想列を利用して、異なる結果を強制することです。これによりクエリが複雑になり、2 つの無意味な列が導入されますが、結果が異なることを事前に知る必要がないという利点があります。役に立たない列を保持できない場合は、別の SELECT でラップして削除します。

INSERT OVERWRITE LOCAL DIRECTORY ...
SELECT {{enumerate every column except the virutal columns}}
FROM (
    SELECT DISTINCT /*+ MAPJOIN(...) */ *, INPUT__FILE__NAME, BLOCK__OFFSET__INSIDE__FILE 
    FROM ..
) x

どちらのソリューションも、思いついたものよりも面倒ですが、明確な結果を持つクエリに限定されないという利点があります。

Hive に限定されていない場合は、別のオプションがあります。を取り除きLOCAL、結果を HDFS に書き込むことができます。これは、5000 のマッパーでも高速であるはずです。次に、 を使用hadoop fs -getmerge /result/dir/on/hdfs/して結果をローカル ファイル システムにプルします。残念ながら、これは Hive の外部に到達しますが、2 段階の Oozie ワークフローを設定することは、ユース ケースに受け入れられる可能性があります。

于 2013-10-25T05:31:37.493 に答える