idea远程调试MapReduce

作为习惯了用idea开发的小伙伴,不太想用eclipse开发Hadoop,于是研究了一下idea如何远程调试mr,现分享一下。

一 开发环境

本地win10系统

Intellij idea14工具

虚拟机中hadoop2.6.0伪分布模式

二配置步骤(这里笨小葱参考的这篇文章http://www.cnblogs.com/yjmyzz/p/how-to-remote-debug-hadoop-with-eclipse-and-intellij-idea.html下面列出idea中的配置)

2.1 下载hadoop-2.6.0二进制文件(hadoop-2.6.0.tar.gz),解压。

官网地址:https://archive.apache.org/dist/hadoop/common/hadoop2.6.0/.

2.2 在win10中添加几个环境变量

HADOOP_HOME=D:\yangjm\Code\study\hadoop\hadoop-2.6.0

HADOOP_BIN_PATH=%HADOOP_HOME%\bin

HADOOP_PREFIX=D:\yangjm\Code\study\hadoop\hadoop-2.6.0

另外,PATH变量在最后追加;%HADOOP_HOME%\bin

2.3 创建一个maven的WordCount项目

pom文件如下:

idea远程调试MapReduce
idea远程调试MapReduce
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
 3          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 5     <modelVersion>4.0.0</modelVersion>
 6 
 7     <groupId>yjmyzz</groupId>
 8     <artifactId>mapreduce-helloworld</artifactId>
 9     <version>1.0-SNAPSHOT</version>
10 
11     <dependencies>
12         <dependency>
13             <groupId>org.apache.hadoop</groupId>
14             <artifactId>hadoop-common</artifactId>
15             <version>2.6.0</version>
16         </dependency>
17         <dependency>
18             <groupId>org.apache.hadoop</groupId>
19             <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
20             <version>2.6.0</version>
21         </dependency>
22         <dependency>
23             <groupId>commons-cli</groupId>
24             <artifactId>commons-cli</artifactId>
25             <version>1.2</version>
26         </dependency>
27     </dependencies>
28 
29     <build>
30         <finalName>${project.artifactId}</finalName>
31     </build>
32 
33 </project>
idea远程调试MapReduce

项目结构如下:

idea远程调试MapReduce

项目上右击-》Open Module Settings 或按F12,打开模块属性

idea远程调试MapReduce

添加依赖的Libary引用

idea远程调试MapReduce

然后把$HADOOP_HOME下的对应包全导进来

idea远程调试MapReduce

导入的libary可以起个名称,比如hadoop2.6

idea远程调试MapReduce

3.2 设置运行参数

idea远程调试MapReduce

注意二个地方:

1是Program aguments,这里跟eclipes类似的做法,指定输入文件和输出文件夹

2是Working Directory,即工作目录,指定为$HADOOP_HOME所在目录

然后就可以调试了

idea远程调试MapReduce

intellij下唯一不爽的,由于没有类似eclipse的hadoop插件,每次运行完wordcount,下次再要运行时,只能手动命令行删除output目录,再行调试。

 在IDE环境中运行时,IDE需要知道去连哪一个hdfs实例(就好象在db开发中,需要在配置xml中指定DataSource一样的道理),将$HADOOP_HOME\etc\hadoop下的core-site.xml,复制到resouces目录下,类似下面这样:
idea远程调试MapReduce

里面的内容如下:

idea远程调试MapReduce
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://172.28.20.***:9000</value>
    </property>
</configuration>
idea远程调试MapReduce

上面的IP换成虚拟机里的IP即可


三 bug解决

问题0:如果启动最初报错一个winutils.exe 找不到,那么下载一下放到HADOOP_HOME的bin目录下.(这里还需要添加一个下载hadoop.dll放到HADOOP_HOME的bin目录下和windows系统的c:/window/system32/,不然的话会出现问题三错误。)

这里分享一下winutils.exe和hadoop.dll的2.6.0版本

网盘地址:http://pan.baidu.com/s/1i5HKJIH

问题一 

抛异常:java.io.IOException: Failed on local exception: com.google.protobuf.InvalidProtocolBufferException: Protocol messageend-group tag did not match expected tag.;

可能是端口问题 
cdh的环境下,hdfs是8020端口,conf.set(“fs.defaultFS”, “hdfs://192.168.0.4:8020”); 
普通hadoop环境,hdfs是9000端口,conf.set(“fs.defaultFS”, “hdfs://192.168.0.121:9000”);


问题二:
抛异常:Exception in thread "main" java.lang.UnsatisfiedLinkError:org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z
at org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Native Method)
at org.apache.hadoop.io.nativeio.NativeIO$Windows.access(NativeIO.java:557)
at org.apache.hadoop.fs.FileUtil.canRead(FileUtil.java:977)
at org.apache.hadoop.util.DiskChecker.checkAccessByFileMethods(DiskChecker.java:187)
        ........

修改org.apache.hadoop.io.nativeio.NativeIO源码:

idea远程调试MapReduceidea远程调试MapReduce

为:

idea远程调试MapReduceidea远程调试MapReduce

重新编译


问题三:

Exception in thread "main" java.lang.UnsatisfiedLinkError:org.apache.hadoop.util.NativeCrc32.nativeComputeChunkedSumsByteArray(II[BI[BIILjava/lang/String;JZ)V

at org.apache.hadoop.util.NativeCrc32.nativeComputeChunkedSumsByteArray(Native Method)

at org.apache.hadoop.util.NativeCrc32.calculateChunkedSumsByteArray(NativeCrc32.java:86)

at org.apache.hadoop.util.DataChecksum.calculateChunkedSums(DataChecksum.java:430)

at org.apache.hadoop.fs.FSOutputSummer.writeChecksumChunks(FSOutputSummer.java:202)

     。。。。。。。。

下载hadoop.dll放到HADOOP_HOME的bin目录下和windows系统的c:/window/system32/

注意如果这个hadoop.dll的版本要和hadoop的一致,可以稍微高一点,低了可能就会报这个异常


问题四:

异常信息: 

Exception in thread "main" org.apache.hadoop.security.AccessControlException: Permission denied:user=Administrator, access=WRITE, inode="/spark/global":root:supergroup:drwxr-xr-x

at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkFsPermission(FSPermissionChecker.java:271)

at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:257)

这是因为当前用户Administrator没有对hdfs的写入权限. 有几种方式解决:

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

2、将当前系统的帐号修改为hdfs用户(CDH默认为用户名hdfs)

3、使用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目录,后面的这个是为根目录调整权限。


bug全部改完后打个断点就可以远程调试mr啦。idea远程调试MapReduce