2012-12-08 64 views
4

我有一個豬腳本,屬於2豬關係,可以說A和B.A是一個小關係,B是一個大關係。我的UDF應該將所有的A加載到每臺機器的內存中,然後在處理B時使用它。目前我這樣做。Apache Pig將整個關係加載到UDF中

A = foreach smallRelation Generate ... 
B = foreach largeRelation Generate propertyOfB; 
store A into 'templocation'; 
C = foreach B Generate CustomUdf(propertyOfB); 

然後我讓每一臺機器都從'templocation'加載到A上。這樣做有效,但是我有兩個問題。

  1. 我的理解是我應該以某種方式使用HDFS緩存,但我不確定如何將關係直接加載到HDFS緩存中。
  2. 當我在我的UDF中重新加載文件時,我必須編寫邏輯來解析從輸出到文件的輸出,當我寧願直接使用包和元組時(是否有內置的Pig java函數來解析字符串回到Bag/Tuple形式?)。

有誰知道它應該怎麼做?

+0

做A和B有列你可以做一個JOIN? – alexeipab

+0

在這種情況下,是的,他們有相同的數據並可以加入。我需要比較A的每一行和B的每一行。我想我可以做一個交叉連接,但這不會更低效嗎?我將重新處理B A - 超過必要的1倍,並且我將失去一次一行地運行B所有行的能力,這是必需的。 – Manny

+0

你可以發表一個輸入和輸出數據的例子嗎? – alexeipab

回答

0

這是一個可以幫助你的技巧。

您先完成一個GROUP ALL,它將A中的所有數據「包裝」到一個字段中。然後人爲地在A和B上添加一個公共字段並加入它們。這樣,在增強B中的foreach元組中,您將擁有A的完整數據供您的UDF使用。

是這樣的:

(比如最初在A,你有域FA1,FA2,FA3,在你FB1,FB2 B)

-- add an artificial join key with value 'xx' 
B_aux = FOREACH B GENERATE 'xx' AS join_key, fb1, fb2; 
A_all = GROUP A ALL; 
A_aux = FOREACH A GENERATE 'xx' AS join_key, $1; 
A_B_JOINED = JOIN B_aux BY join_key, A_aux BY join_key USING 'replicated'; 

C = FOREACH A_B_JOINED GENERATE CustomUdf(fb1, fb2, A_all); 
因爲這

複製加盟,這也是隻有地圖端連接。

+0

我認爲我目前的解決方案只需將HDFS保存在AFS中,然後將其加載到我所有的還原器中就比採用笛卡爾產品更高效。希望能夠找到一種不詭計的方式來做到這一點。 – Manny

+0

對不起,我把A和B弄混了。我認爲A是更大的關係,B更小。我改變了我的代碼。我擁有的代碼根本不是笛卡兒的產品,它只是地圖邊連接非常高效,而且您不必在UDF中處理讀取/解析A(想象一下,您想在本地模式下測試它,然後您的UDF將不起作用) –

+0

GROUP ALL不是地圖端,只有連接是 – bridiver