我正在使用Datafu的Hyperloglog UDF来估算数据集中唯一ID的数量。在这种情况下,我有3.2亿个唯一ID,可能会在我的数据集中出现多次。
Dataset : Country, ID.
这是我的代码:
REGISTER datafu-1.2.0.jar;
DEFINE HyperLogLogPlusPlus datafu.pig.stats.HyperLogLogPlusPlus();
-- id is a UUID, for example : de305d54-75b4-431b-adb2-eb6b9e546014
all_ids =
LOAD '$data'
USING PigStorage(';') AS (country:chararray, id:chararray);
estimate_unique_ids =
FOREACH (GROUP all_ids BY country)
GENERATE
'Total Ids' as label,
HyperLogLogPlusPlus(all_ids) as reach;
STORE estimate_unique_ids INTO '$output' USING PigStorage();
使用120减速器我发现其中大部分都在几分钟内完成。然而,少数减速器被数据超载并永远运行。我24小时后杀了他们。
我认为Hyperloglog比计算真实更有效率。这里出了什么问题?
答案 0 :(得分:0)
在DataFu 1.3.0中,添加了一个Algebraic的HyperLogLog实现。这允许UDF使用组合器,并且可能会改善偏斜情况下的性能。
但是,在the comments in the Jira issue中讨论了使用HyperLogLog时可能出现的其他一些性能问题。相关报价如下:
要记住的是HyperLogLogPlus的每个实例都分配了一个相当大的字节数组。我不记得确切的数字,但我认为默认精度为20,它是几百KB。因此,在您的示例中,如果“a”的基数很大,您将分配许多需要从组合器传输到reducer的大字节数组。因此,除非您知道关键基数非常小,否则我会避免在“分组依据”情况下使用它。这个UDF更适合于拥有大量输入数据的“所有组”场景。此外,如果输入数据远小于字节数组,那么使用此UDF可能会更糟糕。如果你可以接受更低的精度,那么字节数组可以变得更小。