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类 ...
随机推荐
- iOS 精确定时器
Do I need a high precision timer? Don't use a high precision timer unless you really need it. They c ...
- MSSQL2005数据库自动备份问题(到同一个局域网上的另一台电脑上)
有A数据库服务器,B本机: 我现在想通过在B机器上通过代码调用SQL来执行A数据库的备份到B机器上 调用的SQL语句为:Backup Database MYDATABASE To Disk ...
- 素数筛法--SPOJ Problem 2 Prime Generator
质数(prime number)又称素数,除了1和它本身外,不能整除以其他自然数,换句话说就是该数除了1和它本身以外不再有其他的因数:否则称为合数.最小的质数是2. 要判断一个整数N是不是质数很简单, ...
- newClass a = Func(3)中隐藏的操作
缘起 #include <iostream> #include <bitset> using namespace std; class A { public: A() { co ...
- JNIEnv解析
1.关于JNIEnv和JavaVM JNIEnv:线程相关的变量 JavaVM:是虚拟机在JNI层的代表, JNIEnv是一个与线程相关的变量,不同线程的JNIEnv彼此独立.JavaVM是虚拟机在J ...
- 1641. Duties
1641 枚举 #include <iostream> #include<cstdio> #include<cstring> #include<algorit ...
- UVa 11105 (筛法) Semi-prime H-numbers
题意: 你现在来到了一个所有的数都模4余1的世界,也就是除了这种数没有其他的数了. 然而素数的定义依然没变,如果一个数不能写成两个非1数字的乘积,则它是素数. 比如,在这里5就变成了最小的素数. 两个 ...
- BZOJ_1029_[JSOI2007]_建筑抢修_(贪心+优先队列)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1029 \(n\)个任务需要完成,给出每个任务所需时间\(t_1\)与deadline\(t_2 ...
- 编译pure-ftpd时提示错误Your MySQL client libraries aren't properly installed
如果出现类似configure: error: Your MySQL client libraries aren’t properly installed 的错误,请将mysql目录下的 includ ...
- iOS应用的crash日志的分析基础
Outline如何获得crash日志如何解析crash日志如何分析crash日志 1. iOS策略相关 2. 常见错误标识 3. 代码bug 一.如何获得crash日志 ...