Hive交叉加入在本地地图加入

时间:2015-08-01 17:39:26

标签: hadoop join hive cross-join google-hadoop

是否有直接的方法来解决以下错误或整体更好的方法来使用Hive来获得我需要的连接?输出到存储表不是必需的,因为我可以满足于INSERT OVERWRITE LOCAL DIRECTORY到csv。

我正在尝试执行以下交叉连接。 ipint是一个9GB的表,geoiplite是270MB。

CREATE TABLE iplatlong_sample AS
SELECT ipintegers.networkinteger, geoiplite.latitude, geoiplite.longitude
FROM geoiplite
CROSS JOIN ipintegers
WHERE ipintegers.networkinteger >= geoiplite.network_start_integer AND ipintegers.networkinteger <= geoiplite.network_last_integer;

我在ipintegers上使用CROSS JOIN而不是geoiplite,因为我已经读过规则是让小桌子在左边,在右边更大。

根据HIVE,地图和减少阶段完成100%,但随后

  

2015-08-01 04:45:36,947 Stage-1 map = 100%,reduce = 100%,累积   CPU 8767.09秒

     

MapReduce累计CPU总时间:0天2小时26   分7秒90毫秒

     

结束工作= job_201508010407_0001

     

第8阶段由条件解析器选择。

     

执行日志:/tmp/myuser/.log

     

2015-08-01 04:45:38开始启动本地任务来处理地图   加入;最大记忆= 12221153280

     

执行失败并退出状态:3

     

获取错误信息

     

任务失败!

     

任务ID:Stage-8

     

日志:

     

/tmp/myuser/hive.log

     

失败:执行错误,返回代码3   org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask​​

     

MapReduce Jobs   推出:工作0:地图:38减少:1累计CPU:8767.09秒
  HDFS阅读:9438495086 HDFS写:8575548486成功

我的hive配置:

SET hive.mapred.local.mem=40960;
SET hive.exec.parallel=true;
SET hive.exec.compress.output=true;
SET hive.exec.compress.intermediate = true;
SET hive.optimize.skewjoin = true;
SET mapred.compress.map.output=true;
SET hive.stats.autogather=false;

我在 true false 之间有SET hive.auto.convert.join个变化,但结果相同。

以下是来自/tmp/myuser/hive.log

的输出日志中的错误
$ tail -12 -f tmp/mysyer/hive.log

2015-08-01 07:30:46,086 ERROR exec.Task (SessionState.java:printError(419)) - Execution failed with exit status: 3
2015-08-01 07:30:46,086 ERROR exec.Task (SessionState.java:printError(419)) - Obtaining error information
2015-08-01 07:30:46,087 ERROR exec.Task (SessionState.java:printError(419)) -
Task failed!
Task ID:
  Stage-8

Logs:

2015-08-01 07:30:46,087 ERROR exec.Task (SessionState.java:printError(419)) - /tmp/myuser/hive.log
2015-08-01 07:30:46,087 ERROR mr.MapredLocalTask (MapredLocalTask.java:execute(268)) - Execution failed with exit status: 3
2015-08-01 07:30:46,094 ERROR ql.Driver (SessionState.java:printError(419)) - FAILED: Execution Error, return code 3 from org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask

我在Master上运行hive客户端,类型为n1-highmem-8型(8 CPU,52GB)的Google Cloud Platform实例,工作人员为n1-highmem-4(4CPU 26GB),但我怀疑在MAP之后并减少本地加入(如暗示)在主人身上发生。无论如何,在bdutils中我为工作节点(n1-highmem-4)配置了JAVAOPTS:n1-highmem-4

解决方案编辑:解决方案是将范围数据组织到范围树中。

1 个答案:

答案 0 :(得分:1)

我不认为有可能执行这种交叉连接蛮力 - 只是乘以行数,它有点失控。你需要一些优化,我认为蜂巢还没有。

但是这个问题实际上可以在O(N1 + N2)时间内解决,只要您对数据进行排序(哪个配置单元可以为您做) - 您只需同时浏览两个列表,每一步获取一个ip整数,看看是否有任何间隔从这个整数开始,添加它们,删除那些结束,发出匹配的元组,等等。伪代码:

intervals=[]
ipintegers = iterator(ipintegers_sorted_file)
intervals = iterator(intervals_sorted_on_start_file)
for x in ipintegers:
    intervals = [i for i in intervals if i.end >= x]

    while(intervals.current.start<=x):
        intervals.append(intervals.current)
        intervals.next()
    for i in intervals:
        output_match(i, x)

现在,如果你有一个外部脚本/ UDF函数知道如何读取较小的表并获取ip整数作为输入并将匹配元组作为输出吐出,则可以使用hive和SELECT TRANSFORM将输入流式传输到它

或者您可以在具有两个输入文件的本地计算机上运行此算法,因为这只是O(N),甚至9 gb的数据也非常可行。