配置 Hadoop Cluster
集群复刻
使用虚拟机的朋友请直接克隆
切记要返回第四步骤更改各节点ip,不然会发生ip冲突
1)备份
前往根目录
cd /
备份
tar cvpzf backup.tgz / --exclude=/proc --exclude=/lost+found --exclude=/mnt --exclude=/sys --exclude=backup.tgz
备份完成后,在文件系统的根目录将生成一个名为“backup.tgz”的文件,它的尺寸有可能非常大。你可以把它烧录到 DVD 上或者放到你认为安全的地方去
在备份命令结束时你可能会看到这样一个提示:’tar: Error exit delayed from previous
errors’,多数情况下你可以忽略
2)准备
别忘了到其他设备下重新创建那些在备份时被排除在外的目录(如果不存在):
mkdir proc mkdir lost+found mkdir mnt mkdir sys
3)复刻
可选前提:
- 将备份文件拷贝至外存储
- 到其他设备下挂在外存储
到其他物理机上恢复文件
tar xvpfz backup.tgz -C /
恢复 SELinux 文件属性
restorecon -Rv /
集群互联
HOST 配置
1)修改 hostname
到各设备下执行
# 设备 1 (立即生效) hostnamectl set-hostname master
# 设备 2 (立即生效) hostnamectl set-hostname slave1
# 设备 3 (立即生效) hostnamectl set-hostname slave2
# 设备 4 (立即生效) hostnamectl set-hostname slave3
2)配置 host 文件
查看各设备 ip(到各设备下执行)
ifconfig
到 master 下打开 host 文件
vim /etc/hosts
末尾追加
master设备的ip master slave1设备的ip master slave2设备的ip master slave3设备的ip master
3)通过 scp 传输 host 文件
scp 语法:
scp 文件名 远程主机用户名@远程主机名或ip:存放路径
到 master 下执行
scp /etc/hosts root@SlaveIP:/etc/
注意:请按照 slave 个数,对其 ip 枚举传输
ping 一下
ping -c 4 slave1
1
能 ping 通就没问题
配置无密码 SSH
以下操作均在master下执行
1)到各设备下生成密钥
ssh-keygen -t rsa
一路回车
到 master 生成公钥
cd ~/.ssh/ && cat id_rsa.pub > authorized_keys
之后将各设备的密钥全复制到authorized_keys文件里
2)通过 scp 传输公钥
到 master 下执行
scp authorized_keys root@SlaveNumbe:~/.ssh/
注意:请按照之前设置的 hostname ,对其 ip 枚举传输
例如: scp authorized_keys root@slave1:~/.ssh/
注意,如果各节点下没有 ~/.ssh/ 目录则会配置失败
检查
ssh slave1
中断该 ssh 连接(可选)
exit
客户端配置(建议)
该配置主要方便客户端远程操作
无论是用虚拟机进行学习的朋友,还是工作的朋友都强烈推荐
以下操作均在客户端(MAC OS)上执行
修改 hots 文件
sudo vim /etc/hosts
将 master 设备下/etc/hosts 之前追加的内容,copy 追加到客户端 hosts 末尾
ping 一下,能 ping 通就没问题
windows 修改 host 教程
免密钥 ssh 登陆
客户端生产密钥:
sudo ssh-keygen -t rsa
打开密钥
vim ~/.ssh/id_rsa
将密钥的内容追加到 master 设备的 ~/.ssh/authorized_keys 文件内
到 master 内向各节点申请同步
scp authorized_keys root@SlaveNumbe:~/.ssh/
windows ssh 目录:C:\Users\your_userName.ssh
检查
ssh master
部署 ZooKeeper
此文采用版本 ZooKeepr3.6.3
官方下载地址:Zookeeper
记得下载带bin字样的
准备
从客户端上下载 压缩包
到 master 节点上创建 zookeeper 文件夹
mkdir /usr/local/zookeeper
从客户端上传到 master
scp 你下载的Zookeeper路径 root@master:/usr/local/zookeeper
以下操作切换至master节点上
解压
cd /usr/local/zookeeper tar xf apache-zookeeper-3.6.3-bin.tar.gz
添加环境变量
打开配置文件
vim /etc/profile
在末尾添加
# ZooKeeper3.6.3 # 添加zookeeper地址变量 ZOOKEEPER_HOME=/usr/local/zookeeper/apache-zookeeper-bin.3.6.3 # 添加PATH地址变量 PATH=$ZOOKEEPER_HOME/bin:$PATH # 使变量生效 export ZOOKEEPER_HOME PATH
刷新配置文件
source /etc/profile
修改配置
创建数据目录
mkdir /zookeeper mkdir /zookeeper/data mkdir /zookeeper/logs # 同步 # 自行枚举
添加配置文件
cp $ZOOKEEPER_HOME/conf/zoo_sample.cfg $ZOOKEEPER_HOME/conf/zoo.cfg
vim $ZOOKEEPER_HOME/conf/zoo.cfg
修改和添加
tickTime=2000 initLimit=10 syncLimit=5 dataDir=/zookeeper/data dataLogDir=/zookeeper/logs clientPort=2181 server.1=master:2888:3888 server.2=slea1:2888:3888 server.3=slea2:2888:3888 server.4=slea3:2888:3888:observer
集群部署
到 master 下执行
请根据节点个数枚举执行
同步文件
scp /etc/profile root@slave1:/etc/
scp -r /zookeeper root@slave1:/
scp -r /usr/local/zookeeper root@slave1:/usr/local/
配置节点标识
参考资资料:leader 选举
ssh master "echo "9" > /zookeeper/data/myid" ssh slave1 "echo "1" > /zookeeper/data/myid" ssh slave2 "echo "2" > /zookeeper/data/myid" ssh slave3 "echo "3" > /zookeeper/data/myid"
防火墙配置
#开放端口 firewall-cmd --add-port=2181/tcp --permanent firewall-cmd --add-port=2888/tcp --permanent firewall-cmd --add-port=3888/tcp --permanent #重新加载防火墙配置 firewall-cmd --reload
节点批量执行
# master节点 ssh master "firewall-cmd --add-port=2181/tcp --permanent && firewall-cmd --add-port=2888/tcp --permanent && firewall-cmd --add-port=3888/tcp --permanent && firewall-cmd --reload " # slave1节点 其他请自行枚举执行 ssh slave1 "firewall-cmd --add-port=2181/tcp --permanent && firewall-cmd --add-port=2888/tcp --permanent && firewall-cmd --add-port=3888/tcp --permanent && firewall-cmd --reload "
启动 ZooKeeper
sh $ZOOKEEPER_HOME/bin/zkServer.sh start
编写批量启动 shell
vim /bin/zk && chmod 777 /bin/zk
#! /bin/sh case $1 in "start"){ echo -e "\e[32m---------------------------------------------------------------------------\033[0m" echo -e "\e[32m...master-start...\033[0m" ssh master "sh $ZOOKEEPER_HOME/bin/zkServer.sh start" echo -e "\e[32m...slave1-start...\033[0m" ssh slave1 "sh $ZOOKEEPER_HOME/bin/zkServer.sh start" echo -e "\e[32m...slave2-start...\033[0m" ssh slave2 "sh $ZOOKEEPER_HOME/bin/zkServer.sh start" echo -e "\e[32m...slave3-start...\033[0m" ssh slave3 "sh $ZOOKEEPER_HOME/bin/zkServer.sh start" echo -e "\e[32m...all-start-end...\033[0m" echo -e "\e[32m---------------------------------------------------------------------------\033[0m" };; "stop"){ echo -e "\e[32m---------------------------------------------------------------------------\033[0m" echo -e "\e[32m...master-stop...\033[0m" ssh master "sh $ZOOKEEPER_HOME/bin/zkServer.sh stop" echo -e "\e[32m...slave1-start...\033[0m" ssh slave1 "sh $ZOOKEEPER_HOME/bin/zkServer.sh stop" echo -e "\e[32m...slave2-start...\033[0m" ssh slave2 "sh $ZOOKEEPER_HOME/bin/zkServer.sh stop" echo -e "\e[32m...slave3-start...\033[0m" ssh slave3 "sh $ZOOKEEPER_HOME/bin/zkServer.sh stop" echo -e "\e[32m...all-stop-end...\033[0m" echo -e "\e[32m---------------------------------------------------------------------------\033[0m" };; "status"){ echo -e "\e[32m---------------------------------------------------------------------------" echo -e "\e[32m...master-status...\033[0m" ssh master "sh $ZOOKEEPER_HOME/bin/zkServer.sh status" echo -e "\e[32m...slave1-start...\033[0m" ssh slave1 "sh $ZOOKEEPER_HOME/bin/zkServer.sh status" echo -e "\e[32m...slave2-start...\033[0m" ssh slave2 "sh $ZOOKEEPER_HOME/bin/zkServer.sh status" echo -e "\e[32m...slave3-start...\033[0m" ssh slave3 "sh $ZOOKEEPER_HOME/bin/zkServer.sh status" echo -e "\e[32m...all-status-end...\033[0m" echo -e "\e[32m---------------------------------------------------------------------------\033[0m" };; esac
命令
# 启动 zk start # 查看状态 zk status # 关闭 zk stop
启动之后 MODE 和我的显示一样就算成功了
部署 Hadoop
此文采用版本 Hadoop3.2.2
官方下载地址:Hadoop
准备
从客户端上下载 压缩包
到 master 节点上创建 Hadoop 文件夹
mkdir /usr/local/hadoop
从客户端上传到 master
scp 你下载的hadoop路径 root@master:/usr/local/hadoop
以下操作切换至master节点上
解压
cd /usr/local/hadoop tar xf hadoop包名
添加环境变量
打开配置文件
vim /etc/profile
在末尾添加
# Hadoop 3.2.2 # 添加hadoop地址变量 HADOOP_HOME=/usr/local/hadoop/hadoop-3.3.0 # 添加PATH地址变量 PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin # 使变量生效 export HADOOP_HOME PATH # IF HADOOP >= 3x / for root # HDFS HDFS_DATANODE_USER=root HADOOP_SECURE_DN_USER=hdfs HDFS_NAMENODE_USER=root HDFS_SECONDARYNAMENODE_USER=root HDFS_ZKFC_USER=root # YARN YARN_RESOURCEMANAGER_USER=root HADOOP_SECURE_DN_USER=yarn YARN_NODEMANAGER_USER=root # run export HDFS_DATANODE_USER HADOOP_SECURE_DN_USER HDFS_NAMENODE_USER HDFS_SECONDARYNAMENODE_USER HDFS_ZKFC_USER YARN_RESOURCEMANAGER_USER HADOOP_SECURE_DN_USER YARN_NODEMANAGER_USER
请自行使用scp将文件同步至各节点
刷新配置文件
source /etc/profile
配置
创建数据目录
mkdir /hadoop mkdir /hadoop/journaldata mkdir /hadoop/hadoopdata # 同步 # 自行枚举
添加 Jdk 环境
打开文件
vim /usr/local/hadoop/hadoop-3.3.0/etc/hadoop/hadoop-env.sh
添加或修改
export JAVA_HOME=/usr/local/java
接下来我们要修改的文件:
- core-site.xml
- hadoop-env.sh
- mapred-env.sh
- yarn-env.sh
- workers
前往配置文件目录
cd /usr/local/hadoop/hadoop-3.3.0/etc/hadoop/
core-site.xml
<configuration> <!--指定hdfs nameservice--> <property> <name>fs.defaultFS</name> <value>hdfs://jed</value> </property> <!--指定hadoop工作目录--> <property> <name>hadoop.tmp.dir</name> <value>/hadoop/hadoopdata</value> </property> <!--指定zookeeper集群访问地址--> <property> <name>ha.zookeeper.quorum</name> <value>master:2181,slave1:2181,slave2:2181,slave3:2181</value> </property> </configuration>
hdfs-site.xml
<configuration> <!--不超过datanode节点数的副本数--> <property> <name>dfs.replication</name> <value>2</value> </property> <!--与core-site.xml中一致的hdfs nameservice--> <property> <name>dfs.nameservices</name> <value>jed</value> </property> <!--jed的NameNode,nn1,nn2 --> <property> <name>dfs.ha.namenodes.jed</name> <value>nn1,nn2</value> </property> <!-- nn1 的 RPC 通信地址 --> <property> <name>dfs.namenode.rpc-address.jed.nn1</name> <value>master:9000</value> </property> <!-- nn1 的 http 通信地址 --> <property> <name>dfs.namenode.http-address.jed.nn1</name> <value>master:50070</value> </property> <!-- nn2 的 RPC 通信地址 --> <property> <name>dfs.namenode.rpc-address.jed.nn2</name> <value>slave1:9000</value> </property> <!-- nn2 的 http 通信地址 --> <property> <name>dfs.namenode.http-address.jed.nn2</name> <value>slave1:50070</value> </property> <!-- 指定NameNode的edits元数据在JournalNode 上的存放位置 --> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://master:8485;slave1:8485;slave2:8485/jed</value> </property> <!-- 指定 JournalNode 在本地磁盘存放数据的位置 --> <property> <name>dfs.journalnode.edits.dir</name> <value>/hadoop/journaldata</value> </property> <!-- 开启 NameNode 失败自动切换 --> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> <!-- 配置失败自动切换实现方式 --> <!-- 此处配置较长,在安装的时候切记检查不要换行--> <property> <name>dfs.client.failover.proxy.provider.jed</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property> <!-- 配置隔离机制方法,多个机制用换行分割,即每个机制占用一行--> <property> <name>dfs.ha.fencing.methods</name> <value> sshfence shell(/bin/true) </value> </property> <!-- 使用 sshfence 隔离机制时需要 ssh 免登陆 --> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/var/root/.ssh/id_rsa</value> </property> <!-- 配置 sshfence 隔离机制超时时间(20s) --> <property> <name>dfs.ha.fencing.ssh.connect-timeout</name> <value>20000</value> </property> </configuration>
mapred-site.xml
<configuration> <!-- 指定 mr 框架为 yarn 方式 --> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <!-- 设置 mapreduce 的历史服务器地址和端口号 --> <property> <name>mapreduce.jobhistory.address</name> <value>master:10020</value> </property> <!-- mapreduce 历史服务器的 web 访问地址 --> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>master:19888</value> </property> <!--给mapreduce & app配置路径--> <property> <name>yarn.app.mapreduce.am.env</name> <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value> </property> <property> <name>mapreduce.map.env</name> <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value> </property> <property> <name>mapreduce.reduce.env</name> <value>HADOOP_MAPRED_HOME=${HADOOP_HOME}</value> </property> </configuration>
yarn-site.xml
<configuration> <!-- Site specific YARN configuration properties --> <!-- 开启 RM 高可用 --> <property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property> <!-- 指定 RM 的 cluster id,可以自定义--> <property> <name>yarn.resourcemanager.cluster-id</name> <value>Cyarn</value> </property> <!-- 指定 RM 的名字,可以自定义 --> <property> <name>yarn.resourcemanager.ha.rm-ids</name> <value>rm1,rm2</value> </property> <!-- 分别指定 RM 的地址 --> <property> <name>yarn.resourcemanager.hostname.rm1</name> <value>slave2</value> </property> <property> <name>yarn.resourcemanager.webapp.address.rm1</name> <value>slave2</value> </property> <property> <name>yarn.resourcemanager.hostname.rm2</name> <value>slave3</value> </property> <property> <name>yarn.resourcemanager.webapp.address.rm2</name> <value>slave3</value> </property> <!-- 指定 zk 集群地址 --> <property> <name>yarn.resourcemanager.zk-address</name> <value>master:2181,slave1:2181,slave2:2181,slave3:2181</value> </property> <!-- 要运行 MapReduce 程序必须配置的附属服务 --> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <!-- 开启 YARN 集群的日志聚合功能 --> <property> <name>yarn.log-aggregation-enable</name> <value>true</value> </property> <!-- YARN 集群的聚合日志最长保留时长 --> <property> <name>yarn.log-aggregation.retain-seconds</name> <!--1天--> <value>86400</value> </property> <!-- 启用自动恢复 --> <property> <name>yarn.resourcemanager.recovery.enabled</name> <value>true</value> </property> <!-- 制定 resourcemanager 的状态信息存储在 zookeeper 集群上--> <property> <name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value> </property> </configuration>
workers
注意!在Hadoop3x以前的版本是 slaves 文件
master slave1 slave2 slave3
使用 scp 分发给其他节点
scp -r /usr/local/hadoop slave1:/usr/local/
请自行枚举执行
检查
使用之前的 zk 脚本启动 zeekeeper 集群
zk start
分别在每个 journalnode 节点上启动 journalnode 进程
# master slave1 slave2 hadoop-daemon.sh start journalnode
在第一个 namenode 节点上格式化文件系统
hadoop namenode -format
同步两个 namenode 的元数据
查看你配置的 hadoop.tmp.dir 这个配置信息,得到 hadoop 工作的目录,我的是/hadoop/hadoopdata/
把 master 上的 hadoopdata 目录发送给 slave1 的相同路径下,这一步是为了同步两个 namenode 的元数据
scp -r /hadoop/hadoopdata slave1:/hadoop/
也可以在 slave1 执行以下命令:
hadoop namenode -bootstrapStandby
格式化 ZKFC(任选一个 namenode 节点格式化)
hdfs zkfc -formatZK
启动 hadoop 集群
start-all.sh
相关命令请前往 $HADOOP_HOME/sbin/ 查看
启动 mapreduce 任务历史服务器
mr-jobhistory-daemon.sh start historyserver
编写 jps 集群脚本
vim /bin/jpall && chmod 777 /bin/jpall
#! /bin/sh echo -e "\e[32m---------------------------------------------------------------------------\033[0m" echo -e "\e[32m...master-jps...\033[0m" ssh master "jps" echo -e "\e[32m...slave1-jps...\033[0m" ssh slave1 "jps" echo -e "\e[32m...slave2-jps...\033[0m" ssh slave2 "jps" echo -e "\e[32m...slave3-jps...\033[0m" ssh slave3 "jps" echo -e "\e[32m...all-jps-end...\033[0m" echo -e "\e[32m---------------------------------------------------------------------------\033[0m"
运行
jpall
查看各节点的主备状态
hdfs haadmin -getServiceState nn1
查看 HDFS 状态
hdfs dfsadmin -report
WEB 访问可以直接浏览器: IP:50070
测试
HDFS
上传一个文件
hdfs dfs -put test.out
check
hdfs dfs -ls /user/root
hadoop fs -rm -r -skipTrash /user/root/test.out
删除
Mapreduce
我们使用 hadoop 自带的圆周率测试
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.0.jar pi 5 5
运行结果
高可用
查看进程
jps
杀死进程
kill -9 5114
现在 master 已不是 namenode 了
现在 slave1 变成了主节点
恢复 master 节点
hadoop-daemon.sh start namenode
master 变成了 standby,什么 HA 具备
Hadoop HA 集群的重装
- 删除所有节点中 hadoop 的工作目录(core-site.xml 中配置的 hadoop.tmp.dir 那个目录)
- 如果你在 core-site.xml 中还配置了 dfs.datanode.data.dir 和 dfs.datanode.name.dir 这两个配置,那么把这两个配置对应的目录也删除
- 删除所有节点中 hadoop 的 log 日志文件,默认在 HADOOP_HOME/logs 目录下
- 删除 zookeeper 集群中所关于 hadoop 的 znode 节点
图中的红色框中 rmstore 这个节点不能删除,删除另外两个就可以
- 重新格式化 ZKFC 的时候会询问是否覆盖 rmstore 这个节点,输入 yes 即可
- 删除所有节点中的 journaldata,路径是在 hdfs-site.xml 中的 dfs.journalnode.edits.dir 中配置的
- 按照上面安装集群的步骤重新安装即可