思想比较简单,就是每个通过map来获取当前的数据块中的的topk个数据,然后将他们以相同的key值放到reduce中,最后通过reduce来对这n*k个数据排序并获得topk个数据。具体的就是建立一个k个大小的数组,一开始初始化为都是100(假定这里的100是最大的数),然后往里面插数据小的数据即可。

 
PS:有几个小细节以及当时写代码的时候出错的地方。
1 map和reduce都是在每个键值对来的时候会被调用。当时觉得应该把这k的数组放在哪,以及怎么初始化。如果放在map方法里面,那每次都会被初始化,岂不是白搞了。如果把这数组当作局部变量,那肯定是不行的,因为当作局部变量就无法实现存放k个数据了。只能存放当前的数据。后来查了资料发现,有个setup这个函数,就是用于mapper中的某些数据的初始化,这样就可以把数组作为mapper的属性,然后在setup中进行初始化了。
2 当我全部遍历完这个数据分片的数据后,并且已经获得了当前mapper中的topk了,我如何把数据传到reducer呢,最理想的就是在遍历完后才把数据发送过去,但是以前都是处理一个键值对就发送一个,然后查了下,发现有个cleanup函数,就是用于mapper或者reducer结束后用的,那么就可以通过这个函数来发送键值对了。
3 这是个逻辑上的问题,我这里的topk是选最小的几个,然后当时写的是,先将数组排序,然后从前往后查询,如果发现value<list[i]那么就将该数组中数据替换,但是这个有问题,例如有这样的
45
21
75
94
1
34
56
7
67
按照我一开始的逻辑是,
45,100,100
21,100,100显然这一步就错了,应该是21,45,100所以应该是从后往前的查询,每次查询能替换的最大的数据,而不是从前往后的查询替换最小的数据
 
具体代码:
Map
 
                 public void setup(Context context){
                                Configuration conf=context.getConfiguration();
                                 int k=Integer.parseInt(conf.get( "k" ));
                                 list =new int[k];
                                 for (int i=0;i<k;i++){
                                                 list [i]=100;
                                }
                }
                
                 public void cleanup(Context context) throws IOException, InterruptedException{
                                 for (int i=0;i< list. length ;i++){
                                                context.write( new IntWritable(0), new IntWritable( list[i]));
                                                System. out .println("                                 ");
                                                System. out .println("map is " + list[i]);
                                                System. out .println("                                 ");
                                }
                }
                
                 public void map(LongWritable ikey, Text ivalue, Context context)
                                                 throws IOException, InterruptedException {
                                Configuration conf=context.getConfiguration();
                                 int k=Integer.parseInt(conf.get( "k" ));
                                 int value=Integer.parseInt(ivalue.toString());
                                
                                Arrays. sort( list);
                                System. out .println("                                 ");
                                System. out .println("n is " + n);
                                System. out .println("                                 ");
 
                                                 for (int j=k-1;j>=0;j--){
                                                                 if (value<list [j]){
                                                                                 list [j]=value;
                                                                                 break ;
                                                                }
                                                }
                                
                                
                }
 
}
 
Reducer
 
                 public void setup(Context context){
                                Configuration conf=context.getConfiguration();
                                 int k=Integer.parseInt(conf.get( "k" ));
                                 list =new int[k];
                                 for (int i=0;i<k;i++){
                                                 list [i]=100;
                                }
                }
                
                 public void cleanup(Context context) throws IOException, InterruptedException{
                                Arrays. sort( list);
                                 for (int i=0;i< list. length ;i++){
                                                context.write( new IntWritable(i), new IntWritable( list[i]));
                                }
                }
                
                
                 public void reduce(IntWritable _key, Iterable<IntWritable> values, Context context)
                                                 throws IOException, InterruptedException {
                                 // process values
                                Configuration conf=context.getConfiguration();
                                 int k=Integer.parseInt(conf.get( "k" ));
                                 for (IntWritable val : values) {
                                                 /*
                                                System.out.println("                                 ");
                                                System.out.println("value is "+val.get());
                                                System.out.println("                                 ");
                                                */
                                                Arrays. sort( list);
 
                                                                 for (int j=k-1;j>=0;j--){
                                                                                 if (val.get()<list [j]){
                                                                                                 list [j]=val.get();
                                                                                                 break ;
                                                                                }
                                                                }
                                                                
                                                
                                }
                }

