Ubuntu虚拟机配置hadoop集群--学习笔记

在这里插入图片描述

  1. 虚拟机创建,常用软件与阿里云环境的配置,参考【刚创建ubuntu 16.04虚拟机必备设置与软件】
  2. JDK和hadoop环境配置,参考【hadoop开发环境配置】

【注】本篇博客默认虚拟机已经安装好、相关必要的软件已经安装好、jdk、hadoop已经安装好并且配置好的环境变量(满足这4个条件即可)。

现在你的手中只有一台虚拟机,我一开始也是,将一台配置好了之后再克隆,可以免掉很多的工作量。现在假装你正在使用的虚拟机的主机名为hadoop100

虚拟机ip配置

首先安装模板虚拟机,该虚拟机的主机名为hadoop100。

配置虚拟机的ip

点击编辑->虚拟网络编辑器:
在这里插入图片描述
选中VMnet8->更改配置:
在这里插入图片描述)
重新选中VMnet8,将子网ip改成192.168.10.0(常用),子网掩码改为255.255.255.0(常用),然后点击NAT设置:
在这里插入图片描述

将网关改为192.168.10.2(常用),然后保存:
在这里插入图片描述

修改windows的VMnet8

依次点击:设置->网络和Internet->以太网->更改适配器
在这里插入图片描述
右键VMnet8->属性:
在这里插入图片描述
双击箭头指向:
在这里插入图片描述
改成如下配置:
在这里插入图片描述
保存即可,如果windows中的VMnet8没有出来,点击虚拟机的虚拟网络编辑器,点击还原默认设置即可:
在这里插入图片描述

登录虚拟机设置ip

编辑文件/etc/network/interfaces,添加如下内容(注意,这里的address是192.168.10.102,因为我打开的是另外一台虚拟机,复制过来的,如果是你正在配置模板虚拟机的话,应该是192.168.10.100):

# static ip
auto ens33
iface ens33 inet static
address 192.168.10.102
netmask 255.255.255.0
gateway 192.168.10.2
dns-nameserver 8.8.8.8
dns-nameserver 8.8.4.4
dns-nameserver 192.168.10.2

在这里插入图片描述
可能你修改的是这个文件/etc/resolv.conf,但是发现每一次重启之后文件都将你之前添加的内容清除了,所以可以修改上面说的那个文件。修改之后执行sudo service networing restart即可联网。这里的ens33可以输入ifconfig查看你的网卡是不是这个,比如我的是:
在这里插入图片描述

此时输入ifconfig可以看见自己的ip变成了自己修改的内容,参见上面的图片。测试联网:
ping www.baidu.com
如果现实接收数据报说明配置成功,否则应该是上面的某个步骤出了问题。

还有不明白的可以参考这篇博客:
【Ubuntu系统重启后/etc/resolv.conf内容丢失】

修改/etc/hostname和/etc/hosts文件

hostname存放的是当前虚拟机的主机名,hosts文件将要配置ip映射。
目前使用的hadoop100是模板主机,其主机名就是hadoop100,所以暂时不修改hostname文件,打开hosts文件,添加如下内容:

192.168.10.100 hadoop100
192.168.10.101 hadoop101
192.168.10.102 hadoop102
192.168.10.103 hadoop103
192.168.10.104 hadoop104

并将这一行注释掉:
在这里插入图片描述

克隆虚拟机

一共需要克隆三台,主机名分别为:hadoop102, hadoop103, hadoop104.
关闭虚拟机,右键->管理->克隆:
在这里插入图片描述
创建完整克隆:
在这里插入图片描述

等待克隆完成,需要将这三台克隆完成的虚拟机修改如下内容:

  1. 修改/etc/hostname和/etc/network/interfaces文件,前者是主机名,三台克隆虚拟机分别设置为:hadoop102,hadoop103,hadoop104。后者只需要修改address即可:
    在这里插入图片描述
    分别修改为:
    192.168.10.102
    192.168.10.103
    192.168.10.104
    重启即可看到主机名变化,然后也可以测试一下ping外网。接下来的步骤用不上hadoop100了,可以关闭。后面的步骤都先在hadoop102中配置好,然后分发给其他的结点。

