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

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

一,统计词频

 package TopK;
import java.io.IOException;
import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; /**
* 统计词频
* @author zx
* zhangxian1991@qq.com
*/
public class WordCount { /**
* 读取单词
* @author zx
*
*/
public static class Map extends Mapper<Object,Text,Text,IntWritable>{ IntWritable count = new IntWritable(1); @Override
protected void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
StringTokenizer st = new StringTokenizer(value.toString());
while(st.hasMoreTokens()){
String word = st.nextToken().replaceAll("\"", "").replace("'", "").replace(".", "");
context.write(new Text(word), count);
}
} } /**
* 统计词频
* @author zx
*
*/
public static class Reduce extends Reducer<Text,IntWritable,Text,IntWritable>{ @SuppressWarnings("unused")
@Override
protected void reduce(Text key, Iterable<IntWritable> values,Context context)
throws IOException, InterruptedException {
int count = 0;
for (IntWritable intWritable : values) {
count ++;
}
context.write(key,new IntWritable(count));
} } @SuppressWarnings("deprecation")
public static boolean run(String in,String out) throws IOException, ClassNotFoundException, InterruptedException{ Configuration conf = new Configuration(); Job job = new Job(conf,"WordCount");
job.setJarByClass(WordCount.class);
job.setMapperClass(Map.class);
job.setReducerClass(Reduce.class); // 设置Map输出类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class); // 设置Reduce输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class); // 设置输入和输出目录
FileInputFormat.addInputPath(job, new Path(in));
FileOutputFormat.setOutputPath(job, new Path(out)); return job.waitForCompletion(true);
} }

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

 package TopK;

 import java.io.IOException;
import java.util.Comparator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.regex.Pattern; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.MultipleOutputs;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; /**
* 以单词出现的频率排序
*
* @author zx
* zhangxian1991@qq.com
*/
public class Sort { /**
* 读取单词(词频 word)
*
* @author zx
*
*/
public static class Map extends Mapper<Object, Text, IntWritable, Text> { // 输出key 词频
IntWritable outKey = new IntWritable();
Text outValue = new Text(); @Override
protected void map(Object key, Text value, Context context)
throws IOException, InterruptedException { StringTokenizer st = new StringTokenizer(value.toString());
while (st.hasMoreTokens()) {
String element = st.nextToken();
if (Pattern.matches("\\d+", element)) {
outKey.set(Integer.parseInt(element));
} else {
outValue.set(element);
}
} context.write(outKey, outValue);
} } /**
* 根据词频排序
*
* @author zx
*
*/
public static class Reduce extends
Reducer<IntWritable, Text, Text, IntWritable> { private static MultipleOutputs<Text, IntWritable> mos = null; //要获得前K个频率最高的词
private static final int k = 10; //用TreeMap存储可以利用它的排序功能
//这里用 MyInt 因为TreeMap是对key排序,且不能唯一,而词频可能相同,要以词频为Key就必需对它封装
private static TreeMap<MyInt, String> tm = new TreeMap<MyInt, String>(new Comparator<MyInt>(){
/**
* 默认是从小到大的顺序排的,现在修改为从大到小
* @param o1
* @param o2
* @return
*/
@Override
public int compare(MyInt o1, MyInt o2) {
return o2.compareTo(o1);
} }) ; /*
* 以词频为Key是要用到reduce的排序功能
*/
@Override
protected void reduce(IntWritable key, Iterable<Text> values,
Context context) throws IOException, InterruptedException {
for (Text text : values) {
context.write(text, key);
tm.put(new MyInt(key.get()),text.toString()); //TreeMap以对内部数据进行了排序,最后一个必定是最小的
if(tm.size() > k){
tm.remove(tm.lastKey());
} }
} @Override
protected void cleanup(Context context)
throws IOException, InterruptedException {
String path = context.getConfiguration().get("topKout");
mos = new MultipleOutputs<Text, IntWritable>(context);
Set<Entry<MyInt, String>> set = tm.entrySet();
for (Entry<MyInt, String> entry : set) {
mos.write("topKMOS", new Text(entry.getValue()), new IntWritable(entry.getKey().getValue()), path);
}
mos.close();
} } @SuppressWarnings("deprecation")
public static void run(String in, String out,String topKout) throws IOException,
ClassNotFoundException, InterruptedException { Path outPath = new Path(out); Configuration conf = new Configuration(); //前K个词要输出到哪个目录
conf.set("topKout",topKout); Job job = new Job(conf, "Sort");
job.setJarByClass(Sort.class);
job.setMapperClass(Map.class);
job.setReducerClass(Reduce.class); // 设置Map输出类型
job.setMapOutputKeyClass(IntWritable.class);
job.setMapOutputValueClass(Text.class); // 设置Reduce输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class); //设置MultipleOutputs的输出格式
//这里利用MultipleOutputs进行对文件输出
MultipleOutputs.addNamedOutput(job,"topKMOS",TextOutputFormat.class,Text.class,Text.class); // 设置输入和输出目录
FileInputFormat.addInputPath(job, new Path(in));
FileOutputFormat.setOutputPath(job, outPath);
job.waitForCompletion(true); } }