Mapreduce TopK的更多相关文章

  1. MapReduce TopK统计加排序

    Hadoop技术内幕中指出Top K算法有两步,一是统计词频,二是找出词频最高的前K个词.在网上找了很多MapReduce的Top K案例,这些案例都只有排序功能,所以自己写了个案例. 这个案例分两个 ...

  2. 使用MapReduce实现一些经典的案例

    在工作中,很多时候都是用hive或pig来自动化执行mr统计,但是我们不能忘记原始的mr.本文记录了一些通过mr来完成的经典的案例,有倒排索引.数据去重等,需要掌握. 一.使用mapreduce实现倒 ...

  3. MapReduceTopK TreeMap

    版权声明: https://blog.csdn.net/zhangxiango/article/details/33319281 MapReduce TopK统计加排序中介绍的TopK在mapredu ...

  4. MapReduce实现TopK的示例

    由于开始学习MapReduce编程已经有一段时间了,作为一个从编程中寻找自信和乐趣以及热爱编程的孩子来讲,手开始变得很“痒”了,很想小试一下身手.于是自己编写了TopK的代码.TopK的意思就是从原文 ...

  5. Hadoop学习笔记—12.MapReduce中的常见算法

    一.MapReduce中有哪些常见算法 (1)经典之王:单词计数 这个是MapReduce的经典案例,经典的不能再经典了! (2)数据去重 "数据去重"主要是为了掌握和利用并行化思 ...

  6. mapReduce编程之auto complete

    1 n-gram模型与auto complete n-gram模型是假设文本中一个词出现的概率只与它前面的N-1个词相关.auto complete的原理就是,根据用户输入的词,将后续出现概率较大的词 ...

  7. mapReduce编程之Recommender System

    1 协同过滤算法 协同过滤算法是现在推荐系统的一种常用算法.分为user-CF和item-CF. 本文的电影推荐系统使用的是item-CF,主要是由于用户数远远大于电影数,构建矩阵的代价更小:另外,电 ...

  8. InAction-MR的topK

    本来只是想拿搜狗的数据练练手的,却无意踏足MR的topK问题.经过几番波折,虽然现在看起来很简单,但是摸爬滚打中也学到了不少 数据是搜狗实验室下的搜索日志,格式大概为: 00:00:00 298219 ...

  9. MapReduce 支持的部分数据挖掘算法

    MapReduce 支持的部分数据挖掘算法 MapReduce 能够解决的问题有一个共同特点:任务可以被分解为多个子问题,且这些子问题相对独立,彼此之间不会有牵制,待并行处理完这些子问题后,任务便被解 ...

随机推荐

  1. iOS 常用代码块

    1.判断邮箱格式是否正确的代码: // 利用正则表达式验证 -( BOOL )isValidateEmail:( NSString  *)email {   NSString  *emailRegex ...

  2. Android &Swift iOS开发:语言与框架对比

    转载自:http://www.infoq.com/cn/articles/from-android-to-swift-ios?utm_campaign=rightbar_v2&utm_sour ...

  3. html5利用websocket完成的推送功能

    利用websocket和java完成的消息推送功能,服务器用的是tomcat7.0,一些东西是自己琢磨的,也不知道恰不恰当,不恰当处,还请各位见谅,并指出. 程序简单来说,就是客户A可以发送消息给客户 ...

  4. c++ 中bool 的默认值

    比如在Test.h中定义变量: _isFirst; //Test.h头文件 #ifndef __TEST_H__ #define __TEST_H__ class Test{ private: boo ...

  5. mysql HA-keepalived

    关于MySQL-HA,目前有多种解决方案,比如heartbeat.drbd.mmm.共享存储,但是它们各有优缺点.heartbeat.drbd配置较为复杂,需要自己写脚本才能实现MySQL自动切换,对 ...

  6. 【linux系统学习】计算机硬件核心知识

    (一)企业里PC服务器品牌及型号 互联网公司服务器品牌:DELL,HP,IBM(百度):国内品牌:浪潮,联想,航天联志 DELL服务器品牌:1u = 4.45CM 2010年前 1u 1850,195 ...

  7. LNMPA by lin

    CentOS系统下执行:wget -c http://soft.vpser.net/lnmp/lnmp1.1-full.tar.gz && tar zxf lnmp1.1-full.t ...

  8. 简单实现contentOS下开机自动启动tomcat

    看过网上很多写tomcat开机自启动的例子,很多都是写了一个比较复杂的脚步.找到一个比较简单的. 首先编辑 vi /etc/rc.d/rc.local 在尾部加入 export JDK_HOME=/u ...

  9. table固定宽度高度, 及overflow省略号

    整体设置标签为:td {text-overflow: ellipsis; white-space: nowrap; overflow: hidden; } table fix设置 <table ...

  10. Mysql获取去重后的总数

    如果一张表中某个字段存在重复的值,现在我想去重后获取这个字段值的总数 先看这张表 这张表中的openid有重复值 怎么通过sql语句获取openid的去重总数呢 select count(distin ...