安装jdk和hadoop

这一步骤在上一篇博客已经介绍了,就不重复说了。
但是需要注意的一点是,之前配置环境变量都是在/etc/profile文件中配置的,为了更好管理,可以自己新建一个文件:/etc/profile.d/my_env.sh,然后在这个文件里配置,配置完成之后source /etc/profile即可。因为每一次操作都会自动加载/etc/profile.d下的全部文件。

如果你在克隆之前已经安装了,那么克隆之后的虚拟机里都有jdk和hadoop,如果还没安装,那么先只用在hadoop102中安装,然后将jdk文件和hadoop文件全部转发给剩余的集群结点即可。

编写集群分发脚本xsync

scp 是 secure copy 的简写,用于在 Linux 下进行远程拷贝文件,类似于 cp 命令,不过 cp 只能在本机中拷贝。
rsync指令和scp的区别:前者只传差异文件,后者不论是否有差异都传。
切换到/home/bin目录下:
cd ~/bin
新建一个文件:
touch xsync
将如下内容复制进去:

#!/bin/bash

#1.判断参数个数
if [ $# -lt 1 ]
then
    echo Not Enough Argument!
    exit;
fi

#2.遍历集群所有机器
for host in hadoop102 hadoop103 hadoop104
do
    echo ===================== $host =========================
    #3. 遍历所有目录,挨个发送
    for file in $@
    do
        #4.判断文件是否存在
        if [ -e $file ]
            then
                #5.获取父目录
                pdir=$(cd -P $(dirname $file); pwd)

                #6.获取当前文件名称
                fname=$(basename $file)
                ssh $host "mkdir -p $pdir"
                rsync -av $pdir/$fname $host:$pdir
            else
                echo $file does not exists!
        fi
    done
done

然后为这个文件赋予执行权限:
chmod +x xsync
尝试将这个文件分发给其他的结点:

cd ..
xsync bin/

分别执行上面两句指令之后,可以去其他的结点相应的路径查看,文件已经分发成功。

为什么要在这个路径下~/bin创建这个文件呢?首先这个目录是空的,我们用户自己创建的执行文件,最重要的是,输入echo $PATH发现环境变量有这个路径:
在这里插入图片描述
这就意味着在哪个地方都可以直接执行xsync [filename],如果你输echo $PATH没有这个路径,可以输入下面格式的指令添加:
PATH=$PATH:/home/hostname/bin

这个分发的文件配置好了,就可以将你的jdk和hadoop文件夹以及my_env.sh分发给其他的结点了(如果其他结点没有的话),记得如果当前路径和需要分发的文件不是在同一目录下的时候要输入绝对路径。

ssh免密登录(凡是涉及到user的根据自己的用户名来更改)

cd .ssh
如果报错,先执行:ssh localhost
在hadoop102下执行:

cd ~/.ssh               # 如果没有该目录,先执行一次ssh localhost
rm ./id_rsa*            # 删除之前生成的公匙(如果有)
ssh-keygen -t rsa       # 一直按回车就可以

让hadoop102能无密码登录本机:
cat ./id_rsa.pub >> ./authorized_keys
然后可以执行ssh hadoop102验证一下。
将hadoop102上的公钥传给其他的结点:

scp ~/.ssh/id_rsa.pub user@hadoop103:/home/user/
scp ~/.ssh/id_rsa.pub user@hadoop104:/home/user/

需要输入用户密码的时候输入即可。
接着在hadoop103、hadoop104 节点上,将 ssh 公匙加入授权:

mkdir ~/.ssh       # 如果不存在该文件夹需先创建,若已存在则忽略
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
rm ~/id_rsa.pub    # 用完就可以删掉了

然后就可以各个结点之间互相ssh无秘连接试试了,如果还需要密码,检查上述步骤是否有误。

还有第二种添加id的方式,这种方式比较繁琐,如果结点一多,嗯。所以还是建议上面的方法。第二种方式为:
执行:

ssh-copy-id master
ssh-copy-id hadoop1
ssh-copy-id hadoop2
ssh-copy-id hadoop3

以上的每一步在每一个虚拟机都执行
检验是否成功:(每一台都可以执行)

ssh master
exit
ssh hadoop1
exit
ssh hadoop2
exit
ssh hadoop3
exit

如果不需要输入密码就可以登录就算成功了。

集群部署

部署规划:
在这里插入图片描述
需要注意如下几点:

  • NameNode和SecondaryNameNode不要安装在同一台服务器
  • ResourceManager也很消耗内存,不要和NameNode、SecondaryNameNode配置在同一台机器上。

需要配置的文件

每一个文件中配置信息凡是涉及到/app-hadoop/hadoop3.1.4的路径需要改成自己的hadoop所在的路径。

core-site.xml

这个文件中有/app-hadoop/hadoop3.1.4,需要修改

<configuration>
 <!--指定NameNode的地址-->
 <property>
  <name>fs.defaultFS</name>
  <value>hdfs://hadoop102:8020</value>
 </property>
 <!--指定hadoop数据的存储目录-->
 <property>
  <name>hadoop.tmp.dir</name>
  <value>/app-hadoop/hadoop-3.1.4/data</value>
 </property>
 <!-- 配置 HDFS 网页登录使用的静态用户为 wangxiaolong (非必须,可以不要)-->
 <property>
  <name>hadoop.http.staticuser.user</name>
  <value>wangxiaolong</value>
 </property>
</configuration>

hdfs-site.xml

<configuration>
 <!--nn web端访问地址-->
 <property>
  <name>dfs.namenode.http-address</name>
  <value>hadoop102:9870</value>
 </property>
 <!--2nn web端访问地址-->
 <property>
  <name>dfs.namenode.secondary.http-address</name>
  <value>hadoop104:9868</value>
 </property>
<!-- 当集群结点小于等于3,写文件操作容易出错,所以添加以下内容 -->
<property>
	<name>dfs.client.block.write.replace-datanode-on-failure.enable</name>
	<value>true</value>
</property>
<property>
	<name>dfs.client.block.write.replace-datanode-on-failure.policy</name>
	<value>NEVER</value>
</property>

<property>
	<name>dfs.client.block.write.replace-datanode-on-failure.best-effort</name>
	<value>false</value>
</property>
<!--hdfs 读写权限设定-->
<property>
  <name>dfs.permissions.enabled</name>
  <value>false</value>
  <description>
    If "true", enable permission checking in HDFS.
    If "false", permission checking is turned off,
    but all other behavior is unchanged.
    Switching from one parameter value to the other does not change the mode,
    owner or group of files or directories.
  </description>
</property>
</configuration>

yarn-site.xml

<configuration>
 <!--指定MR走shuffle -->
 <property>
  <name>yarn.nodemanager.aux-services</name>
  <value>mapreduce_shuffle</value>
 </property>
 <!--指定ResourceManager的地址-->
 <property>
  <name>yarn.resourcemanager.hostname</name>
  <value>hadoop103</value>
 </property>
 <!--环境变量的继承-->
 <property>
  <name>yarn.nodemanager.env-whitelist</name>
  <value>JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,CLASSPATH_PREPEND_DISTCACHE,HADOOP_YARN_HOME,HADOOP_MAPRED_HOME</value>
 </property>
 <!--开启日志聚集功能-->
  <property>
   <name>yarn.log-aggregation-enable</name>
   <value>true</value>
  </property>
 <!--设置日志聚集服务器地址-->
  <property>
   <name>yarn.log.server.url</name>
   <value>http://hadoop102:19888/jobhistory/logs</value>
  </property>
 <!--设置日志保留时间为7天-->
  <property>
   <name>yarn.log-aggregation.retain-seconds</name>
   <value>604800</value>
  </property>
</configuration>

mapred-site.xml

<configuration>
 <!--指定MapReduce程序运行在Yarn上-->
  <property>
   <name>mapreduce.framework.name</name>
   <value>yarn</value>
  </property>
 <!--历史服务器端地址-->
 <property>
  <name>mapreduce.jobhistory.address</name>
  <value>hadoop102:10020</value>
 </property>
 <!--历史服务器web端地址-->
 <property>
  <name>mapreduce.jobhistory.webapp.address</name>
  <value>hadoop102:19888</value>
 </property>
</configuration>

hadoop-env.sh

将你配置环境变量时的jdk路径放进去即可,比如我的是JAVA_HOME=/app-hadoop/jdk1.8.0_281

yarn-env.sh

将你配置环境变量时的jdk路径放进去即可,比如我的是JAVA_HOME=/app-hadoop/jdk1.8.0_281

mapred-env.sh

将你配置环境变量时的jdk路径放进去即可,比如我的是JAVA_HOME=/app-hadoop/jdk1.8.0_281

wokers

这个文件在之前的版本中是slaves文件,后来改成了workers。
添加结点的主机名:

hadoop101
hadoop102
hadoop103

最后分发文件:

cd etc/
xsync hadoop/

Hadoop Startup:

  1. 将新的分布式文件系统格式化为hdfs
    bin/hdfs namenode -format
    如果你弄了伪分布式或者本地的,先将{hadoop}/data和{hadoop}/logs删除掉。格式化的指令只用在第一次启动集群的时候执行即可。如果遇到了某一次自己的namenode没有启动,不要慌,将这两个目录删除,然后重新执行格式化即可。下图中data/和/input/还有logs/不是安装hadoop自带的,input是我自己创建的。
    在这里插入图片描述

  2. all of the HDFS processes can be started with a utility script(原文更加原汁原味)
    sbin/start-dfs.sh

  3. 不使用了记得关闭:sbin/stop-dfs.sh
    如果强制关机,可能造成下一次开启的时候有的必须的结点无法启动如namenode。
    开启之后,输入:
    hdfs dfsadmin -report看看live datanodes是不是和自己设置的workers结点数量相同:
    在这里插入图片描述
    如果没有,检查你的workers文件和/etc/hosts文件是否正确。

上面提到的启动dfs的指令可以在任意一台虚拟机上执行,下面总结一下常用的启动、关闭服务的指令:

sbin/start-dfs.sh  # 任意虚拟机均可执行
sbin/start-yarn.sh  # 只能在hadoop103中执行(yarn-site.xml文件中的配置决定)
bin/mapred --daemon start historyserver  # hadoop102中执行
bin/mapred --daemon stop historyserver  # hadoop102中执行
sbin/stop-yarn.sh  # 只能在hadoop103中执行(yarn-site.xml文件中的配置决定)
sbin/stop-dfs.sh  # 任意虚拟机均可执行

上面如果想都启动的话,要按顺序启动,对于每一条指令的含义解释如下:

# 整体启动/停止HDFS:
start-dfs.sh/stop-dfs.sh
# 整起启动/停止YARN
start-yarn.sh/stop-yarn.sh
# 各个服务器组件逐一启动/停止
# (1) 分别启动/停止HDFS组件
hdfs --daemon start/stop namenode/datanode/secondarynamenode
# (2) 启动/停止YARN
yarn --daemon start/stop resourcemanager/nodemanager

常用网址:

hadoop102:9870
# 历史服务器:
hadoop102:19888
# 查看正在执行的任务:
hadoop103:8088

检查是不是所有的结点都可以访问hdfs:

每一个虚拟机都执行:
hadoop fs -ls /
如果报错了,检查你的/etc/hosts文件是否正确。

常用脚本

  1. 每一次启动的时候,如果想启动hdfs、资源管理结点、历史服务器,那得每一次都去一个一个启动,关闭的时候一个一个关闭,很麻烦,下面的脚本可以解决这个问题:
    在~/bin目录下创建一个文件:myhadoop.sh,内容如下(记得改路径):
#!/bin/bash
if [ $# -lt 1 ]
	then
		echo "No Args Input..."
		exit ;
fi
case $1 in
"start")
	echo " =================== 启动hadoop集群==================="
	echo " ---------------启动hdfs ---------------"
	ssh hadoop102 "/app-hadoop/hadoop-3.1.4/sbin/start-dfs.sh"
	echo " ---------------启动yarn ---------------"
	ssh hadoop103 "/app-hadoop/hadoop-3.1.4/sbin/start-yarn.sh"
	echo " ---------------启动historyserver ---------------"
	ssh  hadoop102  "/app-hadoop/hadoop-3.1.4/bin/mapred --daemon  start historyserver"
;;
"stop")
	echo " =================== 关闭hadoop集群==================="
	echo " ---------------关闭historyserver ---------------"
	ssh  hadoop102  "/app-hadoop/hadoop-3.1.4/bin/mapred --daemon  stop historyserver"
	echo " ---------------关闭yarn ---------------"
	ssh hadoop103 "/app-hadoop/hadoop-3.1.4/sbin/stop-yarn.sh"
	echo " ---------------关闭hdfs ---------------"
	ssh hadoop102 "/app-hadoop/hadoop-3.1.4/sbin/stop-dfs.sh"
