[英]Hive cross join fails on local map join
是否有直接的方法來解決以下錯誤或總體上使用 Hive 獲得我需要的連接的更好方法? 不需要輸出到存儲表,因為我可以對 csv 的INSERT OVERWRITE LOCAL DIRECTORY
感到滿意。
我正在嘗試執行以下交叉連接。 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,Map 和 Reduce 階段完成到 100%,但隨后
2015-08-01 04:45:36,947 第一階段地圖 = 100%,減少 = 100%,累積 CPU 8767.09 秒
MapReduce 累積 CPU 總時間:0 天 2 小時 26 分 7 秒 90 毫秒
結束的工作 = job_201508010407_0001
Stage-8 由條件解析器選擇。
執行日志位於:/tmp/myuser/.log
2015-08-01 04:45:38 開始啟動本地任務來處理地圖加入; 最大內存 = 12221153280
執行失敗,退出狀態:3
獲取錯誤信息
任務失敗!
任務 ID:第 8 階段
日志:
/tmp/myuser/hive.log
失敗:執行錯誤,從 org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask 返回代碼 3
MapReduce Jobs Launched: Job 0: Map: 38 Reduce: 1 Cumulative CPU: 8767.09 sec
HDFS 讀取:9438495086 HDFS 寫入:8575548486 成功
我的蜂巢配置:
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 實例,worker 是 n1-highmem-4(4CPU 26GB),但我懷疑在 MAP 和 REDUCE 之后本地連接(如暗示的)發生在 Master 上。 無論如何,在 bdutils 中,我將工作節點( n1-highmem-4
highmem n1-highmem-4
)的 JAVAOPTS 配置為: n1-highmem-4
解決方案編輯:解決方案是將范圍數據中的數據組織到范圍樹中。
我認為不可能執行這種交叉連接蠻力 - 只需將行號相乘,這有點失控。 你需要一些優化,我認為 hive 還沒有能力。
但是,這個問題實際上可以在 O(N1+N2) 時間內解決嗎,前提是您對數據進行了排序(hive 可以為您做)-您只需同時瀏覽兩個列表,在每個步驟中獲取一個 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 的數據也是非常可行的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.