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

这个案例分两个步骤,第一个是就是wordCount案例,二就是排序功能。

一,统计词频

  1. package TopK;
  2. import java.io.IOException;
  3. import java.util.StringTokenizer;
  4.  
  5. import org.apache.hadoop.conf.Configuration;
  6. import org.apache.hadoop.fs.Path;
  7. import org.apache.hadoop.io.IntWritable;
  8. import org.apache.hadoop.io.Text;
  9. import org.apache.hadoop.mapreduce.Job;
  10. import org.apache.hadoop.mapreduce.Mapper;
  11. import org.apache.hadoop.mapreduce.Reducer;
  12. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  13. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  14.  
  15. /**
  16. * 统计词频
  17. * @author zx
  18. * zhangxian1991@qq.com
  19. */
  20. public class WordCount {
  21.  
  22. /**
  23. * 读取单词
  24. * @author zx
  25. *
  26. */
  27. public static class Map extends Mapper<Object,Text,Text,IntWritable>{
  28.  
  29. IntWritable count = new IntWritable(1);
  30.  
  31. @Override
  32. protected void map(Object key, Text value, Context context)
  33. throws IOException, InterruptedException {
  34. StringTokenizer st = new StringTokenizer(value.toString());
  35. while(st.hasMoreTokens()){
  36. String word = st.nextToken().replaceAll("\"", "").replace("'", "").replace(".", "");
  37. context.write(new Text(word), count);
  38. }
  39. }
  40.  
  41. }
  42.  
  43. /**
  44. * 统计词频
  45. * @author zx
  46. *
  47. */
  48. public static class Reduce extends Reducer<Text,IntWritable,Text,IntWritable>{
  49.  
  50. @SuppressWarnings("unused")
  51. @Override
  52. protected void reduce(Text key, Iterable<IntWritable> values,Context context)
  53. throws IOException, InterruptedException {
  54. int count = 0;
  55. for (IntWritable intWritable : values) {
  56. count ++;
  57. }
  58. context.write(key,new IntWritable(count));
  59. }
  60.  
  61. }
  62.  
  63. @SuppressWarnings("deprecation")
  64. public static boolean run(String in,String out) throws IOException, ClassNotFoundException, InterruptedException{
  65.  
  66. Configuration conf = new Configuration();
  67.  
  68. Job job = new Job(conf,"WordCount");
  69. job.setJarByClass(WordCount.class);
  70. job.setMapperClass(Map.class);
  71. job.setReducerClass(Reduce.class);
  72.  
  73. // 设置Map输出类型
  74. job.setMapOutputKeyClass(Text.class);
  75. job.setMapOutputValueClass(IntWritable.class);
  76.  
  77. // 设置Reduce输出类型
  78. job.setOutputKeyClass(Text.class);
  79. job.setOutputValueClass(IntWritable.class);
  80.  
  81. // 设置输入和输出目录
  82. FileInputFormat.addInputPath(job, new Path(in));
  83. FileOutputFormat.setOutputPath(job, new Path(out));
  84.  
  85. return job.waitForCompletion(true);
  86. }
  87.  
  88. }

