一、架构Hadoop
首先安装ubuntu,虚拟机VMware
下载hadoop2.7.7
1、安装SSH,设置SSH无密码登录,在服务器A上执行命令,创建密钥对。
2、加入授权,然后已经不需要密码就可以登陆localhost。
3、安装jdk1.8.0_231,首先下载jdk,上传到ubuntu上,配置环境变量。
4、在文件修改完毕后,输入以下代码使新配置的环境变量生效,检查是否安装成功。查看java版本。
5、下载hadoop2.7.7,然后解压Hadoop压缩包。然后配置Hadoop的bin和sbin文件夹到环境变量中。
执行source ~/.bashrc使配置生效,并查看hadoop是否成功。
6、修改/etc/hadoop/hadoop-env.sh配置JAVA_HOME
7、修改core-site.xml文件主要配置访问Hadoop集群的主要信息,localhost是主机名称,9000代表端口。外部通过配置hdfs://localhost:9000信息,就可以找到Hadoop集群。
8、hdfs-site.xml配置文件配置了HDFS的相关信息,其中dfs.replication代表副本数,这里设置为1.
9、配置完成后格式化HDFS,初始化集群,基本配置完成后。
10、启动namenode和datanode进程,并查看启动结果。启动完成后,可以通过命令jps来判断是否成功启动,启动后会列出如下进程:“Namenode”,“Datanode”,”SecondaryNameNode”
11、成功启动后,可以访问Web:http://localhost:50070查看NameNode和DataNode信息,还可以在线查看HDFS的文件。
二、运行MapReduce案例
1、下载hadoop-eclipse-plugin-2.7.7jar
2、下载Eclipse,添加Hadoop。
3、创建项目。
4、配置Hadoop端口。
5、配置完成,打开DFS文件系统。打开DFS Locations查看HDFS文件系统,可以直接查看HDFS的文件,不需要通过命令进行控制。
6、创建数据源,并上传数据
(前四位是年份,后两位为数据,改程序用来判断每一年的数据出现的最大数据)
7、编写MapReduce程序,添加需要的依赖文件。
package org.apache.hadoop.examples;
import java.io.IOException;
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.util.GenericOptionsParser;
public class years_maxNumber {
/**
* Map
*/
public static class mapper extends Mapper<Object, Text, Text, IntWritable>{
public void map(Object key, Text value, Context context) throws IOException, InterruptedException{
//value为每一行的值
//Text相当于String,IntWritable相当于int
String date = value.toString().substring(0, 4); //取前四位年份
String tem = value.toString().substring(4); //取后两位的数据
int tem_ = Integer.parseInt(tem); //转换为int型
context.write(new Text(date), new IntWritable(tem_));
//这里可以理解为用context将数据打包给reduce
//假设这里的数据为201835,经过以上步骤后date=2018,tmp_=35
//假设下一个数据为201833,经过以上步骤后date=2018,tmp_=33
//…………
//经历了Map后,会将年份相同的所有数据放在一起 可看作一个list
//因此在Reduce端接收到的数据中 key=2018,values=[33,35……]
}
}
/**
* Reduce
*/
public static class reducer extends Reducer<Text, IntWritable, Text, IntWritable>{
public void reduce(Text key,Iterable<IntWritable> values, Context context) throws IOException, InterruptedException{
int max = 0;
for(IntWritable val:values) { //迭代values值
int temp = Integer.parseInt(val.toString()); //取val值并转换成int型
if(temp > max) { //比较最大值
max = temp;
}
}
context.write(key, new IntWritable(max)); //最终结果,key为年份,max为最大数据
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
if (otherArgs.length != 2) {
System.err.println("Usage: wordcount <in> <out>");
System.exit(2);
}
Job job = new Job(conf, "firstTest"); //创建一个作业
job.setJarByClass(years_maxNumber.class); //指定class
job.setMapperClass(mapper.class); //设置对应的Map类
job.setCombinerClass(reducer.class); //这里设置为Reduce类
job.setReducerClass(reducer.class); //设置对应的Reduce类
job.setOutputKeyClass(Text.class); //设置最终结果中key的类型,这里是Text
job.setOutputValueClass(IntWritable.class); //设置最终结果中value的类型,这里是IntWritable
FileInputFormat.addInputPath(job, new Path(otherArgs[0])); //设置数据来源
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1])); //设置输出结果存储位置
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
8、运行程序。
9、查看运行结果。