mapreduce中的高效设置操作

时间:2010-09-28 19:59:59

标签: hadoop mapreduce set

我继承了mapreduce代码库,主要计算不同广告随时间推移看到的唯一身份用户ID的数量。对我而言,它看起来并不是非常有效,我想知道是否有任何关于如何在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 个答案:

答案 0 :(得分: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); 

答案 1 :(得分:2)

Niels的解决方案很好,但是对于更接近原始代码并且仅使用一个地图缩减阶段的近似替代方案,只需用布隆过滤器替换该集合。布隆过滤器中的成员资格查询具有较小的错误概率,但尺寸估计非常准确。

相关问题