假设我有三个基本模型:用户,公司和访问。用户每次访问公司时,都会以(user_id, company_id, visit_date)
格式记录访问次数。
我希望能够计算出公司的平均访问时间。不是整体访问,而是特别是他们的客户在返回商店之前平均等待多长时间。
例如,如果一个用户在星期二,星期三和星期五访问,则给出一天的“间隙”,以及两天的一个“差距”=> (1,2)。如果另一个用户在星期一和星期五访问,则给出一个4天的差距=> (4)。如果第三个用户只访问过一次,则不应考虑他。公司用户访问的平均时间为(1 + 2 + 4)/ 3 = 2.333天。
如果我有成千上万的用户,水龙头和公司,我想为每家公司计算一个数字,我该怎么办呢?我之前只完成了基本的MapReduce应用程序,我无法弄清楚我的Map和Reduce步骤是如何完成的。任何人都可以帮我找出伪代码中的MapReduce吗?或者是否有其他分布式计算方法可以合理地执行?为了记录,我想每晚在我的数据库上执行此操作。
答案 0 :(得分:0)
过于简单化的方法是有两个工作步骤。
第一个作业步骤有一个映射器,用于以“company:user”和“visit_date”的形式写入键值。在上面的示例中,映射器将编写类似于:
的内容"user1:companyA" -> "2012/07/16"
"user1:comapnyA" -> "2012/07/17"
"user1:comapnyA" -> "2012/07/19"
"user2:comapnyA" -> "2012/07/15"
"user2:comapnyA" -> "2012/07/19"
...
这意味着每次调用reducer都会将单个用户的所有访问传递给单个公司。这意味着对reducer的一次调用将传入:
"user1:companyA" -> {2012/07/16, 2012/07/17, 2012/07/19}
另一个电话会传入:
"user2:companyA" -> {2012/07/15, 2012/07/19}
我假设在排序时很容易管理日期集(作为Iterable值传递),找出差距并将每个间隙的记录写为“公司”形式的键值对, “间隙”。例如,传递时:
"user1:companyA" -> {2012/07/16, 2012/07/17, 2012/07/19}
第一份工作的减速器将写入上下文:
"companyA" -> 1
"compnayA" -> 2
第二个作业有一个传递映射器,它只是将公司/间隙信息传递给reducer。每次调用reducer都会为特定公司提供一个Iterable间隙值。迭代数据以产生平均值,并以“company”和“average_gap”的形式写出键值对。
如果原始访问次数太大,我们可以谈谈让hadoop为您做一些自定义比较器的排序。