我遵循alexeipab的How to handle spill memory in pig帮助,它确实可以正常工作,但是现在我还有另一个问题,相同的示例代码:

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

pymt_grp_with_salt = GROUP pymt BY (key,salt)

results_with_salt = FOREACH pymt_grp {
    --distinct
    mid_set = FILTER pymt BY xxx=='abc';
    mid_set_result = DISTINCT mid_set.yyy;
    result = COUNT(mid_set_result)
}

pymt_grp = GROUP results_with_salt BY key;

result = FOREACH pymt_grp {

   GENERATE SUM(results_with_salt.result); --it is WRONG!!
}

我不能在该组中使用总和,这与不加盐的计算结果有很大不同。

有什么解决办法吗?如果先进行过滤,则会花费很多JOIN工作,并且会降低性能。

最佳答案

为此,您需要在mid_set.yyy和salt之间建立多对一的关系,以便将来自不同行的mid_set.yyy的相同值映射到相同的salt值。如果不是,则该值mid_set.yyy将出现在GROUP pymt BY(键,盐)生产的不同袋子中,可以在DISTINCT中以不同的盐生存,因此多次包含在最终汇总中。这就是为什么在使用盐和COUNT DISTINCT时会得到错误的结果的原因。

一种简单的方法可能是用mid_set.yyy本身替换盐,或者编写一个UDF /静态方法,该方法通过获取mid_set.yyy的哈希值来计算盐,并使用mod N,其中N可以为1到无穷大,为了获得最佳分布N一个质数。

关于hadoop - 如何用盐处理DISTINCT,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12087690/

10-10 17:01