二,排序 并求出频率最高的前K个词

  1. package TopK;
  2.  
  3. import java.io.IOException;
  4. import java.util.Comparator;
  5. import java.util.Map.Entry;
  6. import java.util.Set;
  7. import java.util.StringTokenizer;
  8. import java.util.TreeMap;
  9. import java.util.regex.Pattern;
  10.  
  11. import org.apache.hadoop.conf.Configuration;
  12. import org.apache.hadoop.fs.Path;
  13. import org.apache.hadoop.io.IntWritable;
  14. import org.apache.hadoop.io.Text;
  15. import org.apache.hadoop.mapreduce.Job;
  16. import org.apache.hadoop.mapreduce.Mapper;
  17. import org.apache.hadoop.mapreduce.Reducer;
  18. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  19. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  20. import org.apache.hadoop.mapreduce.lib.output.MultipleOutputs;
  21. import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
  22.  
  23. /**
  24. * 以单词出现的频率排序
  25. *
  26. * @author zx
  27. * zhangxian1991@qq.com
  28. */
  29. public class Sort {
  30.  
  31. /**
  32. * 读取单词(词频 word)
  33. *
  34. * @author zx
  35. *
  36. */
  37. public static class Map extends Mapper<Object, Text, IntWritable, Text> {
  38.  
  39. // 输出key 词频
  40. IntWritable outKey = new IntWritable();
  41. Text outValue = new Text();
  42.  
  43. @Override
  44. protected void map(Object key, Text value, Context context)
  45. throws IOException, InterruptedException {
  46.  
  47. StringTokenizer st = new StringTokenizer(value.toString());
  48. while (st.hasMoreTokens()) {
  49. String element = st.nextToken();
  50. if (Pattern.matches("\\d+", element)) {
  51. outKey.set(Integer.parseInt(element));
  52. } else {
  53. outValue.set(element);
  54. }
  55. }
  56.  
  57. context.write(outKey, outValue);
  58. }
  59.  
  60. }
  61.  
  62. /**
  63. * 根据词频排序
  64. *
  65. * @author zx
  66. *
  67. */
  68. public static class Reduce extends
  69. Reducer<IntWritable, Text, Text, IntWritable> {
  70.  
  71. private static MultipleOutputs<Text, IntWritable> mos = null;
  72.  
  73. //要获得前K个频率最高的词
  74. private static final int k = 10;
  75.  
  76. //用TreeMap存储可以利用它的排序功能
  77. //这里用 MyInt 因为TreeMap是对key排序,且不能唯一,而词频可能相同,要以词频为Key就必需对它封装
  78. private static TreeMap<MyInt, String> tm = new TreeMap<MyInt, String>(new Comparator<MyInt>(){
  79. /**
  80. * 默认是从小到大的顺序排的,现在修改为从大到小
  81. * @param o1
  82. * @param o2
  83. * @return
  84. */
  85. @Override
  86. public int compare(MyInt o1, MyInt o2) {
  87. return o2.compareTo(o1);
  88. }
  89.  
  90. }) ;
  91.  
  92. /*
  93. * 以词频为Key是要用到reduce的排序功能
  94. */
  95. @Override
  96. protected void reduce(IntWritable key, Iterable<Text> values,
  97. Context context) throws IOException, InterruptedException {
  98. for (Text text : values) {
  99. context.write(text, key);
  100. tm.put(new MyInt(key.get()),text.toString());
  101.  
  102. //TreeMap以对内部数据进行了排序,最后一个必定是最小的
  103. if(tm.size() > k){
  104. tm.remove(tm.lastKey());
  105. }
  106.  
  107. }
  108. }
  109.  
  110. @Override
  111. protected void cleanup(Context context)
  112. throws IOException, InterruptedException {
  113. String path = context.getConfiguration().get("topKout");
  114. mos = new MultipleOutputs<Text, IntWritable>(context);
  115. Set<Entry<MyInt, String>> set = tm.entrySet();
  116. for (Entry<MyInt, String> entry : set) {
  117. mos.write("topKMOS", new Text(entry.getValue()), new IntWritable(entry.getKey().getValue()), path);
  118. }
  119. mos.close();
  120. }
  121.  
  122. }
  123.  
  124. @SuppressWarnings("deprecation")
  125. public static void run(String in, String out,String topKout) throws IOException,
  126. ClassNotFoundException, InterruptedException {
  127.  
  128. Path outPath = new Path(out);
  129.  
  130. Configuration conf = new Configuration();
  131.  
  132. //前K个词要输出到哪个目录
  133. conf.set("topKout",topKout);
  134.  
  135. Job job = new Job(conf, "Sort");
  136. job.setJarByClass(Sort.class);
  137. job.setMapperClass(Map.class);
  138. job.setReducerClass(Reduce.class);
  139.  
  140. // 设置Map输出类型
  141. job.setMapOutputKeyClass(IntWritable.class);
  142. job.setMapOutputValueClass(Text.class);
  143.  
  144. // 设置Reduce输出类型
  145. job.setOutputKeyClass(Text.class);
  146. job.setOutputValueClass(IntWritable.class);
  147.  
  148. //设置MultipleOutputs的输出格式
  149. //这里利用MultipleOutputs进行对文件输出
  150. MultipleOutputs.addNamedOutput(job,"topKMOS",TextOutputFormat.class,Text.class,Text.class);
  151.  
  152. // 设置输入和输出目录
  153. FileInputFormat.addInputPath(job, new Path(in));
  154. FileOutputFormat.setOutputPath(job, outPath);
  155. job.waitForCompletion(true);
  156.  
  157. }
  158.  
  159. }

自己封装的Int

  1. package TopK;
  2.  
  3. public class MyInt implements Comparable<MyInt>{
  4. private Integer value;
  5.  
  6. public MyInt(Integer value){
  7. this.value = value;
  8. }
  9.  
  10. public int getValue() {
  11. return value;
  12. }
  13.  
  14. public void setValue(int value) {
  15. this.value = value;
  16. }
  17.  
  18. @Override
  19. public int compareTo(MyInt o) {
  20. return value.compareTo(o.getValue());
  21. }
  22.  
  23. }

运行入口

  1. package TopK;
  2.  
  3. import java.io.IOException;
  4.  
  5. /**
  6. *
  7. * @author zx
  8. *zhangxian1991@qq.com
  9. */
  10. public class TopK {
  11. public static void main(String args[]) throws ClassNotFoundException, IOException, InterruptedException{
  12.  
  13. //要统计字数,排序的文字
  14. String in = "hdfs://localhost:9000/input/MaDing.text";
  15.  
  16. //统计字数后的结果
  17. String wordCout = "hdfs://localhost:9000/out/wordCout";
  18.  
  19. //对统计完后的结果再排序后的内容
  20. String sort = "hdfs://localhost:9000/out/sort";
  21.  
  22. //前K条
  23. String topK = "hdfs://localhost:9000/out/topK";
  24.  
  25. //如果统计字数的job完成后就开始排序
  26. if(WordCount.run(in, wordCout)){
  27. Sort.run(wordCout, sort,topK);
  28. }
  29.  
  30. }
  31. }