自己封装的Int

 package TopK;

 public class MyInt implements Comparable<MyInt>{
private Integer value; public MyInt(Integer value){
this.value = value;
} public int getValue() {
return value;
} public void setValue(int value) {
this.value = value;
} @Override
public int compareTo(MyInt o) {
return value.compareTo(o.getValue());
} }

运行入口

 package TopK;

 import java.io.IOException;

 /**
*
* @author zx
*zhangxian1991@qq.com
*/
public class TopK {
public static void main(String args[]) throws ClassNotFoundException, IOException, InterruptedException{ //要统计字数,排序的文字
String in = "hdfs://localhost:9000/input/MaDing.text"; //统计字数后的结果
String wordCout = "hdfs://localhost:9000/out/wordCout"; //对统计完后的结果再排序后的内容
String sort = "hdfs://localhost:9000/out/sort"; //前K条
String topK = "hdfs://localhost:9000/out/topK"; //如果统计字数的job完成后就开始排序
if(WordCount.run(in, wordCout)){
Sort.run(wordCout, sort,topK);
} }
}

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. HDU5099——Comparison of Android versions(简单题)(2014上海邀请赛重现)

    Comparison of Android versionsProblem DescriptionAs an Android developer, itˇs really not easy to fi ...

  2. Android 类似时间轴的实现

    想要实现图片中的的时间轴的效果,设定了三种颜色,但是出来的只有一个黑色,还不是设定好的,而且长度很长的话不能滚动,下面上代码: 布局文件: <LinearLayout xmlns:android ...

  3. 【原创】30分钟入门 github

    很久没更新了,这篇文章重点在github的入门使用,读者可以下载github for windows shell,边看边操作,加深印象. 好了,30分钟的愉快之旅开始吧: 一.github使用的注意事 ...

  4. HS-T912 adb 连接配置

    手机丢了,花300大洋买的新手机阿...不讨论好不好用,只说怎么用. 安装驱动 linux 跳过 插上电脑,在__通知__里面打开__USB 连接__,会弹出__USB 设置__对话框. 选择__海信 ...

  5. Java关键字static、final使用小结

    static  1. static变量     按照是否静态的对类成员变量进行分类可分两种:一种是被static修饰的变量,叫静态变量或类变量:另一种是没有被static修饰的变量,叫实例变量.两者的 ...

  6. ha_innobase::general_fetch

    /***********************************************************************//** Reads the next or previ ...

  7. bzoj1296: [SCOI2009]粉刷匠

    dp. 用到俩次dp,用1和0代表俩种颜色,首先对于每块木板我们进行一次dp,g[i][j]代表前j个格子刷i次最多能涂到几个格子. 则 g[i][j]=max(g[i-1][k],max(cnt[j ...

  8. C#.NET U盘插拔监控

    [1]涉及的知识点 1) windows消息处理函数 ? 1 protected override void WndProc(ref Message m) 捕获Message的系统硬件改变发出的系统消 ...

  9. UVa 11526 H(n)

    题意: long long H(int n){ long long res = 0; for( int i = 1; i <= n; i=i+1 ){ res = (res + n/i); } ...

  10. css动画集合地址

    CSS3 UI Lib库是由腾讯AlloyTeam前端开发团队建立,主要收集国内外友好体验和创意的界面组件Demo. 它除了使用CSS3技术外,还使用了HTML5,JS,JX,jQuery等技术,来达 ...