Java中的mapreduce没了_Hadoop之MapReduce的Java实现

今天将为大家演示一下,Hadoop中MR用Java是如何编码实现的。

1.环境准备

1.1 需要把下载的hadoop包解压到windows目录下,注意不要有空格目录或者中文字符

ad258b3ed6a5

image.png

1.2 配置环境变量

配置系统环境变量HADOOP_HOME,指向hadoop安装目录(如果你不想招惹不必要的麻烦,不要在目录中包含空格或者中文字符) 。把HADOOP_HOME/bin加到PATH环境变量(非必要,只是为了方便)

以下截图为windows下配置:

ad258b3ed6a5

image.png

ad258b3ed6a5

image.png

1.3 windows例外配置1

如果是windows:在E:\bigdata\hadoop\etc\hadoop目录下的hadoop-env.cmd文件中修改JAVA_HOME环境变量(注意JDK安装路径不能含有空格,如:C:\Java\jdk1.8.0_11)

ad258b3ed6a5

image.png

1.4 windows例外配置2

如果是在windows下开发,需要添加windows的库文件,把网盘中共享的bin目录覆盖HADOOP_HOME/bin(已经转移到CSDN,下载),如果还是不行,把其中的hadoop.dll复制到c:\windows\system32目录下,可能需要重启机器。

1.5 建立新项目,引入hadoop需要的jar文件

2.代码

WordMapper类:

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;

import org.apache.hadoop.io.LongWritable;

import org.apache.hadoop.io.Text;

import org.apache.hadoop.mapreduce.Mapper;

public class WordMapper extends Mapper {

@Override

protected void map(LongWritable key, Text value, Mapper.Context context)

throws IOException, InterruptedException {

//接收到split中的输出结果作为map的输入

String line = value.toString();

String[] words = line.split(" ");

//放到list中,每个text统计加1,作为map的输出

//写到context上下文环境中,输出到下一个执行过程shuffle

for(String word : words) {

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

}

}

}

WordReducer类

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;

import org.apache.hadoop.io.LongWritable;

import org.apache.hadoop.io.Text;

import org.apache.hadoop.mapreduce.Reducer;

public class WordReducer extends Reducer {

@Override

protected void reduce(Text key, Iterable values,

Reducer.Context context) throws IOException, InterruptedException {

long count = 0;

//此时的输入是shuffle的输出

//输入的key是字符串,输入的value是shuffle派发过来的是一个个list

for(IntWritable v : values) {

count += v.get();

}

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

}

}

3.运行

3.1 直接本地运行

直接本地输入输出,代码Test

import org.apache.hadoop.conf.Configuration;

import org.apache.hadoop.fs.Path;

import org.apache.hadoop.io.IntWritable;

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;

public class Test {

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

Configuration conf = new Configuration();

Job job = Job.getInstance(conf);

job.setMapperClass(WordMapper.class);

job.setReducerClass(WordReducer.class);

job.setMapOutputKeyClass(Text.class);

job.setMapOutputValueClass(IntWritable.class);

job.setOutputKeyClass(Text.class);

job.setOutputValueClass(LongWritable.class);

FileInputFormat.setInputPaths(job, "c:/bigdata/hadoop/test/test.txt");

FileOutputFormat.setOutputPath(job, new Path("c:/bigdata/hadoop/test/out/"));

job.waitForCompletion(true);

}

}

直接本地运行结果:

ad258b3ed6a5

本地运行结果1.png

ad258b3ed6a5

本地运行结果2.png

3.2 把hdfs中的文件拉到本地来运行

需要Test中的以下代码:

FileInputFormat.setInputPaths(job, "hdfs://master:9000/wcinput/");

FileOutputFormat.setOutputPath(job, new Path("hdfs://master:9000/wcoutput2/"));

注意这里是把hdfs文件拉到本地来运行,如果观察输出的话会观察到jobID带有local字样

同时这样的运行方式是不需要yarn的(自己停掉yarn服务做实验)

ad258b3ed6a5

hdfs文件拉到本地来运行.png

如上图,此时还是在本地运行mapReduce程序

3.3 在远程服务器执行

修改以下代码:

//配置了fs.defaultFS选项,则下面的setInputPaths等配置不需要再配置前缀

conf.set("fs.defaultFS", "hdfs://192.168.56.200:9000/");

conf.set("mapreduce.framework.name", "yarn");//MapReduce运行环境为yarn

conf.set("yarn.resourcemanager.hostname", "192.168.56.200");//yarn的recourseManager的主机名

conf.set("mapreduce.app-submission.cross-platform", "true");//表示MapReduce是跨平台运行的

