写在开头:目前已经陆陆续续搭建好了Linux、Hadoop相关的环境,可以开始一些简单的实例演示了。后面也会陆续更新这个系列了。
学习内容安排
本阶段学习内容的安排的话可能没有具体的内容规划,不会去涉及环境配置、软件安装的内容,主要是以介绍使用为主,以实例出发。大数据需要在Linux系统上进行,然后现在电脑使用的软件如下(部分软件由于学习原因选择的老版本),
软件名称 | 备注 |
---|---|
NetBeans IDE 8.2 | JAVA编译器 |
CentOS 6.6 | Linux系统 |
VMware Workstation11 | 桌面版虚拟机 |
SecureCRT 7.0.0 | 终端仿真程序 |
Hadoop 2.6.5 | 分布式框架 |
Hive 1.2.2 | 数据仓库 |
电脑配置和虚拟机分配方面,因为资金有限,笔记本配置只有16个g,创建了4台虚拟机组建了伪分布式,配置这些已经调整好了,可能还没有安装的朋友在这个安装过程中可能需要费电功夫了,下面开始今天的Mapreduce实战讲解吧。
MapReduce之词频统计
MapReduce的介绍一时半会儿可能解释不清楚,这里大家可以参考学习一下这篇MapReduce过程总结,讲得还是比较清楚了,好了让我们正式开始吧。
今天要完成的目标是对一个本地txt文档利用MapReduce进行统计分析,所需的流程1.上传数据、2.编写MapReduce Java代码、3.输出结果。
1.上传数据
其实数据就是自己随意编写的一段话,首先需要从本地上传数据,假设我们本地数据放在c盘,然后需要知道自己的master主节点ip地址(可在linux中使用ifconfig进行查看)和上传的文件的目标文件夹,这里上传数据不是上传到linux里,而是直接上传到HDFS里,代码如下,
// 本地上传数据到HDFS
package com.mycompany.mavenproject1;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public class NewClass {
public static void main(String[] args) throws IOException {
Configuration conf = new Configuration(); //初始化配置
conf.set("fs.defaultFS", "hdfs://192.168.0.23:9000"); //连接数据库fs.defaultFS为配置文件、9000为端口号
FileSystem file = FileSystem.get(conf);// 设置文件配置
file.copyFromLocalFile(new Path("c:/t1.txt"), new Path("/user/root/input/")); //确定输入与输出路径
file.close();
}
}
上传完数据后可以在网页版Hadoop窗口进行查看,网址为http://你的主节点ip:50070/explorer.html,
2.编写MapReduce Java代码
然后就来通过java编写MapReduce的整个流程代码吧,首先编写Map代码
Map编写思路:
1)需要在类上定义Map输入键值对于输出到Reduce的键值对类别,这里,这里定义输入的键值对为每一行的数据,所有就有行号和值,于是定义其类别为LongWritable和Text,然后输出的应该是每个单词和数值1,类别是Text和LongWritable,所以定义Mapper<LongWritable, Text, Text, LongWritable>;
2)然后编写map函数:首先需要对每次输入的值转为字符型并全为小写,然后利用split进行分词,最后将分好的词通过循环,输出值与个数1的键值对。
package test;
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
public class WcMapper extends Mapper<LongWritable, Text, Text, LongWritable>{//框架传过来是什么、写回去的是什么类型
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
String line = value.toString().toLowerCase(); //得到了每一行的数据
String[] words = line.split("[\\s\\d\\pP]+");
for (String word: words) {
context.write(new Text(word), new LongWritable(1));
}
}
}
Reduce编写思路
将Map输出的值传入Reduce进行自动计算,最后输出我们想要的词频统计,
1)首先接受从Map传过来的对应数据类型然后再输出单词和词频,也就是Text和Longwritable;
2)编写reduce函数,将value设置为LongWritable可进行数值循环,然后初始化count用于技术,通过强制转换value进行值的统计,最后将值传入最后的工作文档进行输出。
package test;
import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class WcReduce extends Reducer<Text, LongWritable, Text, LongWritable>{
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
int count = 0;
for (LongWritable value : values) {
count = count + (int)value.get();
}
context.write(key, new LongWritable(count));
}
}
执行代码编辑思路
首先需要连接HDFS,定义Job作业,然后依次配置Map、Reduce、Map输出类别,整体输出类别,文件读取/输出路径,其他的都是程序进程类信息,这样再Hadoop启动后,运行程序就可以实现词频统计啦。
package test;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
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;
import org.apache.log4j.BasicConfigurator;
public class WordCount {
public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {
BasicConfigurator.configure();
Configuration conf = new Configuration();
conf.set("fs.defaultPS", "hdfs://192.168.0.23:9000");//hadoop集群下的配置core-site.xml
Job job = Job.getInstance(conf);
job.setJarByClass(WordCount.class);
job.setMapperClass(WcMapper.class);
job.setReducerClass(WcReduce.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
FileInputFormat.setInputPaths(job, new Path("hdfs://192.168.0.23:9000/user/root/input"));
FileOutputFormat.setOutputPath(job, new Path("hdfs://192.168.0.23:9000/user/root/output"));
job.waitForCompletion(true);
System.setProperty("hadoop.home.dir", "D:\\hadoop-common-2.2.0-bin-master\\hadoop-common-2.2.0-bin-master");
}
}
3.输出结果.
最后来看一看输出的结果,不错,确实是我们需要的词频统计。
结语
词频统计在之前也用个Java写过,但是Hadoop最明显的优点就是速度快,此次使用的文件比较小,还体现不出来Hadoop的优越性,后续如果有机会优化,还可以把Hadoop分词嵌入到可视化界面进行,不过现在先学习一下后续的内容。
谢谢阅读。