MapReduce TopK统计加排序的更多相关文章

  1. mapreduce数据处理——统计排序

    接上篇https://www.cnblogs.com/sengzhao666/p/11850849.html 2.数据处理: ·统计最受欢迎的视频/文章的Top10访问次数 (id) ·按照地市统计最 ...

  2. MapReduce 单词统计案例编程

    MapReduce 单词统计案例编程 一.在Linux环境安装Eclipse软件 1.   解压tar包 下载安装包eclipse-jee-kepler-SR1-linux-gtk-x86_64.ta ...

  3. 分页查询最好加排序(order by)

    昨天,与外部化系统对接时,发现有一个数据一直咩有集成到,双方各自排查了自己系统的代码,都觉得逻辑非常简单,无法就是一个分页查询而已. 问题就出在这个分页查询上. 为了说明当时问题发生的情景,我模拟了一 ...

  4. DataTable列查询加排序

    DataTable列查询加排序 DataRow[] drArray = dt.Select("ANLYCOM_ID='" + chSPrdtStblAnly.AnlyComId + ...

  5. 【Cloud Computing】Hadoop环境安装、基本命令及MapReduce字数统计程序

    [Cloud Computing]Hadoop环境安装.基本命令及MapReduce字数统计程序 1.虚拟机准备 1.1 模板机器配置 1.1.1 主机配置 IP地址:在学校校园网Wifi下连接下 V ...

  6. mysql 分组统计、排序、取前N条记录解决方案

    需要在mysql中解决记录的分组统计.排序,并抽取前10条记录的功能.现已解决,解决方案如下: 1)表结构 CREATE TABLE `policy_keywords_rel` ( `id` int( ...

  7. Mapreduce的排序(全局排序、分区加排序、Combiner优化)

    一.MR排序的分类 1.部分排序:MR会根据自己输出记录的KV对数据进行排序,保证输出到每一个文件内存都是经过排序的: 2.全局排序: 3.辅助排序:再第一次排序后经过分区再排序一次: 4.二次排序: ...

  8. PHP几个几十个G大文件数据统计并且排序处理

    诸多大互联网公司的面试都会有这么个问题,有个4G的文件,如何用只有1G内存的机器去计算文件中出现次数最多的数字(假设1行是1个数组,例如QQ号 码).如果这个文件只有4B或者几十兆,那么最简单的办法就 ...

  9. MapReduce应用案例--简单排序

    1. 设计思路 在MapReduce过程中自带有排序,可以使用这个默认的排序达到我们的目的. MapReduce 是按照key值进行排序的,我们在Map过程中将读入的数据转化成IntWritable类 ...

随机推荐

  1. iOS 精确定时器

    Do I need a high precision timer? Don't use a high precision timer unless you really need it. They c ...

  2. MSSQL2005数据库自动备份问题(到同一个局域网上的另一台电脑上)

    有A数据库服务器,B本机:    我现在想通过在B机器上通过代码调用SQL来执行A数据库的备份到B机器上    调用的SQL语句为:Backup Database MYDATABASE To Disk ...

  3. 素数筛法--SPOJ Problem 2 Prime Generator

    质数(prime number)又称素数,除了1和它本身外,不能整除以其他自然数,换句话说就是该数除了1和它本身以外不再有其他的因数:否则称为合数.最小的质数是2. 要判断一个整数N是不是质数很简单, ...

  4. newClass a = Func(3)中隐藏的操作

    缘起 #include <iostream> #include <bitset> using namespace std; class A { public: A() { co ...

  5. JNIEnv解析

    1.关于JNIEnv和JavaVM JNIEnv:线程相关的变量 JavaVM:是虚拟机在JNI层的代表, JNIEnv是一个与线程相关的变量,不同线程的JNIEnv彼此独立.JavaVM是虚拟机在J ...

  6. 1641. Duties

    1641 枚举 #include <iostream> #include<cstdio> #include<cstring> #include<algorit ...

  7. UVa 11105 (筛法) Semi-prime H-numbers

    题意: 你现在来到了一个所有的数都模4余1的世界,也就是除了这种数没有其他的数了. 然而素数的定义依然没变,如果一个数不能写成两个非1数字的乘积,则它是素数. 比如,在这里5就变成了最小的素数. 两个 ...

  8. BZOJ_1029_[JSOI2007]_建筑抢修_(贪心+优先队列)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1029 \(n\)个任务需要完成,给出每个任务所需时间\(t_1\)与deadline\(t_2 ...

  9. 编译pure-ftpd时提示错误Your MySQL client libraries aren't properly installed

    如果出现类似configure: error: Your MySQL client libraries aren’t properly installed 的错误,请将mysql目录下的 includ ...

  10. iOS应用的crash日志的分析基础

        Outline如何获得crash日志如何解析crash日志如何分析crash日志     1. iOS策略相关     2. 常见错误标识     3. 代码bug 一.如何获得crash日志 ...