2

Hiveのcollect_set()関数について学び、開発用の3ノードクラスターで仕事を始めました。

処理できるのは約10GBだけです。しかし、その仕事は文字通り永遠にかかっています。collect_set()の実装にバグがあるか、コードにバグがあるか、collect_set()関数が実際にリソースを大量に消費している可能性があると思います。

これがMySQLfor Hiveです(しゃれは意図されていません):

INSERT OVERWRITE TABLE sequence_result_1
SELECT sess.session_key as session_key,
       sess.remote_address as remote_address,
       sess.hit_count as hit_count,
       COLLECT_SET(evt.event_id) as event_set,
       hit.rsp_timestamp as hit_timestamp,
       sess.site_link as site_link
    FROM site_session sess 
        JOIN (SELECT * FROM site_event 
                WHERE event_id = 274 OR event_id = 284 OR event_id = 55 OR event_id = 151) evt 
            ON (sess.session_key = evt.session_key)
        JOIN site_hit hit ON (sess.session_key = evt.session_key)
GROUP BY sess.session_key, sess.remote_address, sess.hit_count, hit.rsp_timestamp, sess.site_link
ORDER BY hit_timestamp;

4つのMRパスがあります。最初は約30秒かかりました。2番目のマップは約1分かかりました。そして、2番目の削減のほとんどは約2分かかりました。過去2時間で、97.71%から97.73%に増加しています。これは正しいですか?何か問題があるに違いないと思います。ログを見てみましたが、正常かどうかわかりません。

【ログサンプル】

2011-06-21 16:32:22,715 WARN org.apache.hadoop.hive.ql.exec.GroupByOperator: Hash Tbl flush: #hash table = 120894
2011-06-21 16:32:22,758 WARN org.apache.hadoop.hive.ql.exec.GroupByOperator: Hash Table flushed: new size = 108804
2011-06-21 16:32:23,003 INFO org.apache.hadoop.hive.ql.exec.JoinOperator: 4 forwarding 5142000000 rows
2011-06-21 16:32:23,003 INFO org.apache.hadoop.hive.ql.exec.SelectOperator: 5 forwarding 5142000000 rows
2011-06-21 16:32:24,138 INFO org.apache.hadoop.hive.ql.exec.JoinOperator: 4 forwarding 5143000000 rows
2011-06-21 16:32:24,138 INFO org.apache.hadoop.hive.ql.exec.SelectOperator: 5 forwarding 5143000000 rows
2011-06-21 16:32:24,725 WARN org.apache.hadoop.hive.ql.exec.GroupByOperator: Hash Tbl flush: #hash table = 120894
2011-06-21 16:32:24,768 INFO org.apache.hadoop.hive.ql.exec.GroupByOperator: 6 forwarding 42000000 rows
2011-06-21 16:32:24,771 WARN org.apache.hadoop.hive.ql.exec.GroupByOperator: Hash Table flushed: new size = 108804
2011-06-21 16:32:25,338 INFO org.apache.hadoop.hive.ql.exec.JoinOperator: 4 forwarding 5144000000 rows
2011-06-21 16:32:25,338 INFO org.apache.hadoop.hive.ql.exec.SelectOperator: 5 forwarding 5144000000 rows
2011-06-21 16:32:26,467 INFO org.apache.hadoop.hive.ql.exec.JoinOperator: 4 forwarding 5145000000 rows
2011-06-21 16:32:26,468 INFO org.apache.hadoop.hive.ql.exec.SelectOperator: 5 forwarding 5145000000 rows

私はこれにかなり慣れていないので、collect_set()とHive Arrayを操作しようとすると、私は最深部から追い出されます。

前もって感謝します :)

4

3 に答える 3

2

大失敗。以下の私の解決策。結局、COLLECT_SET に問題はありませんでした。無限にあるすべてのアイテムを COLLECT しようとしただけです。

なんで?セットの一部でさえなかったものに参加したからです。2 番目の結合は同じ ON 条件でしたが、現在は正しく表示されますhit.session_key = evt.session_key

INSERT OVERWRITE TABLE sequence_result_1
SELECT sess.session_key as session_key,
       sess.remote_address as remote_address,
       sess.hit_count as hit_count,
       COLLECT_SET(evt.event_id) as event_set,
       hit.rsp_timestamp as hit_timestamp,
       sess.site_link as site_link
    FROM tealeaf_session sess 
        JOIN site_event evt ON (sess.session_key = evt.session_key)
        JOIN site_hit hit   ON (sess.session_key = hit.session_key)
    WHERE evt.event_id IN(274,284,55,151)
GROUP BY sess.session_key, sess.remote_address, sess.hit_count, hit.rsp_timestamp, sess.site_link
ORDER BY hit_timestamp;
于 2011-06-22T16:06:30.277 に答える
0

何が起こっているのかは、COLLECT_SET()返されるはずのforEACH行を生成していることだと思います。したがって、返す行ごとに、によって生成された配列全体が返されCOLLECT_SETます。それは負担がかかり、長い時間がかかるかもしれません。

クエリを実行せずにパフォーマンスを確認しCOLLECT_SETます。それが十分に高速である場合は、の計算をサブクエリにプッシュしてからCOLLECT_SET、現在の場所で計算を行う代わりにその列を使用します。

私はCOLLECT_SETを使用したり、テストを行ったりしていません。あなたの投稿から、それが私が最初に疑うものです。

于 2011-06-22T01:09:25.360 に答える
0

私が最初に試みることは、サブセレクトを取り除き、site_event に参加してから、event_id フィルターを外側の where 句に移動し、in() に変更することです。次のようなものです:

SELECT sess.session_key as session_key,
   sess.remote_address as remote_address,
   sess.hit_count as hit_count,
   COLLECT_SET(evt.event_id) as event_set,
   hit.rsp_timestamp as hit_timestamp,
   sess.site_link as site_link
FROM site_session sess 
    JOIN site_event evt ON (sess.session_key = evt.session_key)
    JOIN site_hit hit ON (sess.session_key = evt.session_key)
WHERE evt.event_id in(274,284,55151)
GROUP BY sess.session_key, sess.remote_address, sess.hit_count, hit.rsp_timestamp, sess.site_link
ORDER BY hit_timestamp;

さらに、各テーブルのサイズはわかりませんが、一般的に Hive では、最大のテーブル (通常はファクト テーブル) を結合の右側に保持して、メモリ使用量を削減します。その理由は、Hive が結合の左側をメモリに保持しようとし、結合を完了するために右側をストリーミングするためです。

于 2011-06-22T00:06:59.673 に答える