1

我按照帮助如何处理来自alexeipab的猪溢出内存,它确实工作正常,但我现在有另一个问题,相同的示例代码:

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!!
}

我不能在那个组中使用 sum,这与没有盐计算的结果有很大不同。

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

4

2 回答 2

1

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

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

于 2012-08-23T15:28:38.053 回答
0

谢谢alexeipab,你给了我很大的帮助,我的做法如下

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

pymt = FOREACH pymt GENERATE *, (yyy%$prime_num) as salt;

pymt_grp_with_salt = GROUP pymt BY (key,salt);

有用!!

如果 yyy 是 num 整数,则可以使用 hash 将字符串或其他字符串转换为整数

于 2012-08-24T06:20:19.903 回答