Map Reduce Job可在时间窗口中查找热门项目

时间:2018-05-03 04:30:16

标签: hadoop mapreduce bigdata

我在接受采访时被问到这个问题,我不确定我是否给出了正确的答案,所以我想要一些见解。

问题:有一组用户和项目。在每一分钟,我都会收到一个元组列表(用户,项目),表示用户 u 消耗的项目 i 。我需要在过去一小时内找到前100个热门项目,即计算每个项目消耗的用户数量并对其进行排序。这里的诀窍是,在过去的一小时内,如果一个项目被同一个用户多次使用,则只考虑一次消费。不允许同一用户重复消费。面试官说我应该认真思考,每小时会有数百万的消费。所以,他建议我做一个map-reduce工作或者每分钟可以处理大量数据的东西。

我提出的解决方案:我说我可以维护一个消费的用户项 - 时间戳元组的列表(或者你喜欢的矩阵),就像有时间一样 - 窗口移位。类似的东西:

  • U1,I1,T1
  • U1,I2,T1
  • u2,i2,t2 ......等等。

在每分钟,当我收到此分钟的用户项目消耗流时,我首先使用当前时间戳创建map-reduce作业以更新时间窗口矩阵。这个map-reduce作业可以由两个映射器完成(一个用于流,另一个用于时间窗口列表),reducer将简单地获得每对的最大值。我所做的伪代码:

mapTimeWindow(line):
    user, item, timestamp = line.split(" ")
    context.write(key=(user,item), value=timestamp)

mapStream(line):
    user, item = line.split(" ")
    context.write(key=(user,item), value=now())

reducer(key, list):
    context.write(key=(user,item), value=max(list))

接下来,我还通过计算每个用户在该列表中出现的时间来执行map-reduce来计算流行度。我的地图读取更新的时间窗口列表和写入项目1.减速器计算每个项目的列表总和。由于我存储了所有时间戳,因此我验证消耗是否在过去一小时内。另一个map-reduce伪代码:

mapPopularity(line):
    user, item, timestamp = line.split(" ")
    if now()-60>timestamp:
         return
    context.write(key=item, value=1) # no repetition

reducerPopularity(key, list):
    context.write(key=item, value=sum(list))

稍后我们可以执行另一个map-reduce来读取第二个作业的结果并计算top100最大的项目。像this那样做的事情。

我的问题:这个解决方案对于我的采访是否可以接受?它包含三个map-reduce来解决问题。但是,在我看来,每分钟都要执行很多。由于它需要每分钟更新一次,因此不能持续更长时间。我的意思是,我付出了很多努力,但面试官并没有给我反馈,如果它是对的。我想知道:是否可以加快速度?或者是否有可能以另一种方式处理这个问题? (也许不是map-reduce)

0 个答案:

没有答案