Honeyc's Blog

idea下使用脚本在远程hadoop环境去执行和交互

在ideal下创建maven工程,编写mapreduce程序,调用虚拟机上hadoop分布式执行,避免每次都要进行打包,将文件、jar包上传到主节点master上,在主节点上再去调用

1.idea创建maven工程,目录结构如下

maven目录结构

input 文件下放程序需要读取的文件,每个程序对应input下一个文件夹,如wordcount,words文件为com.zju.czx.WordCount 要读取的文件;
output 下为程序执行完成从hdfs上放下的文件
target 存放整个项目的打包生成的jar
src 存放mapreduce的程序
shell 存放执行脚本,通过脚本来对虚拟机上进行操作

pom.xml 使用的是hadoop版本1.2.1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zju.czx</groupId>
<artifactId>remoteHadoop</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>remoteHadoop</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<hadoop.version>1.2.1</hadoop.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

2.在idea这个开发环境的机器上,与master设置ssh的免密码登录

1
2
3
4
5
6
7
8
# 在ssh下生成 id_rsa.pub、id_rsa
ssh-keygen -t rsa
# 将公钥复制到master下面
cp id_rsa.pub honeycc_ id_rsa.pub
scp .ssh/honeycc_ id_rsa.pub czx-hadoop@192.168.149.135:~/.ssh/
# 在master上,将公钥添加到 authorized_keys上
cat .ssh/honeycc_ id_rsa.pub >> authorized_keys
#设置成功

3.编写脚本,将开发环境与master进行开发

run.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/bin/sh
jarname=$1
main=$2
dirctory=$3
if [ "$#" -eq "3" ];then
echo "你的jar包的名字是:${jarname}"
echo "你所要执行的主类:${main}"
echo "你所导入的文件目录:${dirctory}"
echo " 将 ${jarname} 上传到主节点的hadoop路径下 master ~/hadoop/"
scp ../target/${jarname} czx-hadoop@192.168.149.135:~/hadoop/
echo " 本地文件复制到主节点上 ../input/${dirctory} czx-hadoop@192.168.149.135:~/input/${dirctory}"
scp -r ../input/${dirctory} czx-hadoop@192.168.149.135:~/input/
echo "在主节点链接 hdfs 创建文件夹 ./hadoop/bin/hadoop fs -mkdir /input/${dirctory}"
ssh czx-hadoop@192.168.149.135 "./hadoop/bin/hadoop fs -mkdir /input/${dirctory}"
echo "将主节点上文件上传到hdfs上 ./hadoop/bin/hadoop fs -put ~/input/${dirctory}/* /input/${dirctory}/"
ssh czx-hadoop@192.168.149.135 "./hadoop/bin/hadoop fs -put ~/input/${dirctory}/* /input/${dirctory}/"
echo "删除输出目录 ./hadoop/bin/hadoop rm -r /output/${dirctory}"
ssh czx-hadoop@192.168.149.135 "./hadoop/bin/hadoop fs -rmr /output/${dirctory}"
echo " 执行${jarname} ./hadoop/bin/hadoop jar hadoop/${jarname} ${main} /input/${dirctory}/* /output/${dirctory}"
ssh czx-hadoop@192.168.149.135 "./hadoop/bin/hadoop jar hadoop/${jarname} ${main} /input/${dirctory}/* /output/${dirctory}"
ssh czx-hadoop@192.168.149.135 "rm -r ~/output/${dirctory}"
echo "从hdfs取出执行完成的结果 ./hadoop/bin/hadoop fs -get /output/${dirctory} ~/output/${dirctory}"
ssh czx-hadoop@192.168.149.135 "./hadoop/bin/hadoop fs -get /output/${dirctory} ~/output/${dirctory}"
echo "将结果复制到本地"
rm -r ../output/${dirctory}
scp -r czx-hadoop@192.168.149.135:~/output/${dirctory}/ ../output/
else
echo "需要提供3个参数,你只提供了 $# 参数,第一个参数为jar名字,第二个为执行主函数 第三个为输入文件的文件夹名字 eg: remoteHadoop-1.0-SNAPSHOT.jar com.zju.czx.WordCount words"
fi

总结

这样一来就减少了每次再手动与虚拟机进行脚本,一个脚本就进行操作了。在执行上可能要按照规定好规则去执行。目录结构的创建也要按照规则去创建。不过自己使用起来还是很方便的,而且用maven对其进行打包控制,可以重复编写多个mapreduce程序,只要在执行脚本的时候设定好主类就好了。

1
2
./run.sh remoteHadoop-1.0-SNAPSHOT.jar com.zju.czx.WordCount words
# jar包,主类类名,程序要读取的文件夹