;;
*)
	echo "Input Args Error..."
;;
esac

为该脚本赋予执行权限:
chmod 777 myhadoop.sh
启动:myhadoop.sh start
关闭:myhadoop.sh stop
但是结果会报错:
在这里插入图片描述
错误的原因参考这篇博客:【SSH远程执行脚本报错command not found和环境变量问题】

  1. 为了查看结点的启动情况,每一次都得一个一个执行jps,很麻烦,用如下的脚本可以解决问题,创建一个脚本名为:jpsall,内容如下:
#!/bin/bash
for host in hadoop102 hadoop103 hadoop104
do
	echo =============== $host ===============
	ssh $host jps 
done

为该脚本赋予执行权限:
chmod 777 jpsall
使用:jpsall

注意,这里你可能会得到这样的错误:
在这里插入图片描述

解决方法:

参见这篇博客:【解决ssh ltt3.bg.cn ‘jps’ bash: jps: command not found 问题】

走坑过程:

为什么报错?参照这篇博客:【解决ssh ltt3.bg.cn ‘jps’ bash: jps: command not found 问题】
按照博客说的,输入ssh hadoop102 '$PATH'得到:
在这里插入图片描述
确实这里的环境变量有问题,我一开始的想法是,将~/bin目录下自己创建的脚本移动到/usr/local/bin中:sudo mv ~/bin/* /usr/local/bin,重新执行jpsall,报错:
在这里插入图片描述
没办法,只得将文件移动回去。。。

常用端口号总结

hadoop3.x

  • HDFS NameNode 内部通讯端口:8020/9000/9820
  • HDFS NameNode 对用户的查询端口:9870
  • Yarn查看任务运行情况:8088
  • 历史服务器:19888

hadoop2.x

  • HDFS NameNode 内部通讯端口:8020/9000
  • HDFS NameNode 对用户的查询端口:50070
  • Yarn查看任务运行情况:8088
  • 历史服务器:19888

常用的配置文件总结

hadoop3.x

core-site.xml hdfs-site.xml yarn-site.xml mapred-site.xml workers

hadoop2.x

core-site.xml hdfs-site.xml yarn-site.xml mapred-site.xml slaves

常见错误总结:

防火墙没关闭、或者没有启动YARN

报错信息:INFO client.RMProxy: Connecting to ResourceManager at hadoop108/192.168.10.108:8032

root用户和user用户启动集群不统一

一会儿用root启动,一会儿用非root用户启动:统一使用非root用户启动。

DataNode和NameNode进程同时只能启动一个

原因:新生成的clusterid和之前的clusterid不一致。
解决方法:格式化之前,先杀死所有的namenode和datanode进程,然后删除DataNode里面的信息(默认在/tmp,如果配置了该目录,就去自己配置的目录下删除数据。比如我就改到了{hadoop}/data里。),删除记得将所有的结点都要删除一遍,除了删除{hadoop}/data之外,还要删除{hadoop}/logs目录。删除之后重新格式化主节点:
hdfs namenode -format
然后启动集群:
sbin/start-dfs.sh

jps发现进程已经没有,但是重启集群,提示进程已开启

原因是linux跟目录下/tmp目录中存在启动的进程临时文件,将集群相关的进程删除掉,再重新启动集群。

8088端口连接不上

vi /etc/hosts注释掉第二行:
在这里插入图片描述

在用户查询端口(9870)手动删除文件无权限

在这里插入图片描述

解决方案:
打开core-site.xml文件,在底部添加如下的内容(这里的用户admin需要改成你自己的用户名):

<!-- 配置 HDFS 网页登录使用的静态用户为 admin -->
 <property>
  <name>hadoop.http.staticuser.user</name>
  <value>admin</value>
 </property>

在这里插入图片描述
然后分发:
xsync core-site.xml
如果此时你的集群是开启的,需要重新启动集群才能生效。

遇到的坑:

  1. 第一个坑是xsync一直用不了,一开始我以为是环境变量的问题,但是环境变量配了又配还是一直报错,具体报错是,如果用:xsync hadoop/就提示没权限,如果是sudo xsync hadoop就说找不到命令,因为使用sudo就是在root用户下执行的,而在root用户下是没有这个脚本的。参考了很多文章都没用,有的说/etc/sudoers文件中的secure_path有问题,但是根据他说的改了还是老样子,最后意识到是不是执行权限的问题,然后为xsync文件添加执行权限就可以了,指令前面有说到。
  2. hadoop mapreduce 出现 /bin/bash: /bin/java: No such file or directory,参考这篇博客:【参考】
  3. 如下图所示:运行mapreduce超内存:
    在这里插入图片描述
    可以尝试修改配置文件增加内存:【Container killed on request. Exit code is 143】

或者测试的时候使用小一点的文件即可。

  1. 上方所述的ssh hadoop102 jps报错问题。

参考:

【林子雨hadoop单机配置】
【林子雨hadoop集群配置】
【Ubuntu16.04修改ip、DNS、网关】
【Ubuntu系统重启后/etc/resolv.conf内容丢失】
【Ubuntu Linux Restart Network Service】
【Ubuntu输入su提示认证失败的解决方法】
【集群服务器的同步xsync命令使用】
【Hadoop集群安装配置教程_Hadoop3.1.3_Ubuntu】
【Hadoop集群部署】
【HDFS 集群无法启动 DataNode 节点以及管理界面缺少 DataNode 节点的解决方法】
【http://dblab.xmu.edu.cn/blog/2775-2/】
【ubuntu下重新安装openssh-server】
【centos7搭建hadoop集群之rsync和xsync】
【配置hadoop集群时,ssh无密码登陆设置(各个主机的用户名需要一样)】
【https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-common/ClusterSetup.html】
【Hadoop 添加数据节点(datanode)】
【三节点(Master、Slave1、Slave2)Hadoop集群的配置(Ubuntu)】
【Linux-centos7配置hadoop完全分布式集群搭建步骤】
【Hadoop: 主节点9000端口拒绝访问Call From hadoop3/192.168.91.132 to hadoop1:9000 failed on connection exception】
【Ubuntu etc/hosts 文件】
【ssh连接远程主机执行脚本的环境变量问题】
【SSH远程执行脚本报错command not found和环境变量问题】

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值