2010-09-28 59 views
2

我已经继承了一个mapreduce代码库,它主要计算不同广告随时间变化的唯一用户ID数量。对我来说,它看起来并不像是非常有效地完成,我想知道是否有人有关于如何在mapreduce中尽可能高效地进行这种计算的任何提示或建议。mapreduce中的高效设置操作

我们使用Hadoop的,但我会用伪举一个例子,没有所有的克鲁夫特:

map(key, value): 
    ad_id = .. // extract from value 
    user_id = ... // extract from value 
    collect(ad_id, user_id) 

reduce(ad_id, user_ids): 
    uniqe_user_ids = new Set() 
    foreach (user_id in user_ids): 
    unique_user_ids.add(user_id) 
    collect(ad_id, unique_user_ids.size) 

这不是太多的代码,它不是很难理解,但它不是很有效。我们每天都会获得更多数据,因此我们每天都需要从一开始就查看所有广告展示次数,以计算该广告的唯一用户ID数量,因此每天都需要更长时间,并使用更多内存。此外,如果没有实际分析代码(不确定如何在Hadoop中执行此操作),我很确定几乎所有的工作都在创建一组唯一的ID。它也吃了大量的记忆。

我已经尝试过使用非mapreduce解决方案,并且获得了更好的性能(但问题在于如何按照我可以用Hadoop进行扩展的方式进行缩放),但感觉应该有一个更好的方式来做mapreduce我的代码。对其他人来说,解决这个问题一定是一个常见的问题。

如何使用mapreduce以有效的方式实现唯一ID的计数?

回答

2

问题是,您继承的代码是以“我将自己确定唯一集合”而不是“让我们利用框架为我来做”这样的思维方式编写的。

我想是这样的(伪),而不是:

map(key, value): 
    ad_id = .. // extract from value 
    user_id = ... // extract from value 
    collect(ad_id & user_id , unused dummy value) 

reduce(ad_id & user_id , unused dummy value): 
    output (ad_id , 1); // one unique userid. 

map(ad_id , 1): --> identity mapper! 
    collect(ad_id , 1) 

reduce(ad_id , set of a lot of '1's): 
    summarize ; 
    output (ad_id , unique_user_ids); 
2

尼尔斯的解决方案是好的,但因为这是更接近原始代码,并且只使用一个映射减少相近似替代,只需更换用布隆过滤器设置。布隆过滤器中的成员查询具有很小的错误概率,但尺寸估计非常准确。