本次课设所使用的操作系统是华为的openEluer。
主节点部署
本次演示中,我创建了三台服务器,在创建华为云服务器的之后一定要注意创建的服务器在同一个区域下的同一个可用区,比如我的是华南-广州的可用区5.本次演示所创建的三台服务器的主机名分别为:hadoop102, hadoop103, hadoop104.每一台主机中的用户root的密码均为Aaaa1111@。
创建hadoop用户
这一步最好做一下,因为hadoop内部默认的用户名是hadoop,如果你是root,那么可能发生本文最下方的报错,可能后面还会带来一些莫名其妙的问题,所以建议这一步做一下。但是这一步执行之后,请注意每一步中的操作需要修改的地方,由于本次实验中没有创建hadoop用户,所以使用的用户是root,有些地方需要修改为你当前的用户hadoop。
创建用户:
sudo useradd -m hadoop -s /bin/bash
设置密码,可简单设置为 hadoop,按提示输入两次密码:
sudo passwd hadoop
密码统一设置为Aaaa1111@
hadoop 用户增加管理员权限,方便部署:
sudo adduser hadoop sudo
用hadoop用户登录
su - hadoop #切换当前用户为用户hadoop
分别运行上面命令后,系统中创建一个用户名为hadoop的用户,该用户拥有管理员权限,并使用hadoop用户登录当前系统。
安装最新版本的Java(如果服务器已经预先安装了java就不需要进行这一步,命令行中输入java验证是否安装)
更新软件列表
sudo yum update
安装openjdk-8-jdk
sudo yum install openjdk-8-jdk
查看Java版本,如下:
java -version
安装好 OpenJDK 后,需要找到相应的安装路径
update-alternatives --config java
我们输出的路径为
取绝对路径:
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-1.h5.oe1.aarch64
接着配置 JAVA_HOME 环境变量,先新建一个profile.d/my_env.sh:
vi /etc/profile.d/my_env.sh
添加如下内容(注意 = 号前后不能有空格)并保存:
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-1.h5.oe1.aarch64
export JRE_HOME=$JAVA_HOME/jre
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib
让该环境变量生效
source /etc/profile
设置好后我们来检验一下是否设置正确:
echo $JAVA_HOME # 检验变量值
java -version
$JAVA_HOME/bin/java -version # 与直接执行 java -version 一样
Hadoop下载与环境配置
先下载:(如果速度慢可以先下载到本地,然后拖过去)
wget https://mirrors.bfsu.edu.cn/apache/hadoop/common/hadoop-3.3.0/hadoop-3.3.0-aarch64.tar.gz
解压:
sudo tar -zxvf hadoop-3.3.0-aarch64.tar.gz -C /root/apps
cd /root/apps
sudo mv hadoop-3.3.0 hadoop #重命名为hadoop
# 如果当前用户为hadoop,需要修改用户权限,root不需要
sudo chown -R hadoop ./hadoop #修改文件权限
配置Hadoop环境
vi /etc/profile.d/my_env.sh
将如下内容添加到该文件中:
export HADOOP_HOME=/root/apps/hadoop
export CLASSPATH=$($HADOOP_HOME/bin/hadoop classpath):$CLASSPATH
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
激活环境:
source /etc/profile
使用单机实例测试一下
进入 /tool/apps/hadoop/ 目录,运行以下命令后,查看运行结果,并分析结果。
cd /root/apps/hadoop/
mkdir input
cp etc/hadoop/*.xml input
bin/hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.0.jar grep input output 'dfs[a-z.]+'
cat output/*
输出如下:
Hadoop集群部署
集群配置之前,先把主节点的部分配置好,然后直接分发给从节点即可。从节点只需要下载jdk,hadoop(甚至可以将hadoop分发给从节点),其他不需要配置。
部署规划:
需要配置的文件
需要配置的文件均在这个目录下:
/root/apps/hadoop/etc/hadoop
core-site.xml
将下面的xml内容放入这个文件当中,替换下面框柱的那段内容:
这个文件中的最后一个配置项中的hadoop.http.staticuser.user对应的value应该选用当前的用户,如果你的用户是hadoop,就改成hadoop。如果当前的用户是hadoop,那么这里最后配置HDFS网页登录使用的静态用户那里需要改成hadoop
<configuration>
<!--指定NameNode的地址-->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hadoop102:8020</value>
</property>
<!--指定hadoop数据的存储目录-->
<property>
<name>hadoop.tmp.dir</name>
<value>/root/apps/hadoop/data</value>
</property>
<!-- 配置 HDFS 网页登录使用的静态用户为 root (非必须,可以不要)-->
<property>
<name>hadoop.http.staticuser.user</name>
<value>root</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=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-1.h5.oe1.aarch64
yarn-env.sh
将你配置环境变量时的jdk路径放进去即可,比如我的是JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-1.h5.oe1.aarch64
mapred-env.sh
将你配置环境变量时的jdk路径放进去即可,比如我的是JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.242.b08-1.h5.oe1.aarch64
wokers
这个文件在之前的版本中是slaves文件,后来改成了workers。
添加结点的主机名,vi workers
,将集群中所有的主机名放进去:
hadoop102
hadoop103
hadoop104
/etc/hosts文件
将主节点(hadoop102)的这个文件打开:
vi /etc/hosts
将文件中有主机名的这一行注释掉
然后添加集群中所有节点的内网ip(192开头的ip):
192.168.0.10 hadoop102
192.168.0.11 hadoop103
192.168.0.12 hadoop104
为集群中其他结点创建用户、安装java、配置环境变量
其他集群需要做的事情有这几件:
- 创建用户hadoop(创建用户的目的是因为所有集群要能传文件的话就需要相同用户名的用户,如果你用的是服务器,一般的服务器用户名直接是root这也可以,就不需要重新创建用户了)
- 安装jdk
对于安装hadoop、配置环境变量可以等一下将主节点的相关文件直接发送给从节点即可(在下文有详细步骤)。
关闭防火墙(每一台机器上执行)
- 查看防火墙状态
firewall-cmd --state
- 停止firewall
systemctl stop firewalld.service
- 禁止firewall开机启动
systemctl disable firewalld.service
ssh无密码访问
这步的核心原理是:将每台机器的公钥全部放至同一个文件中(authorized_keys)
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上的公钥传给其他的结点:如果是hadoop用户名,就需要将下面的指令改为hadoop@hadoop103和104
scp ~/.ssh/id_rsa.pub root@hadoop103:/root
scp ~/.ssh/id_rsa.pub root@hadoop104:/root
需要输入用户密码的时候输入即可。
接着在hadoop103、hadoop104 节点上,将 ssh 公匙加入授权:
mkdir ~/.ssh # 如果不存在该文件夹需先创建,若已存在则忽略
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
rm ~/id_rsa.pub # 用完就可以删掉了
至此即可实现hadoop102无密登录hadoop103和hadoop104了,但是我们的目的是他们互相无密登录,所以还需要将hosts文件分发给其他的结点:如果是hadoop用户名,就需要将下面的指令改为hadoop@hadoop103和104
# 分发/etc/hosts
scp /etc/hosts root@hadoop103:/etc/hosts
scp /etc/hosts root@hadoop103:/etc/hosts
这样就可以各个结点之间互相ssh无秘连接试试了,如果还需要密码,检查上述步骤是否有误。
编写集群分发脚本xsync
scp 是 secure copy 的简写,用于在 Linux 下进行远程拷贝文件,类似于 cp 命令,不过 cp 只能在本机中拷贝。
rsync指令和scp的区别:前者只传差异文件,后者不论是否有差异都传。
下载:
yum install rsync -y
切换到/usr/bin目录下:
cd /usr/bin
新建一个文件:
vi 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/
接下来将hadoop和环境变量文件分发给其他的结点:
# 分发/etc/profile.d/my-env.sh
xsync /etc/profile.d/my_env.sh
# 分发/root/apps/hadoop
xsync /root/apps/hadoop
然后分别在hadoop103和hadoop104中激活环境:
source /etc/profile
初始化
如果你弄了伪分布式或者本地的,先将{hadoop}/data和{hadoop}/logs删除掉。格式化的指令只用在第一次启动集群的时候执行即可。如果遇到了某一次自己的namenode没有启动,不要慌,将这两个目录删除,然后重新执行格式化即可。下图中data/和/input/还有logs/不是安装hadoop自带的,input是我自己创建的。
将新的分布式文件系统格式化为hdfs
bin/hdfs namenode -format
常用的启动、关闭服务的指令
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 # 任意虚拟机均可执行
至此,基于OpenEuler的hadoop集群搭建完毕。
OpenEuler配置MySQL数据库
参考链接:【在openEuler系统的ECS上,部署MySQL 8.0.x】
需要注意的是,这一步骤:
不要这样执行,因为这样弄的话下一次开启的时候又会无效,所以需要自己来手动打开文件:/etc/profile
并将如下内容放在最后一行并保存:
export PATH=$PATH:/usr/local/mysql/bin
【注意】每一次关闭服务器之后,然后重新打开可能出现无法登陆MySQL用户的情况,但是MySQL服务可以打开,这个时候首先检查一下MySQL服务是否已经打开了,如果打开了还是无法登陆用户,并且登陆的时候报错:
这个时候需要将以下的指令执行一遍:
vi /etc/ld.so.conf
添加:
/usr/local/mysql/lib
输入:
ldconfig 使得环境变量有效
# 加载mysql.service 之前的配置
systemctl daemon-reload
# 开启服务
service mysql start
ldconfig
ln -s /var/lib/mysql/run/mysql.sock /tmp/mysql.sock
# 登录数据库:
mysql -u root -p
可能的报错
在进行最后一步启动集群的时候报错:
需要在/root/apps/hadoop/sbin/start-dfs.sh中添加如下内容:
HDFS_DATANODE_USER=root
HADOOP_SECURE_DN_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root
在/root/apps/hadoop/sbin/stop-dfs.sh中添加如下内容:
YARN_RESOURCEMANAGER_USER=root
HADOOP_SECURE_DN_USER=yarn
YARN_NODEMANAGER_USER=root
在/root/apps/hadoop/sbin/start-yarn.sh中添加如下内容:
HDFS_DATANODE_USER=root
HADOOP_SECURE_DN_USER=hdfs
HDFS_NAMENODE_USER=root
HDFS_SECONDARYNAMENODE_USER=root
YARN_RESOURCEMANAGER_USER=root
HADOOP_SECURE_DN_USER=yarn
YARN_NODEMANAGER_USER=root
参考这篇博客:https://blog.csdn.net/qq_32635069/article/details/80859790
为了让集群中每一台服务器均可以开启、关闭集群,需要将这些文件分发至集群中的其他服务器:
xsync sbin/
一切都配置好了,而且windows可以ping通hadoop102,但是hadoop102:9870界面无法打开
参考:
【Linux系统重启后/etc/hosts自动添加主机名解析】
【Hadoop集群配置之后浏览器无法访问问题】
问题描述:集群全部配置完成,但是每次重新开启服务器之后再次打开时发现无法打开hadoop102:9870页面,使用windows来ping hadoop102可以通,使用服务器ping baidu.com也可以ping通。
问题解决:
每一次开机之后会发现无法打开hadoop102:9870这个界面,每一次出现问题去/etc/hosts文件中查看时会发现里面莫名其妙自己增加一行映射关系:
而且这次删了下一次开机会自动打开,而我们界面打不开也是这个问题,所以需要关闭这个功能,然后删除/etc/hosts文件中的127.0.0.1 hostname hostname这一行。
关闭自动添加映射关系的功能:
打开/etc/cloud/cloud.cfg文件
注释掉manage_etc_hosts配置项,如下:
# 修改前:
manage_etc_hosts:localhost
# 修改后:
#manage_etc_hosts:localhost
然后打开/etc/hosts文件,将127.0.0.1 hadoop10x hadoop10x删掉,保存重启集群即可。
这下可以查看9870端口是否打开:
ps -aux |grep 9870
netstat -apn
在进行上述步骤之前,输入netstat -apn结果如下:
修改了之后结果如下:
重新测试也发现可以打开: