2015-08-08 69 views
0

我想知道將來自 的所有字段/列合併成單個文件的有效方法。對於每一個將來自50個大文件的列/字段合併到一個文件中

文件1:

1,fname1,one 
2,fname2,two 

文件2:

1,lname1,lone 
2,lname2,ltwo 

預計輸出

1,fname1, one,lname1,lone 
2,fname2,two,lname2,ltwo 

我身邊有70個文件這樣有1億多條記錄與各6列。

目前我正在嘗試使用蜂巢式連接來做到這一點。它似乎永遠在運行 - 差不多24小時仍在運行。我需要更好的解決方案。

+0

你的問題不是很清楚......你能否正確指定例子 – Amar

+0

@Mahesh:有沒有更好的方法來做到這一點? – Learner

回答

1

以「天真」的方式加入70個文件意味着Hive必須按順序執行69個JOIN步驟,左側數據集越來越大。 如果你用嵌套的子查詢顯式地分解任務 - 即將A與B,C與D,AB與CD等連接起來 - 它將不那麼災難性,但仍然是資源密集型的。

在任何情況下,Hive都不會利用所有文件已經排序的事實(請參閱關於Sort-Merge連接的文檔以及關於bucketization的明確要求)

實際上,您的問題與大型機上的COBOL一樣古老。我不確定它可以以分佈式方式高效解決(需要將文件始終以一致的方式進行分區)。所以請考慮非Hadoop的解決方案:

  • 如果你想性能和工業級的解決方案 - 和 有大量現金花 - 然後買Syncsort公司的許可或 類似工具
  • 如果你只是想找到工作,現在做了,所有的文件 下載到一臺Linux機器,並嘗試美好的舊sort -m命令(不知道 的RAM和交換的影響,雖然)
+0

感謝您的迴應。是的,我已經嘗試了分解成多個連接的方法。事實上,我的24小時計時只是在分批加入之後。好的舊類型在這裏不起作用。這是一個真正的大數據問題,無法通過舊的方式解決。 –

+0

@Amar:我也舉了一個例子。當你說不清楚時,我不確定你在找什麼。你能否詳細說明一下。 –

0

以2:怎麼樣,而不是多個JOIN創建一個龐大的「稀疏」表,然後運行一個龐大的GROUP BY?

  • 創建臨時表與所有預期的101米的cols
  • 創建每3列映射到你50的源文件(在50個不同的目錄)50個外部表,當然
  • 運行50 INSERT的 - SELECT查詢將每個文件加載到臨時表中,在適當的列中,即

insert into table SPARSE select ID, CODE1, VAL1, null, null, null, ... from SOURCE1 ; insert into table SPARSE select ID, null, null, CODE2, VAL2, null, ... from SOURCE2 ;

  • 運行最終GROUP BY變平的結果是:對於給定的ID存在用於CODE1只有一個非空值,因此最大(CODE1)實際上將意味着「獲得從SOURCE1附帶的價值和從其他渠道忽略空值」

select ID, Max(CODE1), Max(VAL1), Max(CODE2), ... from SPARSE group by ID

我不是100%確定它可以打敗您當前的24小時處理;但它可能值得一試。希望單個大規模的MapReduce作業比分佈式JOIN的多個作業更有效率。

~~~~

順便說一句,大量GROUP BY可能需要仔細調整,即檢查映射器的數量&減速意義(如果沒有,請嘗試在臨時表運行統計和/或者硬性設置某些屬性),確保使用Snappy或LZ4壓縮中間結果(以減少I/O佔用空間和合理的CPU開銷)等等。通常的東西。

一個主要的優化可能涉及臨時表上的桶;但是你不能對bucketized表運行多個INSERT,所以你將不得不嘗試一個大規模的INSERT OVERWRITE - SELECT UNION ALL SELECT UNION ALL ... yuck。

+0

謝謝,似乎很合理。我有其他的想法。我不知道該怎麼做,但這是我的想法。水平分區數據。我的意思是我將在單個文件中爲所有範圍的ID創建所有列。下一個範圍將在不同的文件中 –

相關問題