#hadoop 开发环境搭建 (ubuntu + idea ) @(hadoop笔记)[idea|开发环境]
基于ubuntu 和 idea 搭建 hadoop开发环境,其实是搭建MR的开发环境。这里简单说一下为什么采用idea,就因为一点,idea比eclipse爽的太多,虽然eclipse有hadoop插件,但是能用idea解决战斗,我宁愿牺牲一点的便利性。
[TOC]
##目的 首先,抛出该开发环境需要达到的目的和效果。
- 支持debug :首要目的!必须达到!不能调试的程序永远是程序员的噩梦。
- 单元测试 :方便微调代码逻辑之后的回归测试。
- 提交到远程集群 :可选,这个可以增加便利性。
基于以上三点,展开对开发环境的搭建。
##hadoop本地client环境搭建 这个是为了方便本地操作集群,包括管理hdfs和提交作业。由于只是提供了本地客户端的功能,所以配置非常简单(当然,如果远程集群开启了kerberos的话,本地也要初始化相应的Keytab)
第一步:下载与远程集群版本一致的hadoo的tar包,解压
第二步:配置环境变量
vi /etc/profile
#配置java环境
export JAVA_HOME=/opt/jdk1.7.0_79
export PATH=$PATH:$JAVA_HOME/bin
#配置hadoop环境,HADOOP_CONF_DIR用来读取配置文件,HADOOP_HOME用来加载hadoop程序和脚本
export HADOOP_CONF_DIR=/etc/hadoop/conf
export HADOOP_HOME=/path/to/your/hadoop #第一步里解压出来的那个路径
export PATH=$PATH:$HADOOP_HOME/bin
第三步:从远程集群上拷贝core-site.xml
,hdfs-site.xml
,yarn-site.xml
,mapred-site.xml
到第二步配置的HADOOP_CONF_DIR目录下
执行hdfs dfs -ls /
命令,测试一下是否成功显示远程hdfs的文件目录
##IDEA开发环境搭建 这一部分会比较详细,可能会有点啰嗦。。。 ###第一步:新建一个wordcount工程 新建一个maven工程wordcount,初始化创建以后如下图目录结构
第二步:生成完整wordcount代码
把hadoop MR的wordcount示例代码拷贝到工程目录下,源代码传送门,并在pom.xml添加所需依赖
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.6.0</version>
<!--<scope>provided</scope>-->
</dependency>
到这里,代码就完全不报错了
第三步:生成hadoop配置
拷贝远程集群上core-site.xml
,hdfs-site.xml
,yarn-site.xml
,mapred-site.xml
到 src/main/resources目录下(如果没有就手动创建,并该目录为resource),这样所需要的配置也有了。当然也可以conf.setXXX方式把所有需要的配置都设置上,但是拷贝配置文件更省事,也跟远程集群配置统一。
第四步:生成测试数据
这里如果把core-site.xml中的fs.defaultFS配置为file:///
表示使用本地文件系统,测试数据生成在本地就好了
<property>
<name>fs.defaultFS</name>
<!--<value>hdfs://DataCenterCluster</value>-->
<value>file:///</value>
</property>
生成本地文件系统上的测试数据
mkdir /tmp/in
# 生成测试数据
echo "this is a test file , test word count" > /tmp/in/test.txt
cat /tmp/in/test.txt
如果core-site.xml中的fs.defaultFS配置为hdfs://DataCenterCluster
(这个是ha的配置)表示使用远程的hdfs文件系统,测试数据就用hdfs上的,也可以在hdfs上手动生成测试数据,如下:
hdfs dfs -mkdir /tmp/in
echo "this is a test file , test word count" | hdfs dfs -put - /tmp/in/test.txt
hdfs dfs -cat /tmp/in/test.txt
当然对于真正MR程序,抽取一小部分真实数据作为测试数据是最好的
第五步:配置debug和run运行环境
配置本地debug运行,配置一个叫WordCount_local的Application,配置参数/tmp/in /tmp/out就是wordcount程序需要的参数。
修改为本地运行模式 重要!!!修改mapred-site.xml的mapreduce.framework.name为local(原本的值为yarn),即表示map和reduce都运行在本地的一个JVM中,方便调试。
运行debug模式 运行debug模式,进行断点调试测试
- map断点
- reduce断点
可以看到map和reduce的断点都能正常的进行断点调试,并能看到现在所有变量的值。这样就解决了文章开头目的的第一点“支持debug”,显然这个debug只能调试小数据量,用来调试程序的正确性。
运行run模式 运行完整的MR程序,这个其实跟debug模式结果一致,只是不进入断点,只测试一下结果数据是否正确。至此,我们使用了远程集群上的数据(第四步配置为集群),配置,只有map和reduce是运行在本地的JVM里,这样排除了yarn的调度的话已经非常接近真正集群的运行状况了(提交到集群其实就是把map和reduce在集群的某台机器的JVM里去运行)。在这里如果运行是预期结果的话已经可以直接打包提交运行了,如果不关心单元测试,可以直接跳到第七步。
第六步:单元测试(非必须)
这里单元测试用到了mrunit,可以很简单的模拟测试map和reduce方法,当修改了map的逻辑之后可以用单元测试测试修改之后的程序的正确性。 先添加mrunit的依赖到pom.xml文件中
<dependency>
<groupId>org.apache.mrunit</groupId>
<artifactId>mrunit</artifactId>
<version>1.1.0</version>
<classifier>hadoop2</classifier>
</dependency>
然后编写测试代码
package com.ottowu.test;
import junit.framework.TestCase;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mrunit.mapreduce.MapDriver;
import org.apache.hadoop.mrunit.mapreduce.ReduceDriver;
import java.io.IOException;
import java.util.Arrays;
/**
* Created by whl on 16-12-12.
*/
public class WordCountTest extends TestCase {
//单元测试map
public void testMap() throws IOException {
Text value = new Text("this is test");
IntWritable one = new IntWritable(1);
new MapDriver<Object, Text, Text, IntWritable>()
.withMapper(new WordCount.TokenizerMapper())
.withInput(NullWritable.get(), value) //模拟输入
.withOutput(new Text("this"), one) //模拟输出,多行输出
.withOutput(new Text("is"), one)
.withOutput(new Text("test"), one)
.runTest(); //运行测试
}
//单元测试reduce
public void testReduce() throws IOException {
IntWritable one = new IntWritable(1);
IntWritable two = new IntWritable(2);
new ReduceDriver<Text, IntWritable, Text, IntWritable>()
.withReducer(new WordCount.IntSumReducer())
.withInput(new Text("this"), Arrays.asList(new IntWritable[]{one, one}))//模拟输入,多行
.withInput(new Text("is"), Arrays.asList(new IntWritable[]{one}))
.withOutput(new Text("this"), two) //模拟输出,多行
.withOutput(new Text("is"), one)
.runTest(); //运行测试
}
}
运行测试,查看测试结果 运行成功,如图
如果运行失败,则会提示哪一个期待结果是不正确的,如图
更多有趣的用法请自行查阅资料
第七步:打包运行
执行mvn clean package
得到wordcount-1.0-SNAPSHOT.jar
运行命令 hadoop jar wordcount-1.0-SNAPSHOT.jar com.ottowu.test.WordCount /tmp/in /tmp/out
即可运行到远程集群上,接下来就是按照部署发布就好了,至此一次完整的开发结束。
通过IDEA直接提交任务到远程集群
一个非常有趣的尝试,可以直接在IDEA中提交任务,不过有点小瑕疵,留待以后补充吧。