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. Intellij IDEA采用Maven+Spring MVC+Hibernate的架构搭建一个java web项目

    原文:Java web 项目搭建 Java web 项目搭建 简介 在上一节java web环境搭建中,我们配置了开发java web项目最基本的环境,现在我们将采用Spring MVC+Spring ...

  2. pancake sort的几个问题

    1. 每次找剩下序列中的最大值,可以进行pancake sort,时间复杂度是O(n^2): 2. 求最少交换次数进行pancake sort的问题是个NP问题,搜索的时候,upper bound是2 ...

  3. java对象实例化

    JAVA类,只要知道了类名(全名)就可以创建其实例对象,通用的方法是直接使用该类提供的构造方法,如 NewObject o = new NewObject(); NewObject o = new N ...

  4. makefile生成静态库和动态库

    库是一种软件组件技术,库里面封装了数据和函数. 库的使用可以使程序模块化. Windows系统包括静态链接库(.lib文件)和动态链接库(.dll文件). Linux通常把库文件存放在/usr/lib ...

  5. NDK(21)JNI的5大正确性缺陷及优化技巧(注意是正确性缺陷)

    转自 : http://www.ibm.com/developerworks/cn/java/j-jni/index.html JNI 编程缺陷可以分为两类: 性能:代码能执行所设计的功能,但运行缓慢 ...

  6. Awesome-awesome-awesome

    Awesome-awesome-awesome A curated list of curated lists of awesome lists. awesome-awesomes @sindreso ...

  7. basicjava

    .完数 . 第一个完全数是6,它有约数1.2.3.6,除去它本身6外,其余3个数相加,1+2+3=6.第二个完全数是28,它有约数1.2.4.7.14. 28,除去它本身28外,其余5个数相加,1+2 ...

  8. CentOS6.6安装mysql出现的问题

    mysql编译需要cmake,我的cmake-2.6.4-5.el6.i686,最新版的是3.1.0,我就先用2.6.4的试试 ​ [root@localhost src]# wget http:// ...

  9. cocos2d-x 2.1.2 bug发现

    1.在做屏蔽触摸时发现 extensions中的CCScrollView类 void CCScrollView::registerWithTouchDispatcher() { CCDirector: ...

  10. Android 生成含签名文件的apk安装包

    做android开发时,必然需要打包生成apk文件,这样才能部署.作为一个完善的apk,必然少不了签名文件,否则下次系统无法进行更新. 一.签名文件的制作及打包生成APK文件 签名文件比较流行的制作方 ...