2011-06-21 48 views
2

我刚刚了解到Hive中的collect_set()函数,并且我开始了一个开发3节点集群的工作。Hive(Hadoop)中的COLLECT_SET()

我只有约10 GB的处理。但是,这项工作从字面上看是永远存在的。我认为可能有一个执行collect_set()的bug,我的代码中存在一个bug,或者collect_set()函数真的是资源密集型的。

,这里是我的蜂巢SQL(没有双关语意):

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秒。第二个地图花了大约1分钟。第二次减少大部分需要大约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工作()和蜂巢阵列是推动我过深结束。

感谢提前:)

回答

2

重大失败。下面我的解决方案毕竟COLLECT_SET没有问题,它只是试图收集所有的项目,其中有无限的。

为什么?因为我加入了一些甚至不属于这个集合的东西。第二个连接用来开启状态一样,现在它正确地说: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; 
0

第一件事,我会努力的摆脱子选择的,只是加盟site_event,然后将过滤器的event_id到外where子句并将其更改为一个在() 。因此,像:

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尝试将连接的左手边保存在内存中,并将右手边流到完成连接。

+0

不知道事实表右侧的规则,但这里已经是这样了。很好记住。我会尝试一下并让你知道。 – batman

+0

运行起来,初始部分稍快,但现在停留在97.71%的邻居。也许这就是运行collect_set()函数的阈值百分比。 – batman

+0

完全不同的问题。谢谢,我的回答如上。 – batman

0

我猜想会发生什么,它会产生一个COLLECT_SET()为每行将返回。 因此,对于您要返回的每一行,它都会返回由COLLECT_SET生成的整个数组。这可能会导致征税并需要很长时间。

检查性能与查询以外的COLLECT_SET。如果速度够快,将COLLECT_SET的计算推入子查询中,然后使用该列代替计算您的位置。

我没有使用COLLECT_SET或做过任何测试,从您的帖子,这是我第一次怀疑。

+0

有趣的想法。我明天更新。 – batman

+0

完全不同的问题。谢谢,我的回答如上。 – batman