简单介绍下词频分析,就是统计一个文件中的字段名的出现的次数。
实现过程:
1.创建maven工程
在pom.xml中加入配置信息
以下内容可以在maven 中心仓库中找到
<!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-client -->
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.8.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<!-- maven打包插件jdk的版本 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
2.编写MapTask类和ReduceTask类
/**
* KEYIN : 是接受的参数key的类型,默认是一行的起始偏移量,Long
* VALUEIN: 是接受的参数valued的类型,默认是一行的内容,String
*
* KEYOUT: 是输出的key的类型,String
* VALUEOUT:是输出的value的类型,Integer
*
* 然而,在mapreduce中,这些key、value数据需要经常序列化到磁盘文件中,但是java中的这些内置数据类型实现的是jdk中的serializable序列化接口
* 这种序列化机制产生的二进制数据非常臃肿,在分佈式计算领域中,效率极其低下
*
* 所以,hadoop开发了一套自己的序列化机制,提供了一个序列化接口Writable
* 那么,在mapreduce中,凡是需要进行序列化的数据,都必须实现Writable接口
*
* String ==> Text
* Integer ==> IntWritable
* Long ==> LongWritable
* Float ==> FloatWritable
* Double ==> DoubleWritable
* ....
*
* @author hunter.ganhoo
*
*/
public class MapTask extends Mapper<LongWritable, Text, Text, IntWritable>{
//继承mapper类的时候有四个参数,分别是keyin,valuein,keyout,valueout
@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context)
throws IOException, InterruptedException {
String[] split = value.toString().split(" ");
for (String string : split) {
context.write(new Text(string), new IntWritable(1));
}
}
}
reduce类:
public class ReduceTask extends Reducer<Text, IntWritable, Text, IntWritable>{
@Override
protected void reduce(Text word, Iterable<IntWritable> values,
Context context) throws IOException, InterruptedException {
int count = 0;
for (IntWritable value : values) {
count += value.get();
}
context.write(word, new IntWritable(count));
}
}
3.还需要一个启动类Driver.class
public class Driver {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
//设置程序jar包所在的路径
job.setJarByClass(Driver.class);
job.setMapperClass(MapTask.class);//设置map方法所属类的位置
job.setReducerClass(ReduceTask.class);//设置reduce方法所属类的位置
job.setMapOutputKeyClass(Text.class);//map的输出的偏移量的类型
job.setMapOutputValueClass(IntWritable.class);//输出的内容的类型
job.setOutputKeyClass(Text.class);//对应
job.setOutputValueClass(IntWritable.class);
FileInputFormat.setInputPaths(job, new Path("/a.txt"));//指定hdfs集群上的文件路径
FileOutputFormat.setOutputPath(job, new Path("/wordcount/output/"));//指定生成结果的路径
//这个方法可以看到提交的过程
boolean b = job.waitForCompletion(true);//提交结果 也可以是submit()
System.out.println(b?"执行成功,没毛病,老铁":"执行失败了,老铁");
}
}
注意:这个是到集群的操作,也可以是本地,只需要在driver类中配置就行。