hadoop使用mapreduce统计词频_Hadoop基础-08-MapReduce词频统计

Hadoop MapReduce实践:词频统计详解
本文详细介绍了如何使用Hadoop的MapReduce框架进行词频统计,包括自定义Mapper、Reducer类的实现,数据类型的选择,以及Combiner优化。通过示例展示了从读取输入文件到输出结果的完整过程。

定义Mapper实现

WordCountMapper extends Mapper

public class Mapper {

......

}

KEYIN : mapping 输入 key 的类型,即每行的偏移量offset(每行第一个字符在整个文本中的位置),Long 类型,对应 Hadoop 中的 LongWritable 类型;

VALUEIN : mapping 输入 value 的类型, 即其实就是一行行的字符串,即每行数据;String 类型,对应 Hadoop 中 Text 类型;

KEYOUT :mapping 输出的 key 的类型,即每个单词;String 类型,对应 Hadoop 中 Text 类型;

VALUEOUT:mapping 输出 value 的类型,即每个单词出现的次数;这里用 int 类型,对应 IntWritable 类型。

WordCountMapper

package com.bigdata.hadoop.mr.wc;

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;

public class WordCountMapper extends Mapper {

@Override

protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {

//把value按照指定的分割符分开

String[] words=value.toString().split("\t");

for(String word: words){

context.write(new Text(word),new IntWritable(1));

}

}

}

自定义Reducer实现

public class WordCountReducer extends Reducer {

@Override

protected void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException {

}

}

Text数据类型 :字符串类型 String

IntWritable : reduce阶段的输入类型 int

Text : reduce阶段的输出数据类型 String类型

IntWritable : 输出词频个数 Int型

WordCountReducer

package com.bigdata.hadoop.mr.wc;

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 {

@Override

protected void reduce(Text key, Iterable values, Context context) throws IOException, InterruptedException {

int count=0;

Iterator iterator = values.iterator();

while(iterator.hasNext()){

IntWritable value = iterator.next();

count += value.get();

}

context.write(key,new IntWritable(count));

}

}

自定义Driver类实现

package com.bigdata.hadoop.mr.wc;

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上的文件对应的词频

//Driver: 配置Mapper,Reducer的相关属性

public class WordCountApp {

public static void main(String[] args) throws Exception{

System.setProperty("HADOOP_USER_NAME","hadoop");

Configuration configuration= new Configuration();

configuration.set("fs.defaultFS","hdfs://192.168.1.200:8020");

//创建一个job

Job job = Job.getInstance(configuration);

// 设置Job对应的参数:设置 Mapper 和 Reducer

job.setMapperClass(WordCountMapper.class);

job.setReducerClass(WordCountReducer.class);

//设置Job对应的参数:Mapper输出Key和value的类型

job.setMapOutputKeyClass(Text.class);

job.setMapOutputValueClass(IntWritable.class);

//设置job对应的参数:Reducer输出的key和value

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(IntWritable.class);

//设置job对应的参数:作业输出的的路径

FileInputFormat.setInputPaths(job,new Path("/map/input"));

FileOutputFormat.setOutputPath(job,new Path("/map/output8"));

// 将作业提交到群集并等待它完成,参数设置为 true 代表打印显示对应的进度

boolean result=job.waitForCompletion(true);

// 根据作业结果,终止当前运行的 Java 虚拟机,退出程序

System.exit( result ? 0:-1);

}

}

[hadoop@hadoop000 hadoop-2.6.0-cdh5.15.1]$ hadoop fs -cat /map/input/local.txt

helloworld

hellohello

hello

world

[hadoop@hadoop000 hadoop-2.6.0-cdh5.15.1]$

[hadoop@hadoop000 hadoop-2.6.0-cdh5.15.1]$ hadoop fs -ls /map/output8

Found 2 items

-rw-r--r-- 3 hadoop supergroup 0 2020-08-27 16:01 /map/output8/_SUCCESS

-rw-r--r-- 3 hadoop supergroup 19 2020-08-27 16:01 /map/output8/part-r-00000

[hadoop@hadoop000 hadoop-2.6.0-cdh5.15.1]$ hadoop fs -cat /map/output8/part-r-00000

1

hello4

world2

[hadoop@hadoop000 hadoop-2.6.0-cdh5.15.1]$

本地方式运行

package com.bigdata.hadoop.mr.wc;

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上的文件对应的词频

//Driver: 配置Mapper,Reducer的相关属性

public class WordCountLocalApp {

public static void main(String[] args) throws Exception{

Configuration configuration= new Configuration();

Job job = Job.getInstance(configuration);

job.setMapperClass(WordCountMapper.class);

job.setReducerClass(WordCountReducer.class);

job.setMapOutputKeyClass(Text.class);

job.setMapOutputValueClass(IntWritable.class);

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(IntWritable.class);

FileInputFormat.setInputPaths(job,new Path("input"));

FileOutputFormat.setOutputPath(job,new Path("output"));

boolean result=job.waitForCompletion(true);

System.exit( result ? 0:-1);

}

}

重构代码

问题,当输出目录存在的时候会报错

//如果路径存在就删除

FileSystem fs=FileSystem.get(new URI("hdfs://192.168.1.200:8020"),configuration,"hadoop");

Path output=new Path("/map/outpu");

if(fs.exists(output)){

fs.delete(output,true);

}

//设置job对应的参数:作业输出的的路径

FileInputFormat.setInputPaths(job,new Path("/map/input"));

FileOutputFormat.setOutputPath(job,new Path("output"));

问题区分大小写

@Override

protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {

//把value按照指定的分割符分开

String[] words=value.toString().split("\t");

for(String word: words){

//.toLowerCase()

context.write(new Text(word.toLowerCase()),new IntWritable(1));

}

}

Combiner操作

combiner是 map 运算后的可选操作,它实际上是一个本地化的 reduce 操作,它主要是在 map 计算出中间文件后做 一个简单的合并重复 key 值的操作 。这里以词频统计为例:

89f709a1a65a9852e6a741ca40f0ce12.png

map 在遇到一个 hadoop 的单词时就会记录为 1,但是这篇文章里 hadoop 可能会出现 n 多次,那么 map 输出文件冗余就会很多,因此在 reduce 计算前对相同的 key 做一个合并操作,那么需要传输的数据量就会减少,传输效率就可以得到提升。

d9cad46d074863a904f335d05af434c3.png

为了避免map任务和reduce任务之间的数据传输而设置的,Hadoop允许用户针对map task的输出指定一个合并函数。即为了减少传输到Reduce中的数据量。它主要是为了削减Mapper的输出从而减少网络带宽和Reducer之上的负载。

1d6001ef19a9897e2040f11517b9b870.png

//添加Combiner的设置的即可

job.setCombinerClass(WordCountReducer.class);

但并非所有场景都适合使用 combiner,使用它的原则是 combiner 的输出不会影响到 reduce 计算的最终输入,例如:求总数,最大值,最小值时都可以使用 combiner,但是做平均值计算则不能使用 combiner。

09d5326323aed19f459909a631521e2f.png

VHDL语言100例 VHDL学习资料VHDL 编程要点VHDL编程心得体会: 100vhdl例子 VHDL 编程要注意问题.doc VHDL——按键消抖.doc VHDL电路简化.doc VHDL编程心得体会.pdf vhd开发的官方手册.pdf 第1例 带控制端口的加法器 第2例 无控制端口的加法器 第3例 乘法器 第4例 比较器 第5例 二路选择器 第6例 寄存器 第7例 移位寄存器 第8例 综合单元库 第9例 七值逻辑与基本数据类型 第10例 函数 第11例 七值逻辑线或分辨函数 第12例 转换函数 第13例 左移函数 第14例 七值逻辑程序包 第15例 四输入多路器 第16例 目标选择器 第17例 奇偶校验器 第18例 映射单元库及其使用举 第19例 循环边界常数化测试 第20例 保护保留字 第21例 进程死锁 第22例 振荡与死锁 第23例 振荡电路 第24例 分辨信号与分辨函数 第25例 信号驱动源 第26例 属性TRANSACTION和分辨信号 第27例 块保护及属性EVENT, 第28例 形式参数属性的测试 第29例 进程和并发语句 第30例 信号发送与接收 第31例 中断处理优先机制建模 第32例 过程限定 第33例 整数比较器及其测试 第34例 数据总线的读写 第35例 基于总线的数据通道 第36例 基于多路器的数据通道 第37例 四值逻辑函数 第38例 四值逻辑向量按位或运算 第39例 生成语句描述规则结构 第40例 带类属的译码器描述 第41例 带类属的测试平台 第42例 行为与结构的混合描述 第43例 四位移位寄存器 第44例 寄存/计数器 第45例 顺序过程调用 第46例 VHDL中generic缺省值的使用 第47例 无输入元件的模拟 第48例 测试激励向量的编写 第49例 delta延迟例释 第50例 惯性延迟分析 第51例 传输延迟驱动优先 第52例 多倍(次)分频器 第53例 三位计数器与测试平台 第54例 分秒计数显示器的行为描述6 第55例 地址计数器 第56例 指令预读计数器 第57例 加.c减.c乘指令的译码和操作 第58例 2-4译码器结构描述 第59例 2-4译码器行为描述 第60例 转换函数在元件例示中的应用 第61例 基于同一基类型的两分辨类型的赋值相容问题 第62例 最大公约数的计算 第63例 最大公约数七段显示器编码 第64例 交通灯控制器 第65例 空调系统有限状态自动机 第66例 FIR滤波器 第67例 五阶椭圆滤波器 第68例 闹钟系统的控制 第69例 闹钟系统的译码 第70例 闹钟系统的移位寄存器 第71例 闹钟系统的闹钟寄存器和时间计数器 第72例 闹钟系统的显示驱动器 第73例 闹钟系统的分频器 第74例 闹钟系统的整体组装 第75例 存储器 第76例 电机转速控制器 第77例 神经元计算机 第78例ccAm2901四位微处理器的ALU输入 第79例ccAm2901四位微处理器的ALU 第80例ccAm2901四位微处理器的RAM 第81例ccAm2901四位微处理器的寄存器 第82例ccAm2901四位微处理器的输出与移位 第83例ccAm2910四位微程序控制器中的多路选择器 第84例ccAm2910四位微程序控制器中的计数器/寄存器 第85例ccAm2910四位微程序控制器的指令计数器 第86例ccAm2910四位微程序控制器的堆栈 第87例 Am2910四位微程序控制器的指令译码器 第88例 可控制计数器 第89例 四位超前进位加法器 第90例 实现窗口搜索算法的并行系统(1)——协同处理器 第91例 实现窗口搜索算法的并行系统(2)——序列存储器 第92例 实现窗口搜索算法的并行系统(3)——字符串存储器 第93例 实现窗口搜索算法的并行系统(4)——顶层控制器 第94例 MB86901流水线行为描述组成框架 第95例 MB86901寄存器文件管理的描述 第96例 MB86901内ALU的行为描述 第97例 移位指令的行为描述 第98例 单周期指令的描述 第99例 多周期指令的描述 第100例 MB86901流水线行为模型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值