2012-08-17 92 views
2

我的代碼就像這樣:如何處理豬溢出內存

pymt = LOAD 'pymt' USING PigStorage('|') AS ($pymt_schema); 

pymt_grp = GROUP pymt BY key 

results = FOREACH pymt_grp { 

     /* 
     * some kind of logic, filter, count, distinct, sum, etc. 
     */ 
} 

但現在我發現很多日誌這樣的:

org.apache.pig.impl.util.SpillableMemoryManager: Spilled an estimate of 207012796 bytes from 1 objects. init = 5439488(5312K) used = 424200488(414258K) committed = 559284224(546176K) max = 559284224(546176K) 

其實我找到原因,大多數的原因是有一個「熱」鍵,有些東西像key = 0作爲ip地址,但我不想過濾這個鍵。有沒有解決方法?我在我的UDF中實現了代數和累加器接口。

+0

,它記錄看起來像聚集放緩。如果我過濾這個熱鍵,它可能花費5分鐘,但如果不過濾,它將花費超過2小時。 – mark 2012-08-17 03:13:58

回答

6

我有嚴重傾斜的數據或嵌套在FOREACH中的DISTINCT的類似問題(因爲PIG會在內存中做不同)。解決的辦法是把DISTINCT從FOREACH中拿出來看看我的回答How to optimize a group by statement in PIG latin?

如果你不想在SUM和COUNT之前做DISTINCT比我建議使用2 GROUP BY。第一組在Key列上加上另一列或隨機數字100,它充當Salt(將單個密鑰的數據分散到多個Reducer中)。比第二個GROUP BY僅在Key列上計算組1的COUNT或Sum的最終總和。

例:

inpt = load '/data.csv' using PigStorage(',') as (Key, Value); 
view = foreach inpt generate Key, Value, ((int)(RANDOM() * 100)) as Salt; 

group_1 = group view by (Key, Salt); 
group_1_count = foreach group_1 generate group_1.Key as Key, COUNT(view) as count; 

group_2 = group group_1_count by Key; 
final_count = foreach group_2 generate flatten(group) as Key, SUM(group_1_count.count) as count; 
+0

感謝Alexeipab,通過您的建議來完成任務。 – mark 2012-08-20 06:28:49

+0

有趣。我有相同的SpillableMemoryManager日誌消息,但是我沒有任何DISTINCT子句。我確實有JOIN,GROUP,inner ORDER和inner LIMIT。 – Marquez 2013-09-04 13:46:23

+0

GROUP將創建一個太大的內部ORDER排序內存。任何超出我認爲90Mb的BAG上的內部操作(DISTINCT或ORDER)都會引發錯誤。在你的情況下,你可以在鹽醃團體中找到最小分鐘數和最小分鐘數。使用GROUP BY(ID,SALT)查找最小值/最大值,這將創建更多更小且適合RAM的BAG。比flatten再次GROUP BY(id) – alexeipab 2013-09-05 16:16:01