• 1
  • 2
  • 3
  • 4
  • 5
阿里云应用开发 首 页  »  帮助中心  »  云服务器  »  阿里云应用开发
mapreduce top n实现方式实例解说
发布日期:2016-8-3 15:8:12

  在最初接触mapreduce的时候,top n 问题的解决办法是将mapreduce输出(排序后)放入一个集合中,取前n个,但是这种写法过于简单,内存能加载的集合的大小是有上限的,一旦数据量大,很容易出现内存溢出。

  现在在这里介绍另一种实现方式,不过这也不是最好的方式,但正所谓一步一个脚印,迈好每一步,以后的步伐才能更坚定。关注阿里云的动态,以后还会有更好的方式需求,得到top 最大的前n条记录。

  这里只给出一些核心的代码,其他job等配置的代码略。

  Configuration conf = new Configuration(); conf.setInt("N", 5);

  初始化job前需要 conf.setInt("N",5); 意在在mapreduce阶段读取N,N就代表着top N。

  以下是map

  接下来是reduce

 


  在这里说一下逻辑,尽管画图比较清晰,但时间有限,画图水平有限,只用语言来描述吧,希望能说的明白。

  若要取top 5,则应该定义一个长度为为6的数组,map所要做的事情就是将每条日志的那个需要排序的字段放入数组第一个元素中,调用Arrays.sort(Array[])方法可将数组按照正序,从数字角度说是从小到大排序,比如第一条记录是9000,那排序结果是[0,0,0,0,0,9000],第二条日志记录是8000,排序结果是[0,0,0,0,8000,9000],第三条日志记录是8500,排序结果是[0,0,0,8000,8500,9000],类推,每次放进去一个数字若大于数组里面最小的元素,相当于将最小的覆盖掉了,也就是说数组中元素永远是拿到日志中最大的那些个记录。

  ok,map将数组原封不动按照顺序输出,reduce接收到从每个map拿到的五个排好序的元素,在进行跟map一样的排序,排序后数组里面就是按照从小到大排好序的元素,最终将这些元素倒序输出就是我们要的结果了。

  同之前的方式做个比较,之前的map做的事情很少,在reduce中排序后哪前5条,reduce的压力是很大的,要把所有的数据都处理一遍,而一般设置reduce的个数较少,一旦数据较多的话,reduce就会承受不了,悲剧了。而现在的方式巧妙的将reduce的压力转移到了map,而map是集群效应的,很多台服务器来做这件事情,减少一台机器上的负担,每个map其实只是输出了5个元素,若有5个map,其实reduce才对5*5个数据进行了操作,就不会出现内存溢出等问题了。