Windows10+VMware Workstation Pro+Ubuntu 16.04+Hadoop-2.6.5+IDEA环境搭建(单机&伪分布式&集群)
(注:下面出现的"czifan"为用户名,需替换成自己的用户名)
本篇博客是在实践该篇博客的过程中的一些补充和修改~
0 - 安装VMware Workstation Pro
- 首先下载VM安装包(安装包链接)
- 根据提示安装VM即可
1 - 安装虚拟机(Ubuntu 16.04)
- 下载ubuntu镜像(推荐中科大镜像源)
- 打开VM,点击“主页”→“创建新的虚拟机“进行虚拟机创建即可
- 配置步骤不赘述,但有如下几个注意点:
- 在硬件兼容性中必须选择”Workstation 6.5-7.x“ !!!(不然的话后续启动虚拟机时候会报错)
- 推荐”自定义(高级)“安装方式
- 虚拟机配置使用默认即可(内存还是建议开大一点)
- 一般安装的时候自带安装VM Tools,即可以在本机和虚拟机复制粘贴文件,但由于安装包文件比较大,负责粘贴容易卡死,推荐使用本机和虚拟机的共享文件夹,具体配置过程可见此教程
- 如果出现“无法创建虚拟机,不具备执行此操作的权限”,请检查虚拟机保存文件夹路径是否规范(比如不能有空格等等)
2 - 配置SSH
更新apt包
sudo apt-get update
安装ssh server
sudo apt-get install openssh-server
配置ssh
ssh localhost
如果出现如下报错
The authenticity of host 'localhost (127.0.0.1)' can't be established. ECDSA key fingerprint is SHA256:gxlILe0dd3MNNVD5pXq/AdMcGj+MDA7y1o//BEghD+k. Are you sure you want to continue connecting (yes/no)? Host key verification failed.
编辑/etc/ssh/ssh_config文件,加入下面两行保存重新运行"ssh localhost"即可
StrictHostKeyChecking no UserKnownHostsFile /dev/null
配置无密码登陆,进行初次登陆之后,会自动在~目录下创建一个.ssh文件夹,进入该文件夹
cd ~/.ssh/
使用rsa算法生成密钥和公钥对,一路回车即可
ssh-keygen -t rsa
生成成功可看到保存的位置(默认保存路径~/.ssh/id_rsa)
Your identification has been saved in /home/czifan/.ssh/id_rsa. Your public key has been saved in /home/czifan/.ssh/id_rsa.pub.
把公钥加入到授权中
cat ./id_rsa.pub >> ./authorized_keys
再次运行"ssh localhost"就无需密码了!
3 - 配置java环境
可先用如下命令查看是否以及安装java
java -version
如果已经有java环境请略过这一小节!
首先,在官网下载jdk安装包,这里选择的是Linux x64的tar.gz包(如果下载时需要Oracle账号,可用这个博客提供的),也可以在此博客提供的链接下载,以下用的是jdk-8u221-linux-x64.tar.gz。
创建一个目录来管理java环境
sudo mkdir -p /usr/local/java
将安装包放入该目录下,即/usr/local/java/jdk-8u221-linux-x64.tar.gz
进入该目录并解压安装包
cd /usr/local/java
sudo tar xvzf jdk-8u221-linux-x64.tar.gz
解压成功之后便有路径/usr/local/java/jdk1.8.0_221/
接下来需要配置环境变量,在文件/etc/profile末尾添加如下内容
JAVA_HOME=/usr/local/java/jdk1.8.0_221 PATH=$PATH:$HOME/bin:$JAVA_HOME/bin export JAVA_HOME export PATH
告诉系统java jdk的位置
sudo update-alternatives --install "/usr/bin/java" "java" "/usr/local/java/jdk1.8.0_221/bin/java" 1 sudo update-alternatives --install "/usr/bin/javac" "javac" "/usr/local/java/jdk1.8.0_221/bin/javac" 1 sudo update-alternatives --install "/usr/bin/javaws" "javaws" "/usr/local/java/jdk1.8.0_221/bin/javaws" 1
将其设置为默认方式
sudo update-alternatives --set java /usr/local/java/jdk1.8.0_221/bin/java sudo update-alternatives --set javac /usr/local/java/jdk1.8.0_221/bin/javac sudo update-alternatives --set javaws /usr/local/java/jdk1.8.0_221/bin/javaws
重新加载环境变量
source /etc/profile
检验是否安装成功
java -version
[out]
java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)
4 - 配置hadoop环境
首先下载hadoop安装包,可以去网站下载,注意带src的是源码,需要编译,这里选择的是编译好的版本hadoop-2.6.5.tar.gz
将安装包解压到路径/usr/local
sudo tar -zxf hadoop-2.6.5.tar.gz -C /usr/local
重命名并修改权限
cd /usr/local sudo mv ./hadoop-2.6.5/ ./hadoop
sudo chown -R czifan ./hadoop
将hadoop配置到环境变量里面,方面以后的运行
打开/etc/bash.bashrc,在末尾添加如下内容
export JAVA_HOME=/usr/local/java/jdk1.8.0_221 export JRE_HOME=${JAVA_HOME}/jre export HADOOP_HOME=/usr/local/hadoop export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${JAVA_HOME}/bin:${HADOOP_HOME}/bin:${HADOOP_HOME}/sbin:$PATH
执行下述命令重载环境变量配置
source /etc/bash.bashrc
执行如下命令进行验证
hadoop version
有如下提示表示安装成功,安装成功即是hadoop的单机模式
Hadoop 2.6.5 Subversion Unknown -r Unknown Compiled by root on 2017-05-24T14:32Z Compiled with protoc 2.5.0 From source with checksum f05c9fa095a395faa9db9f7ba5d754 This command was run using /usr/local/hadoop/share/hadoop/common/hadoop-common-2.6.5.jar
这里可以测试以下单机配置,执行如下命令(默认在/usr/local/hadoop路径下),可以看到hadoop内置的例子
cd /usr/local/hadoop
hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.5.jar
选取一个例子进行测试,执行如下命令
sudo mkdir ./input
sudo cp ./etc/hadoop/*.xml ./input
ls ./input hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.5.jar grep ./input/ ./out 'dfs[a-z.]+'
查看输出
cat ./out/*
[out] 1 dfsadmin
这里需要注意,hadoop默认不会覆盖结果,如果再次运行将会报错,所以需要删除输出结果(输入也顺带删掉,避免混乱)
sudo rm -r ./out ./input
5 - 配置伪分布式
hadoop的运行方式是由配置文件决定的,因此在搭建伪分布式的时候需要修改相应的配置文件。
首先编辑/usr/local/hadoop/etc/hadoop/core-site.xml文件,内容如下
<configuration>
<property>
<name>hadoop.tmp.dir</name>
<value>/usr/local/hadoop/tmp</value>
<description>Abase for other temporary directories.</description>
</property>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value>
</property>
</configuration>
其中hdfs://localhost:9000指明了使用的文件系统
然后编辑/usr/local/hadoop/etc/hadoop/hdfs-site.xml文件,内容如下
<configuration> <property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/usr/local/hadoop/tmp/dfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/usr/local/hadoop/tmp/dfs/data</value> </property> </configuration>
dfs.replication指备份的份数。这里指定了dfs.namenode.name.dir和dfs.datanode.data.dir的原因在于如果不指定,hadoop会使用临时目录/tmp/hadoop-hadoop,而这个目录在重启时有可能会被系统清理掉,从而导致需要重新执行下面要介绍的格式化(format),而会产生一系列的不方便。
配置文件编辑好之后,进行namenode的格式化
hdfs namenode -format
注意到,在每一次格式化时会为namenode生成一个新的namespaceID,如果多次对namenode进行format,hadoop.tmp.dir目录下的namespaceID并不会更新,会因为namespaceID不一致而影像后续配置,因此在第2-n次对namenode进行format之前,需要先删除/usr/local/hadoop/tmp/dfs目录下的data!!!
开启namenode和datanode的守护进程
start-dfs.sh
注意,如果开启的时候报错"localhost: Error: JAVA_HOME is not set and could not be found.",则在/usr/local/hadoop/etc/hadoop/hadoop-env.sh文件中添加如下内容然后重新执行start-dfs.sh启动即可
# Set Hadoop-specific environment variables here. # The only required environment variable is JAVA_HOME. All others are # optional. When running a distributed configuration it is best to # set JAVA_HOME in this file, so that it is correctly defined on # remote nodes. # The java implementation to use.
export JAVA_HOME=/usr/local/java/jdk1.8.0_221
验证
jps
[out]
7973 SecondaryNameNode
7783 DataNode
7676 NameNode
8078 Jps
同时出现上面是个即成功
- 如果没有出现SecondaryNameNode,运行stop-dfs.sh关闭进程之后再运行start-dfs.sh重新启动,再用jps测试
- 如果没有DataNode,可能是虚拟机出现了“假死”情况,重启虚拟机,开启start-dfs.sh后再用jps进行测试;同时这种情况也可能是上述的多次格式化没有删除data文件夹的缘故
用例子测试伪分布式。伪分布式和单机的区别在于,需要采用hdfs文件管理系统管理文件。
首先在hdfs中创建用户目录
hdfs dfs -mkdir -p /user/hadoop
创建输入文件夹
hdfs dfs -mkdir /user/hadoop/input
将hadoop自带的例子的input相关文件复制到输入文件夹
hdfs dfs -put /usr/local/hadoop/etc/hadoop/*.xml /user/hadoop/input
hdfs dfs -ls /user/hadoop/input
运行例子进行运算
hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.6.5.jar grep /user/hadoop/input output 'dfs[a-z]+'
查看结果
hdfs dfs -cat output/*
[out] 1 dfsadmin
输出和单机配置时候一样!
6 - 搭建集群
伪分布式是在一个机器中模拟多个节点,而实际过程中往往需要多台机器来构成分布式计算系统,这一小节需要在之前伪分布的基础上采用两台虚拟机搭建集群,分别是主节点Master和从节点Slave1。
为了方便,可以直接利用VM的克隆功能将上面伪分布式的虚拟机进行克隆,途径是“右键已存在虚拟机→管理→克隆”。
将上述虚拟机克隆出两个虚拟机,一个命名为Master,另一个命名为Slave1。
同时配置Master和Slave1。
(注:下述[M]表示在Master中的操作,[S]表示在Slave1中的操作,---->表示修改的意思)
修改/etc/hostname内容重命名虚拟机名称:
[M] localhost ----> Master
[S] localhost ----> Slave1
修改/etc/hosts内容:
[M] 127.0.0.1 localhost ----> 127.0.0.1 Master
[M] 添加一行: Slave1的ip地址 Slave1
[S] 127.0.0.1 localhost ----> 127.0.0.1 Slave1
[S] 添加一行: Master的ip地址 Master
(ip地址可以通过ifconfig命令查看)
配置ssh使得Master和Slave1之间可以无密码登陆。
注意到,如果采用伪分布式的虚拟机,我们修改了ssh_config的配置,现在需要多机器之间交互,需要把配置修改回去,打开/etc/ssh/ssh_config文件,如果存在下述两行,将其删掉(Master和Slave1都需要此操作):
StrictHostKeyChecking no UserKnownHostsFile /dev/null
配置ssh:
[M] cd ~/.ssh [M] ssh-keygen -t rsa [M] cat ./id_rsa.pub >> ./authorized_keys [M] ssh-copy-id -i ~/.ssh/id_rsa.pub czifan@Slave1
[S] cd ~/.ssh
[S] ssh-keygen -t rsa
[S] cat ./id_rsa.pub >> ./authorized_keys
[S] ssh-copy-id -i ~/.ssh/id_rsa.pub czifan@Master
若上述过程出现询问"(yes/no)",键入"yes"回车即可。
完成ssh配置之后,Master和Slave1之间应该可以ping通!可以用ping检验一下。
而后需要修改下Master和Slave1的hadoop配置文件。
Master和Slave1都修改/usr/local/hadoop/etc/hadoop/slaves,将原来的localhost删除,添加两行,分别是Master和Slave1:
localhost ----> Master Slave1
Master和Slave1都修改/usr/local/hadoop/etc/hadoop/core-site.xml如下:
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://Master:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>file:/usr/local/hadoop/tmp</value> <description>Abase for other temporary directories.</description> </property> </configuration>
Master和Slave1都修改/usr/local/hadoop/etc/hadoop/hdfs-site.xml如下:
<configuration> <property> <name>dfs.namenode.secondary.http-address</name> <value>Master:50090</value> </property> <property> <name>dfs.replication</name> <value>2</value> </property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/usr/local/hadoop/tmp/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/usr/local/hadoop/tmp/dfs/data</value>
</property> </configuration>
Master和Slave1都先复制一个mapred-site.xml.template为mapred-site.xml如下:
cp /usr/local/hadoop/etc/hadoop/mapred-site.xml.template /usr/local/hadoop/etc/hadoop/mapred-site.xml
再对其进行修改,如下:
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>mapreduce.jobhistory.address</name> <value>Master:10020</value> </property> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>Master:19888</value> </property> </configuration>
Master和Slave1都修改/usr/local/hadoop/etc/hadoop/yarn-site.xml如下:
<configuration> <property> <name>yarn.resourcemanager.hostname</name> <value>Master</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> </configuration>
然后在Master和Slave1上都执行下述指令来修改权限:
sudo chown -R czifan:czifan /usr/local/hadoop/
然后需要在Master节点下完成对NameNode的初始化,注意到,我们在搭建伪分布式的时候提到第2-N次format的时候需要先删除/usr/local/hadoop/tmp/dfs下的data文件夹。由于我们是克隆伪分布式虚拟机的结果,因此需要在Master和Slave1上都运行如下命令:
sudo rm -r /usr/local/hadoop/tmp/dfs/data
而后对Master上的NameNode进行初始化,如下:
[M] hdfs namenode -format
启动hadoop,在Master上执行如下命令:
start-dfs.sh
start-yarn.sh
mr-jobhistory-daemon.sh start historyserver
输入jps命令验证,如果有如下输出,则集群搭配成功!
[M] jps
输出:
DataNode
ResourceManager
JobHistoryServer
Jps
SecondaryNameNode
NameNode
NodeManager
[S] jps
输出
DataNode
Jps
NodeManager
7 - 搭建IDEA开发环境
hadoop需要将编写的程序打包成jar包。这里选用的开发环境为IDEA+gradle,IDEA从官网下载安装即可。何为gradle?可看此文章,简单说就是一个统一方便的编译工具。注意,老版本的IDEA可能需要自己安装gradle,新版本的都已经集成好了无需额外安装。
使用IDEA创建gradle项目
修改build.gradle文件中的repositories如下,换成国内源在导包的时候可以快很多!
repositories { maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } }
在build.gradle文件中修改dependencies如下,导入hadoop需要的包
dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' compile group: 'org.apache.hadoop', name: 'hadoop-mapreduce-client-core', version: '2.6.5' compile group: 'org.apache.hadoop', name: 'hadoop-common', version: '2.6.5' compile group: 'org.apache.hadoop', name: 'hadoop-client', version: '2.6.5' }
在build.gradle文件中添加如下内容,为后续自动打包配置(其中的XXX请替换成对应的工程名和类名)
jar { baseName 'XXX' String appMainClass = 'XXXX' manifest { attributes 'Main-Class': appMainClass } }
在代码写好之后,从IDEA右侧的Gradle菜单中找到路径“YourProjectName/Tasks/build”中的jar,运行即可自动打包,打包结果存储在项目的build文件夹中。
8 - 参考资料
https://blog.csdn.net/weixin_42001089/article/details/81865101
https://blog.csdn.net/sinat_41464121/article/details/82895297
mirrors.ustc.edu.cn/ubuntu-releases/16.04/
https://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html
https://www.cnblogs.com/xiaostudy/p/9940167.html
https://baijiahao.baidu.com/s?id=1621983882899369902&wfr=spider&for=pc
https://blog.csdn.net/beishanyingluo/article/details/97675724
http://archive.apache.org/dist/hadoop/common/