FileInputFormat.setInputPaths(job, "/wcinput/");

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

此时运行,则会出现权限问题,如下图:

ad258b3ed6a5

image.png

如果遇到权限问题,有三种方法:

在系统的环境变量或java JVM变量里面添加HADOOP_USER_NAME,这个值具体等于多少看自己的情况,以后会运行HADOOP上的Linux的用户名。(修改完重启eclipse,不然可能不生效)

将当前系统的帐号修改为hadoop(运行HADOOP上的Linux的用户名,本例为root)

使用HDFS的命令行接口修改相应目录的权限,hadoop fs -chmod 777 /user,后面的/user是要上传文件的路径,不同的情况可能不一样,比如要上传的文件路径为hdfs://namenode/user/xxx.doc,则这样的修改可以,如果要上传的文件路径为hdfs://namenode/java/xxx.doc,则要修改的为hadoop fs -chmod 777 /java或者hadoop fs -chmod 777 /,java的那个需要先在HDFS里面建立Java目录,后面的这个是为根目录调整权限。

这里采用第一种方法配置执行时的虚拟机参数-DHADOOP_USER_NAME=root

ad258b3ed6a5

image.png

也可以将hadoop的四个配置文件拿下来放到src根目录下,就不需要进行手工配置了,默认到classpath目录寻找

或者将配置文件放到别的地方,使用conf.addResource(.class.getClassLoader.getResourceAsStream)方式添加,不推荐使用绝对路径的方式

通过以上配置以后,就可以运行MapReduce了,如下图所示:

ad258b3ed6a5

image.png

上图就表示,已经在远程服务器中执行MapReduce程序了(jobid没有local前缀了),但是问题又来了,执行到后面出现以下找不到类的情况:

java.lang.ClassNotFoundException: Class org.lyx.mapreduce.WordMapper not found

ad258b3ed6a5

image.png

这是因为服务器上没有WordMapper这个类,这时候需要两个步骤的操作:

1.打包整个MapReduce工程为一个jar包,eclipse的话直接export(java工程),如果是maven工程,直接使用Package打包成jar。如下图所示(idea):

ad258b3ed6a5

image.png

打包完成如下图所示:

ad258b3ed6a5

image.png

2.加入以下代码:

//配置此工程打好的jar包路径,建议使用相对路径

conf.set("mapreduce.job.jar", "target/mapreduce-0.0.1-SNAPSHOT.jar");

或者

job.setJar("target/mapreduce-0.0.1-SNAPSHOT.jar");

加入以上代码后,需要重新打包。

此时再次运行即可在远程服务器中执行MapReduce程序,执行结果如下图所示:

ad258b3ed6a5

远程运行结果.png

ad258b3ed6a5

远程运行结果.png

在web网页中观察结果如下:

hdfs中的情况:

ad258b3ed6a5

image.png

在yarn中的情况如下:

ad258b3ed6a5

image.png

4.Maven配置

建立maven-hadoop项目

4.1 pom.xml

junit

junit

4.12

org.apache.hadoop

hadoop-client

${hadoop.version}

org.apache.hadoop

hadoop-common

${hadoop.version}

org.apache.hadoop

hadoop-hdfs

${hadoop.version}

4.2 log4j

配置log4j.properties,放到src/main/resources目录下

log4j.rootCategory=INFO, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n

5.MapReduce运行程序常见错误以及解决办法:

错误1.

Exit code: 1

Exception message: /bin/bash: 第 0 行: fg: 无任务控制

Stack trace: ExitCodeException exitCode=1: /bin/bash: 第 0 行: fg: 无任务控制

在客户端配置文件(mapred-site.xml)中添加如下属性:

mapreduce.app-submission.cross-platform

true

注意:必须添加到Hadoop程序读取的客户端本地配置文件中,添加到客户端Hadoop安装路径中的“core-site.xml”,“mapred-site.xml”等文件中不起作用

或者在代码中加入:

conf.set("mapreduce.app-submission.cross-platform", "true");//表示MapReduce是跨平台运行的

6. eclipse插件

插件下载:http://download.csdn.net/download/landy8530/10106631

安装hadoop-eclipse插件,直接把hadoop-eclipse-plugin-2.7.3.jar文件放入到eclipse安装目录下的plugins目录即可(为了安全起见,可以先把eclipse先备份一下),重启eclipse,open perspective显示map/reduce即可。

ad258b3ed6a5

eclipse MR插件.png

然后在

ad258b3ed6a5

image.png

中新增一个hdfs的配置即可看到hdfs中的文件系统。

ad258b3ed6a5

image.png

ad258b3ed6a5

image.png

7.延伸阅读

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值