相关安装包准备:
hadoop-3.2.1.tar.gz
pdsh-2.26.tar.bz2
jdk-8u231-linux-x64.tar.gz
虚拟机环境准备
准备3台客户机 ,使用VMWare创建一台虚拟机后可以使用克隆 功能
分别修改三台虚拟机的ip,建议设置静态ip
修改网卡配置:vim /etc/sysconfig/network-scriptsif/cfg-ens33,如下:
修改BOOTPROTO=static
修改ONBOOT=yes
配置IP地址、子网掩码、网关、dns服务器
1 2 3 4 5 6 # 只需修改IPADDR即可,三台服务器设置不同的ip地址,建议分别设置为100、101、102 IPADDR=192.168.3.100 NETMASK=255.255.255.0 GATEWAY=192.168.3.1 DNS1=8.8.8.8 DNS2=114.114.114.114
重启配置systemctl restart network
执行ifconfig查看ip地址是否已经成功修改为192.168.3.100,192.168.3.101,192.168.3.102
修改主机名/etc/hosts
三台虚拟机分别加入如下配置:
1 2 3 192.168.3.100 master 192.168.3.101 slave1 192.168.3.102 slave2
定时时间同步
1 2 3 4 5 6 7 8 # 安装同步工具 sudo yum -y install ntp ntpdate # 设置时间同步 sudo ntpdate cn.pool.ntp.org # 将系统时间写入硬件时间 sudo hwclock --systohc # 查看系统时间 timedatectl
添加定时任务,每隔十分钟同步一次 ,crontab -e添加
1 */10 * * * * ntpdate cn.pool.ntp.org
上传相关安装包到/opt目录下(三台都需上传)
安装ssh、pdsh(建议三台都安装。ssh三台必须都安装,pdsh可只安装在需要批量执行命令的服务器)
一般ssh默认已安装,查看是否运行systemctl status sshd,这里只需安装pdsh,安装步骤如下:
1 2 3 4 5 6 7 8 9 10 11 cd /opt tar -jxvf pdsh-2.26.tar.bz2 cd pdsh-2.26 ./configure \ --without-rsh \ --with-ssh \ --with-machines=/etc/pdsh/machines \ --with-dshgroups \ --with-netgroup \ --with-timeout=10 make && make install
检查是否默认使用ssh:pdsh -V,如果不是,自行百度设置
设置pdsh主机:vim /etc/pdsh/machines,加入:
免密码登录,相关命令如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # 三台都需执行 ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys chmod 0600 ~/.ssh/authorized_keys # 免密码登录自身,(首次需输入yes) ssh localhost # 免密码登录其他机器,三台都需要执行 ssh-copy-id -i ~/.ssh/id_rsa.pub master ssh-copy-id -i ~/.ssh/id_rsa.pub slave1 ssh-copy-id -i ~/.ssh/id_rsa.pub slave2 # 登录测试 ssh master ssh slave1 ssh slave2 # 退出登录 exit
关闭防火墙,相关命令如下:
1 2 3 4 5 6 7 8 # 查看防火墙状态 systemctl status firewalld.service # 关闭防火墙 systemctl stop firewalld.service # 禁止开机自启用 systemctl disable firewalld.service # 重启防火墙 firewall-cmd --reload
安装jdk,可借助pdsh执行部分操作,例如:pdsh -a "cd /usr/local && tar -zxvf jdk-8u231-linux-x64.tar.gz"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # 切换目录 cd /usr/local # 解压 tar -zxvf jdk-8u231-linux-x64.tar.gz # 修改配置文件 vim /etc/profile # 在末尾添加,JAVA_HOME根据实际情况修改 # java environment JAVA_HOME=/usr/local/jdk1.8.0_231 JRE_HOME=$JAVA_HOME/jre PATH=$PATH:$JAVA_HOME/bin:$JRE_home/bin:$PATH CLASSPATH=.:$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:$CLASSPATH export JAVA_HOME export JRE_HOME export PATH export CLASSPATH # 使配置文件生效 source /etc/profile
搭建集群 安装hadoop 借助pdsh执行
1 pdsh -a "cd /opt && tar -zxvf /opt/hadoop-3.2.1.tar.gz"
修改/etc/profile,末尾添加(三台都需添加)
1 2 3 4 # hadoop environment export HADOOP_HOME=/opt/hadoop-3.2.1 export PATH=$PATH:$HADOOP_HOME/bin export PATH=$PATH:$HADOOP_HOME/sbin
检查是否安装成功
集群部署规划
master
slave1
slave2
HDFS
DataNode、NameNode
DataNode
DataNode、SecondaryNameNode
YARN
NodeManager
NodeManager、ResourceManager
NodeManager
配置集群 下面只需配置一台服务器,后续复制文件内容到其他服务器即可
核心配置文件 配置core-site.xml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <configuration > <property > <name > fs.defaultFS</name > <value > hdfs://master:9000</value > </property > <property > <name > io.file.buffer.size</name > <value > 131072</value > </property > <property > <name > hadoop.tmp.dir</name > <value > /opt/hadoop-3.2.1/data/tmp</value > </property > </configuration >
HDFS配置文件 配置hadoop-env.sh,末尾添加
1 2 3 4 5 6 export JAVA_HOME=/usr/local/jdk1.8.0_231 export HDFS_NAMENODE_USER="root" export HDFS_DATANODE_USER="root" export HDFS_SECONDARYNAMENODE_USER="root" export YARN_RESOURCEMANAGER_USER="root" export YARN_NODEMANAGER_USER="root"
配置hdfs-site.xml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 <configuration > <property > <name > dfs.replication</name > <value > 3</value > </property > <property > <name > dfs.namenode.secondary.http-address</name > <value > slave2:9868</value > </property > </configuration >
YARN配置文件 配置yarn-env.sh,末尾加上
1 export JAVA_HOME=/usr/local/jdk1.8.0_231
配置yarn-site.xml,添加
1 2 3 4 5 6 7 8 9 10 11 12 <configuration > <property > <name > yarn.nodemanager.aux-services</name > <value > mapreduce_shuffle</value > </property > <property > <name > yarn.resourcemanager.hostname</name > <value > slave1</value > </property > </configuration >
MapReduce配置文件 配置mapred-env.sh,末尾加上
1 export JAVA_HOME=/usr/local/jdk1.8.0_231
配置mapred-site.xml,添加
1 2 3 4 5 6 7 <configuration > <property > <name > mapreduce.framework.name</name > <value > yarn</value > </property > </configuration >
复制配置文件到其他服务器 1 2 3 4 5 6 7 8 9 pdcp -a /opt/hadoop-3.2.1/etc/hadoop/core-site.xml /opt/hadoop-3.2.1/etc/hadoop/core-site.xml pdcp -a /opt/hadoop-3.2.1/etc/hadoop/hadoop-env.sh /opt/hadoop-3.2.1/etc/hadoop/hadoop-env.sh pdcp -a /opt/hadoop-3.2.1/etc/hadoop/hdfs-site.xml /opt/hadoop-3.2.1/etc/hadoop/hdfs-site.xml pdcp -a /opt/hadoop-3.2.1/etc/hadoop/yarn-env.sh /opt/hadoop-3.2.1/etc/hadoop/yarn-env.sh pdcp -a /opt/hadoop-3.2.1/etc/hadoop/yarn-site.xml /opt/hadoop-3.2.1/etc/hadoop/yarn-site.xml pdcp -a /opt/hadoop-3.2.1/etc/hadoop/mapred-env.sh /opt/hadoop-3.2.1/etc/hadoop/mapred-env.sh pdcp -a /opt/hadoop-3.2.1/etc/hadoop/mapred-site.xml /opt/hadoop-3.2.1/etc/hadoop/mapred-site.xml pdsh -a "source /etc/profile"
启动集群 配置workers 在masters上/opt/hadoop-3.2.1/etc/hadoop下编辑workers文件,加入所有datanode主机名(在hadoop 2.x中这个文件叫slaves)。
同步到其他服务器pdcp -a /opt/hadoop-3.2.1/etc/hadoop/workers /opt/hadoop-3.2.1/etc/hadoop/workers
格式化并启动NameNode 如果集群是第一次启动,需要格式化NameNode。(注意:格式化之前,一定要先停止上次启动的所有namenode和datanode进程,然后再删除data和log数据)
1 2 3 4 # 格式化namenode(只需在master上执行) hadoop namenode -format # 在启动namenode(只需在master上执行) hdfs --daemon start namenode
启动DFS集群 1 2 # 启动DFS集群(只需在master上执行) ./sbin/start-dfs.sh
此时master状态如下:
此时slave1状态如下:
此时slave2状态如下:
参照集群部署规划,说明DFS集群启动成功
启动YARN集群 1 2 # 启动DFS集群(只需在ResouceManager对应的机器上执行) ./sbin/start-yarn.sh
此时master状态如下:
此时slave1状态如下:
此时slave2状态如下:
参照集群部署规划,说明YARN的NodeManager集群启动成功,ResourceManager需要单独在slave1启动。
查看SecondaryNameNode 浏览器打开:http://192.168.3.102:9868,效果如下:
这里显示异常 ,需要修改/opt/hadoop-3.2.1/share/hadoop/hdfs/webapps/static/dfs-dust.js第61行
1 return new Date (Number (v)).toLocaleString();
复制文件到其他服务器
1 pdcp -a /opt/hadoop-3.2.1/share/hadoop/hdfs/webapps/static/dfs-dust.js /opt/hadoop-3.2.1/share/hadoop/hdfs/webapps/static/dfs-dust.js
清除浏览器缓存后刷新页面 ,效果如下:
查看NameNode 浏览器打开:http://192.168.3.100:9870,效果如下:
停止集群 各个服务组件逐一启动/停止
分别启动/停止HDFS组件
1 hadoop-daemon.sh start / stop namenode / datanode / secondarynamenode
分别启动/停止YARN
1 yarn-daemon.sh start / stop resourcemanager / nodemanager
各个模块分开启动/停止(配置ssh是前提) 常用方式,推荐
整体启动/停止HDFS
1 start-dfs.sh / stop-dfs.sh
整体启动/停止YARN
1 start-yarn.sh / stop-yarn.sh
移除hadoop环境 1 2 rm -rf /opt/hadoop-3.2.1/data rm -rf /opt/hadoop-3.2.1/logs
HA配置 环境准备 上面已经准备好了就不用准备了,下面只列出部分HA需要修改的配置文件。
修改IP
修改主机名及主机名和IP地址的映射
关闭防火墙
ssh免密登录
安装JDK,配置环境变量等
HDFS-HA集群配置 集群部署规划
master
slave1
slave2
NameNode
NameNode
JournalNode
JournalNode
JournalNode
DataNode
DataNode
DataNode
ZK
ZK
ZK
ResourceManager
NodeManager
NodeManager
NodeManager
ZK集群 在master、slave1、slave2三个节点上部署Zookeeper,这里使用docker部署。
docker-compose master 节点,除了zookeeper之外,还部署了consul和zkui(zookeeper的web管理界面)
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 39 40 41 42 43 44 version: '3' services: zoo: image: zookeeper:3.4.14 container_name: zoo restart: always hostname: 192.168 .3 .100 network_mode: host volumes: - ./data:/data - ./datalog:/datalog environment: ZOO_MY_ID: 1 ZOO_SERVERS: server.1=192.168.3.100:2888:3888 server.2=192.168.3.101:2888:3888 server.3=192.168.3.102:2888:3888 TZ: Asia/Shanghai consul: image: qnib/consul container_name: consul ports: - 8500 :8500 environment: - DC_NAME=qnib - RUN_SERVER=true - BOOTSTRAP_CONSUL=true dns: 192.168 .3 .100 privileged: true zkui: hostname: 192.168 .3 .100 container_name: zkui dns: 192.168 .3 .100 dns_search: - node.consul - service.consul image: qnib/zkui environment: - DC_NAME=qnib - ZKUI_ZK_SERVER=192.168.3.100:2181,192.168.3.101:2181,192.168.3.102:2181 links: - consul:consul ports: - 9090 :9090 privileged: true
slave1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 version: '3' services: zoo: image: zookeeper:3.4.14 container_name: zoo restart: always hostname: 192.168 .3 .101 network_mode: host volumes: - ./data:/data - ./datalog:/datalog environment: ZOO_MY_ID: 2 ZOO_SERVERS: server.1=192.168.3.100:2888:3888 server.2=192.168.3.101:2888:3888 server.3=192.168.3.102:2888:3888 TZ: Asia/Shanghai
slave2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 version: '3' services: zoo: image: zookeeper:3.4.14 container_name: zoo restart: always hostname: 192.168 .3 .102 network_mode: host volumes: - ./data:/data - ./datalog:/datalog environment: ZOO_MY_ID: 3 ZOO_SERVERS: server.1=192.168.3.100:2888:3888 server.2=192.168.3.101:2888:3888 server.3=192.168.3.102:2888:3888 TZ: Asia/Shanghai
查看状态 进入容器,查看集群状态
status``` 1 2 3 4 连接zookeeper ```bin//zkCli.sh -server 127.0.0.1:2181
或者直接访问zkui:http://192.168.3.100:9090,查看状态
核心配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <configuration > <property > <name > fs.defaultFS</name > <value > hdfs://mycluster</value > </property > <property > <name > io.file.buffer.size</name > <value > 131072</value > </property > <property > <name > hadoop.tmp.dir</name > <value > /opt/hadoop-3.2.1/data/tmp</value > </property > <property > <name > ha.zookeeper.quorum</name > <value > master:2181,slave1:2181,slave2:2181</value > </property > </configuration >
HDFS配置文件 配置hadoop-env.sh,修改为:(主要是加入了HDFS_JOURNALNODE_USER、HDFS_ZKFC_USER)
1 2 3 4 5 6 7 8 export JAVA_HOME=/usr/local/jdk1.8.0_231 export HDFS_NAMENODE_USER="root" export HDFS_DATANODE_USER="root" export HDFS_SECONDARYNAMENODE_USER="root" export YARN_RESOURCEMANAGER_USER="root" export YARN_NODEMANAGER_USER="root" export HDFS_JOURNALNODE_USER="root" export HDFS_ZKFC_USER="root"
配置hdfs-site.xml文件
注意 ,这里加上shell(/bin/true)后,namenode才能实现高可用(active的namenode挂了之后,standby的namenode才会自动成为active)。原因是:standby的namenode只有确定了之前active的namenode此时不为active之后,它才会成为standby,目的是防止发生脑裂,但由于active已经挂了,stanby的namenode无法和他通信,加上此配置后,就会忽略确认过程,直接升级为active。
1 2 3 4 5 6 7 <property> <name>dfs.ha.fencing.methods</name> <value> sshfence shell(/bin/true) </value> </property>
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 <configuration > <property > <name > dfs.nameservices</name > <value > mycluster</value > </property > <property > <name > dfs.replication</name > <value > 1</value > </property > <property > <name > dfs.ha.namenodes.mycluster</name > <value > nn1,nn2</value > </property > <property > <name > dfs.namenode.rpc-address.mycluster.nn1</name > <value > master:9820</value > </property > <property > <name > dfs.namenode.rpc-address.mycluster.nn2</name > <value > slave1:9820</value > </property > <property > <name > dfs.namenode.http-address.mycluster.nn1</name > <value > master:9870</value > </property > <property > <name > dfs.namenode.http-address.mycluster.nn2</name > <value > slave1:9870</value > </property > <property > <name > dfs.namenode.shared.edits.dir</name > <value > qjournal://master:8485;slave1:8485;slave2:8485/mycluster</value > </property > <property > <name > dfs.journalnode.edits.dir</name > <value > /opt/hadoop-3.2.1/journaldata</value > </property > <property > <name > dfs.ha.automatic-failover.enabled</name > <value > true</value > </property > <property > <name > dfs.client.failover.proxy.provider.mycluster</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 > <property > <name > dfs.ha.fencing.ssh.private-key-files</name > <value > /root/.ssh/id_rsa</value > </property > <property > <name > dfs.ha.fencing.ssh.connect-timeout</name > <value > 30000</value > </property > </configuration >
启动集群
先确保zookeeper集群已成功启动
分别在master、slave1、slave2上执行:hdfs --daemon start journalnode
格式化namenode,在master上执行hdfs namenode -format
在master上执行hdfs --daemon start namenode,启动成功后再slave1上执行hdfs namenode -bootstrapStandby
在master上执行hdfs zkfc -formatZK,格式化ZKFC
连接zookeeper可以查看
启动HDFS集群start-dfs.sh(只需在master上执行),效果如下:
分别访问http://master:9870、http://slave1:9870,效果如下:
master是active状态,slaves是standby状态 ,由图可知slave1上的nn是master
验证高可用 在slave1上使用jps查看namenode进程,然后kill -9 杀掉namenode进程
然后再访问http://master:9870,此时它已升级为master,如果这一步没能升级,请检查```hdfs-site.xml```配置
如果隔离机制没有配置shell(/bin/true),推荐kill -9 杀掉DFSZKFailoverController进程,这个时候Standby也能变为active,因为namenode还活着,可以确认他没有获取到锁(即杀掉zkfc后,active会变成standby)。
YARN-HA集群配置 YARN-HA工作机制:http://hadoop.apache.org/docs/r3.2.1/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html
集群部署规划
master
slave1
slave2
NameNode
NameNode
JournalNode
JournalNode
JournalNode
DataNode
DataNode
DataNode
ZK
ZK
ZK
ResourceManager
ResourceManager
NodeManager
NodeManager
NodeManager
YARN配置文件 检查hadoop-env.sh是否存在YARN_RESOURCEMANAGER_USER,YARN_NODEMANAGER_USER
1 2 3 4 5 6 7 8 export JAVA_HOME=/usr/local/jdk1.8.0_231 export HDFS_NAMENODE_USER="root" export HDFS_DATANODE_USER="root" export HDFS_SECONDARYNAMENODE_USER="root" export YARN_RESOURCEMANAGER_USER="root" export YARN_NODEMANAGER_USER="root" export HDFS_JOURNALNODE_USER="root" export HDFS_ZKFC_USER="root"
yarn-site.xml
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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 <configuration > <property > <name > yarn.nodemanager.aux-services</name > <value > mapreduce_shuffle</value > </property > <property > <name > yarn.resourcemanager.ha.enabled</name > <value > true</value > </property > <property > <name > yarn.resourcemanager.cluster-id</name > <value > yarncluster</value > </property > <property > <name > yarn.resourcemanager.ha.rm-ids</name > <value > rm1,rm2</value > </property > <property > <name > yarn.resourcemanager.hostname.rm1</name > <value > master</value > </property > <property > <name > yarn.resourcemanager.hostname.rm2</name > <value > slave1</value > </property > <property > <name > yarn.resourcemanager.webapp.address.rm1</name > <value > master:8088</value > </property > <property > <name > yarn.resourcemanager.webapp.address.rm2</name > <value > slave1:8088</value > </property > <property > <name > yarn.resourcemanager.zk-address</name > <value > master:2181,slave1:2181,slave2:2181</value > </property > <property > <name > yarn.resourcemanager.recovery.enabled</name > <value > true</value > </property > <property > <name > yarn.resourcemanager.store.class</name > <value > org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value > </property > <property > <name > yarn.application.classpath</name > <value > /opt/hadoop-3.2.1/etc/hadoop:/opt/hadoop-3.2.1/share/hadoop/common/lib/*:/opt/hadoop-3.2.1/share/hadoop/common/*:/opt/hadoop-3.2.1/share/hadoop/hdfs:/opt/hadoop-3.2.1/share/hadoop/hdfs/lib/*:/opt/hadoop-3.2.1/share/hadoop/hdfs/*:/opt/hadoop-3.2.1/share/hadoop/mapreduce/lib/*:/opt/hadoop-3.2.1/share/hadoop/mapreduce/*:/opt/hadoop-3.2.1/share/hadoop/yarn:/opt/hadoop-3.2.1/share/hadoop/yarn/lib/*:/opt/hadoop-3.2.1/share/hadoop/yarn/* </value > </property > </configuration >
启动集群 启动之前先确保HDFA-HA已启动
在slave1上执行sbin/start-yarn.sh,如果这里是在master上执行的,那还需要单独去slave1上执行yarn --daemon start resourcemanager。
查看master上的yarn服务状态bin/yarn rmadmin -getServiceState rm1
查看slave1上的yarn服务状态bin/yarn rmadmin -getServiceState rm2
验证高可用 停掉slave1上的resourcemanager(因为它是active),然后查看rm1状态
rm1变为active,说明高可用验证成功
其他 启动命令 推荐分别群启HDFS、YARN的方式
全部启动/关闭 1 2 sbin/start-all.sh sbin/stop-all.sh
群启动/关闭HDFS(包含namenode和datanode) 1 2 sbin/start-dfs.sh sbin/stop-dfs.sh
群启动/关闭YARN(包含resourcemanager和nodemanager) 需在包含resoucemanager上的机器启动,否则还需单独再启动resourcemanager(使用yarn --daemon start resoucemanager单独启动)
1 2 sbin/start-yarn.sh sbin/stop-yarn.sh
单独启动namenode和datanode 1 2 3 4 hdfs --daemon start namenode hdfs --daemon stop namenode hdfs --daemon start datanode hdfs --daemon stop datanode
单独启动/关闭resourcemanager和nodemanager 1 2 3 4 yarn --daemon start resourcemanager yarn --daemon stop resourcemanager yarn --daemon start nodemanager yarn --daemon stop nodemanager
单独启动/关闭zkfc 1 2 sbin/hadoop-daemon.sh start zkfc sbin/hadoop-daemon.sh stop zkfc
单独启动/关闭journalnode 1 2 hdfs --daemon start journalnode hdfs --daemon stop journalnode
端口变动 从hadoop2到hadoop3端口变动如下:
Namenode ports
50470 –> 9871
50070 –> 9870
8020 –> 9820
Secondary NN ports
50091 –> 9869,
50090 –> 9868
Datanode ports
50020 –> 9867
50010 –> 9866
50475 –> 9865
50075 –> 9864