MapReduce词频统计
自定义Mapper实现
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
/**
* KEYIN: Map任务读取数据的key类型,offset,是每行数据起始位置的偏移量,一般为Long类型
* VALUEIN: Map任务读取数据的value类型,其实就是一行行的字符串,String
*
* KEYOUT: map方法自定义实现输出的key类型,String
* VALUEOUT: map方法自定义实现输出的value类型,Integer
*
* 假设有如下待处理文本:
* hello world world
* hello welcome
*
* 词频统计:相同单词的次数 (word,1)
*
* Long,String,String,Integer是Java里面的数据类型
* Hadoop自定义类型:支持序列化和反序列化
*
* LongWritable,Text,Text,IntWritable
*
*/
public class WordCountMapper extends Mapper<LongWritable, Text,Text, IntWritable> {
// 重写map方法
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
// key是偏移量,value是一行行数据
/**
* Map任务的要求:
* (1)切割
* (2)赋1,转成key-value类型,写入context
* (3)其他的交给Shuffle和Reducer处理
*/
String[] words = value.toString().split(" ");// 按指定分隔符切割
for (String word : words) {
context.write(new Text(word),new IntWritable(1)); // java类型转hadoop类型
// (hello,1) (world,1) (world,1)
// (hello,1) (welcome,1)
}
}
}
自定义Reducer实现
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
import java.util.Iterator;
public class WordCountReducer extends Reducer<Text, IntWritable,Text, IntWritable> {
// 重写reduce方法
/** map的输出
* (hello,1) (world,1) (world,1)
* (hello,1) (welcome,1)
*
* map的输出到reduce端,是按照相同的key分发到一个reduce上执行
* reduce1: (hello,1) (hello,1) ==> (hello,<1,1>)
* reduce2: (world,1) (world,1) ==> (world,<1,1>)
* reduce3: (welcome,1) ==> (welcome,<1>)
*/
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
/**
* Reducer任务的要求:(因为每个reduce任务处理的是相同的一个单词的集合)
* (1) 迭代value数组,累加求次数
* (2) 取出key单词,拼成(key,次数),写入context
*/
int count = 0;
Iterator<IntWritable> its = values.iterator();
while (its.hasNext()){
IntWritable next = its.next();
count += next.get(); //取值
}
// 写入context
context.write(key,new IntWritable(count));
}
}
编写Driver类
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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* 使用MR统计HDFS上文件的词频
*/
public class WordCountDriver {
public static void main(String[] args) throws Exception{
Configuration conf = new Configuration();
conf.set("fs.defaultFS","hdfs://localhost:9000");
System.setProperty("HADOOP_USER_NAME","hadoop");
// 创建一个Job
Job job = Job.getInstance(conf);
// 设置Job对应的参数
job.setJarByClass(WordCountDriver.class); //主类
job.setMapperClass(WordCountMapper.class); //使用的Mapper
job.setReducerClass(WordCountReducer.class); //使用的Reducer
// 设置Mapper,Reducer的输出类型
job.setMapOutputKeyClass(Text.class); //Mapper输出的key类型
job.setMapOutputValueClass(IntWritable.class); //Mapper输出的value类型
job.setOutputKeyClass(Text.class); //Reducer输出的key类型
job.setOutputValueClass(IntWritable.class); //Reducer输出的value类型
// 设置作业的输入输出路径
FileInputFormat.setInputPaths(job,new Path("input"));
FileOutputFormat.setOutputPath(job,new Path("output"));
// 提交Job
boolean result = job.waitForCompletion(true);
System.exit(result ? 0 : -1);
}
}
本地测试开发
上面使用的都是基于
HDFS的,那么如何使用本地呢?
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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
/**
* 使用MR统计本地文件的词频:
* 使用本地文件进行词频统计,然后把统计结果输出到本地
* 步骤:
* (1)不需要hdfs路径
* (2)不需要远程访问权限hadoop
* (3)在项目本地创建好input目录访问即可(input和src是同级目录!)
*/
public class WordCountLocalDriver {
public static void main(String[] args) throws Exception{
Configuration conf = new Configuration();
// 创建一个Job
Job job = Job.getInstance(conf);
// 设置Job对应的参数
job.setJarByClass(WordCountLocalDriver.class); //主类
job.setMapperClass(WordCountMapper.class); //使用的Mapper
job.setReducerClass(WordCountReducer.class); //使用的Reducer
// 设置Mapper,Reducer的输出类型
job.setMapOutputKeyClass(Text.class); //Mapper输出的key类型
job.setMapOutputValueClass(IntWritable.class); //Mapper输出的value类型
job.setOutputKeyClass(Text.class); //Reducer输出的key类型
job.setOutputValueClass(IntWritable.class); //Reducer输出的value类型
// 设置作业的输入输出路径
FileInputFormat.setInputPaths(job,new Path("input"));
FileOutputFormat.setOutputPath(job,new Path("output"));
// 提交Job
boolean result = job.waitForCompletion(true);
System.exit(result ? 0 : -1);
}
}
强烈建议
使用
本地模式进行测试和开发,非常高效,Debug也很方便。
代码升级
- 使用代码,删除
HDFS的output目录
// 删除output目录
FileSystem fs = FileSystem.get(new URI("hdfs://localhost:9000"), conf, "hadoop");
Path outputPath = new Path("output");
if (fs.exists(outputPath)){
fs.delete(outputPath,true);
}
- map端聚合
Combiner
处理逻辑和Reducer完全一模一样,
直接套用即可!
// 设置Combiner
job.setCombinerClass(WordCountReducer.class);
使用Combiner优缺点
优点
能减少IO,提升作业的执行性能。
缺点
除法操作慎用!
MapReduce词频统计的更多相关文章
- MapReduce实现词频统计
问题描述:现在有n个文本文件,使用MapReduce的方法实现词频统计. 附上统计词频的关键代码,首先是一个通用的MapReduce模块: class MapReduce: __doc__ = ''' ...
- Hadoop上的中文分词与词频统计实践 (有待学习 http://www.cnblogs.com/jiejue/archive/2012/12/16/2820788.html)
解决问题的方案 Hadoop上的中文分词与词频统计实践 首先来推荐相关材料:http://xiaoxia.org/2011/12/18/map-reduce-program-of-rmm-word-c ...
- 【原创】大数据基础之词频统计Word Count
对文件进行词频统计,是一个大数据领域的hello word级别的应用,来看下实现有多简单: 1 Linux单机处理 egrep -o "\b[[:alpha:]]+\b" test ...
- Hive简单编程实践-词频统计
一.使用MapReduce的方式进行词频统计 (1)在HDFS用户目录下创建input文件夹 hdfs dfs -mkdir input 注意:林子雨老师的博客(http://dblab.xmu.ed ...
- hive进行词频统计
统计文件信息: $ /opt/cdh-5.3.6/hadoop-2.5.0/bin/hdfs dfs -text /user/hadoop/wordcount/input/wc.input hadoo ...
- Hadoop的改进实验(中文分词词频统计及英文词频统计)(4/4)
声明: 1)本文由我bitpeach原创撰写,转载时请注明出处,侵权必究. 2)本小实验工作环境为Windows系统下的百度云(联网),和Ubuntu系统的hadoop1-2-1(自己提前配好).如不 ...
- 初学Hadoop之中文词频统计
1.安装eclipse 准备 eclipse-dsl-luna-SR2-linux-gtk-x86_64.tar.gz 安装 1.解压文件. 2.创建图标. ln -s /opt/eclipse/ec ...
- 初学Hadoop之WordCount词频统计
1.WordCount源码 将源码文件WordCount.java放到Hadoop2.6.0文件夹中. import java.io.IOException; import java.util.Str ...
- Hadoop之词频统计小实验
声明: 1)本文由我原创撰写,转载时请注明出处,侵权必究. 2)本小实验工作环境为Ubuntu操作系统,hadoop1-2-1,jdk1.8.0. 3)统计词频工作在单节点的伪分布上,至于真正实 ...
随机推荐
- 快速沃尔什变换(FWT)及K进制异或卷积&快速子集变换(FST)讲解
前言: $FWT$是用来处理位运算(异或.与.或)卷积的一种变换.位运算卷积是什么?形如$f[i]=\sum\limits_{j\oplus k==i}^{ }g[j]*h[k]$的卷积形式(其中$\ ...
- 用 hugo 和 netlify 搭建blog【转】
用 hugo 和 netlify 搭建blog - kok的笔记本 Releases · gohugoio/hugo · GitHub 测试baidu 测试163
- 【BZOJ3996】[TJOI2015]线性代数(最小割)
[BZOJ3996][TJOI2015]线性代数(最小割) 题面 BZOJ 洛谷 题解 首先把式子拆开,发现我们的答案式就是这个: \[\sum_{i=1}^n\sum_{j=1}^n B_{i,j} ...
- KEIL之工程单独文件属性修改
@2019-04-29 [小记] 可以设置文件是否参与编译.内存分配.宏定义等属性设置
- YUI Compressor
简介 根据雅虎卓越性能团队的说法,40%到60%的雅虎用户拥有空闲缓存体验,所有页面浏览量中约有20%是使用空缓存完成的(请参阅Tenni Theurer在YUIBlog上的这篇文章)有关浏览器缓存使 ...
- [BJOI2019]奥术神杖(分数规划+AC自动机+DP)
题解:很显然可以对权值取对数,然后把几何平均值转为算术平均值,然后很显然是分数规划.先对每个模式串建立AC自动机,每个节点w[i],sz[i]分别表示以其为前缀的字符串,然后再二分最优解k,然后w[i ...
- 构建之法助教园地第一次作业--点评<西北师范大学|李晓婷>
一 博客点评 第一次作业--准备篇:https://www.cnblogs.com/Mookiepiece/p/10464606.html#4192515 点评内容: 首先,你对电脑很感兴趣,兴趣就是 ...
- Lending Club—构建贷款违约预测模型
python信用评分卡(附代码,博主录制) https://study.163.com/course/introduction.htm?courseId=1005214003&utm_camp ...
- Java虚拟机—垃圾回收算法(整理版)
1.概述 由于垃圾收集算法的实现涉及大量的程序细节.因此本节不打算过多地讨论算法的实现,只是介绍几种算法的思想及其发展过程.主要涉及的算法有标记-清除算法.复制算法.标记-整理算法.分代收集算法. 2 ...
- 防止html页面缓存
1.增加如下头 <meta http-equiv="Expires" content="0"> <meta http-equiv=" ...