MapReduce TopK统计加排序
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统计加排序的更多相关文章
- mapreduce数据处理——统计排序
接上篇https://www.cnblogs.com/sengzhao666/p/11850849.html 2.数据处理: ·统计最受欢迎的视频/文章的Top10访问次数 (id) ·按照地市统计最 ...
- MapReduce 单词统计案例编程
MapReduce 单词统计案例编程 一.在Linux环境安装Eclipse软件 1. 解压tar包 下载安装包eclipse-jee-kepler-SR1-linux-gtk-x86_64.ta ...
- 分页查询最好加排序(order by)
昨天,与外部化系统对接时,发现有一个数据一直咩有集成到,双方各自排查了自己系统的代码,都觉得逻辑非常简单,无法就是一个分页查询而已. 问题就出在这个分页查询上. 为了说明当时问题发生的情景,我模拟了一 ...
- DataTable列查询加排序
DataTable列查询加排序 DataRow[] drArray = dt.Select("ANLYCOM_ID='" + chSPrdtStblAnly.AnlyComId + ...
- 【Cloud Computing】Hadoop环境安装、基本命令及MapReduce字数统计程序
[Cloud Computing]Hadoop环境安装.基本命令及MapReduce字数统计程序 1.虚拟机准备 1.1 模板机器配置 1.1.1 主机配置 IP地址:在学校校园网Wifi下连接下 V ...
- mysql 分组统计、排序、取前N条记录解决方案
需要在mysql中解决记录的分组统计.排序,并抽取前10条记录的功能.现已解决,解决方案如下: 1)表结构 CREATE TABLE `policy_keywords_rel` ( `id` int( ...
- Mapreduce的排序(全局排序、分区加排序、Combiner优化)
一.MR排序的分类 1.部分排序:MR会根据自己输出记录的KV对数据进行排序,保证输出到每一个文件内存都是经过排序的: 2.全局排序: 3.辅助排序:再第一次排序后经过分区再排序一次: 4.二次排序: ...
- PHP几个几十个G大文件数据统计并且排序处理
诸多大互联网公司的面试都会有这么个问题,有个4G的文件,如何用只有1G内存的机器去计算文件中出现次数最多的数字(假设1行是1个数组,例如QQ号 码).如果这个文件只有4B或者几十兆,那么最简单的办法就 ...
- MapReduce应用案例--简单排序
1. 设计思路 在MapReduce过程中自带有排序,可以使用这个默认的排序达到我们的目的. MapReduce 是按照key值进行排序的,我们在Map过程中将读入的数据转化成IntWritable类 ...
随机推荐
- No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK? 问题
maven编译项目时出错,提示信息如下: [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3 ...
- Java 进行 RSA 加解密时不得不考虑到的那些事儿
1. 加密的系统不要具备解密的功能,否则 RSA 可能不太合适 公钥加密,私钥解密.加密的系统和解密的系统分开部署,加密的系统不应该同时具备解密的功能,这样即使黑客攻破了加密系统,他拿到的也只是一堆无 ...
- 机器学习 —— 概率图模型(Homework: Exact Inference)
在前三周的作业中,我构造了概率图模型并调用第三方的求解器对器进行了求解,最终获得了每个随机变量的分布(有向图),最大后验分布(双向图).本周作业的主要内容就是自行编写概率图模型的求解器.实际上,从根本 ...
- sdut 2847 Monitor (思维题)
题目 题意:给定a, b, x, y; 求使c, d; 使c:d = x :y; 且c<=a, d<=b, 而且c, d尽量大. 先求最小倍数, 再用最小倍数乘 x, y; #inclu ...
- sql server删除数据后空间无变化处理方法
删除数据库表 第一步: 执行 delete from doc.115sou.com #删除数据,执行效率低 drop table doc.115sou.com #删除表 ...
- 配置IIS服务器,APK文件下载
解决方法:在IIS的MIME类型中添加扩展名.apk,MIME类型application/vnd.android即可
- js 时间转成时间戳对比;My97DatePicker日历控件时间格式;Date.parse Firefox火狐浏览器返回Nan的解决办法
有个情况,我在显示时间的时候是需要显示为 2013年8月15日 14时28分15秒 但是假如我用js去获取到这个时间,并且想进行时间对比的时候,这个时间2013年8月15日 14时28分15秒根本就 ...
- error while loading shared libraries: libevent-2.0.so.5解决办法
安装memcache时,需要建立文件索引或者说文件连接(link),类似windows下的快捷方式 启动服务时出现 error while loading shared libraries: libe ...
- ti processor sdk linux am335x evm /bin/setup-host-check.sh hacking
#!/bin/sh # # ti processor sdk linux am335x evm /bin/setup-host-check.sh hacking # 说明: # 本文主要对TI的sdk ...
- IPicture、BITMAP、HBITMAP和CBitmap的关系
1.有关IPicture加载图片后直接Render到内存DC的问题(HBITMAP转换IPicture)Picture的方法get_Handle可以直接得到图片的句柄 IPicture *pIPict ...