前置条件
准备至少三台服务器,集群状态:一主二从架构
| ip地址 | hostname | 说明 |
|---|---|---|
| 10.177.32.93 | node1 | master |
| 10.177.32.94 | node2 | slave-one |
| 10.177.32.95 | node3 | salve-two |
三台服务器之间可以通过hostname访问
# hostname修改
hostnamectl set-hostname centos137
#三台修改hosts文件,添加以下命令
192.168.108.137 centos137
192.168.108.138 centos138
192.168.108.139 centos139
#重启
reboot
hadoop集群版本号3.3.6版本,集群中安装有hdfs服务。
JDK1.8+推荐自己安装jdk,需要配置JAVA_HOME环境变量
部署步骤
配置主机名
-- 节点一配置
sudo hostnamectl set-hostname node1
echo "10.177.32.93 node1" | sudo tee -a /etc/hosts
echo "10.177.32.94 node2" | sudo tee -a /etc/hosts
echo "10.177.32.95 node3" | sudo tee -a /etc/hosts
-- 节点二配置
sudo hostnamectl set-hostname node2
echo "10.177.32.93 node1" | sudo tee -a /etc/hosts
echo "10.177.32.94 node2" | sudo tee -a /etc/hosts
echo "10.177.32.95 node3" | sudo tee -a /etc/hosts
-- 节点三配置
sudo hostnamectl set-hostname node3
echo "10.177.32.93 node1" | sudo tee -a /etc/hosts
echo "10.177.32.94 node2" | sudo tee -a /etc/hosts
echo "10.177.32.95 node3" | sudo tee -a /etc/hosts
创建普通用户
官方推荐使用普通用户启动,直接用root启动会提示报错信息
useradd flink
设置免密登录
# 在节点一上执行
ssh-keygen -t rsa
ssh-copy-id node1 # 密码认证完毕后,重复操作到node2,node3
ssh-copy-id node2
ssh-copy-id node3
chmod 700 ~/.ssh && chmod 600 ~/.ssh/*
# 节点二也可以设置(选设)
ssh-keygen -t rsa
ssh-copy-id node1 # 密码认证完毕后,重复操作到node2,node3
ssh-copy-id node2
ssh-copy-id node3
chmod 700 ~/.ssh && chmod 600 ~/.ssh/*
# 节点三(选设)
ssh-keygen -t rsa
ssh-copy-id node1 # 密码认证完毕后,重复操作到node2,node3
ssh-copy-id node2
ssh-copy-id node3
chmod 700 ~/.ssh && chmod 600 ~/.ssh/*
# 可以通过ssh node2来验证是否免密
上传文件
# 将相应的文件依次上传到各个节点上
# 如果是有互联网环境可以下按需下载
wget https://mirrors.huaweicloud.com/apache/hadoop/common/hadoop-3.3.6/hadoop-
3.3.6.tar.gz
tar -zxvf hadoop-3.3.6.tar.gz -C apps/
mv apps/hadoop-3.3.6 apps/hadoop
配置环境变量
# 所有节点都需执行
vim ~/.bash_profile
export HADOOP_HOME=/data/app/software/hadoop
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
source ~/.bash_profile
核心配置
配置core-site.xml(HDFS)
<configuration>
<property>
<name>fs.defaultFS</name> // 分布式文件系统的默认命名空间和端口
<value>hdfs://node1:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name> // 临时文件存放目录
<value>/data/app/software/hadoop/tmp</value>
</property>
</configuration>
配置hdfs-site.xml(HDFS)
<configuration>
<property>
<name>dfs.namenode.name.dir</name> // NameNode存储元数据目录
<value>/data/app/software/hadoop/data/namenode</value>
</property>
<property>
<name>dfs.datanode.data.dir</name> // dataNode存储数据目录
<value>/data/app/software/hadoop/data/namenode</value>
</property>
<property>
<name>dfs.replication</name> -- 执行每个数据块的副本数量
<value>2</value>
</property>
</configuration>
配置mapred-site.xml(Yarn)
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
配置yarn-site.xml(Yarn)
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>node1</value>
</property>
</configuration>
配置works文件
node1
node2
node3
启动/停止
# 格式化HDFS
hdfs namenode -format
# 启动HDFS
start-dfs.sh
jps # 可以看到NameNode/DataNode进程
# 启动Yarn容器
start-yarn.sh
jps # 验证是否有ResourceManager/NodeManager
Hadoop高可用方案
部署架构图
配置相关文件
配置core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://node1:9000</value>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>node1:2181,node2:2181,node3:2181</value>
</property>
<property>
<name>ipc.client.connect.max.retries</name>
<value>100</value>
</property>
<property>
<name>ipc.client.connect.retry.interval</name>
<value>10000</value>
</property>
</configuration>
配置hdfs-site.xml
<configuration>
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>node1:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>node2:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>node1:9870</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>node2:9870</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node1:8485;node2:8485;node3:8485/mycluster</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</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/flink/.ssh/id_rsa</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/data/app/software/hadoop/data/journal</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.ha.zkfc.nn1</name>
<value>node1:2181,node2:2181,node3:2181</value>
</property>
<property>
<name>dfs.ha.zkfc.nn2</name>
<value>node1:2181,node2:2181,node3:2181</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/data/app/software/hadoop/data/namenode</value>
</property>
<property>
<name>dfs.datanode.name.dir</name>
<value>file:/data/app/software/hadoop/data/datanode</value>
</property>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
</configuration>
配置yarn-site.xml
<configuration>
<!-- Site specific YARN configuration properties -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce_shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<property>
<name>yarn.resourcemanager.ha.enabled</name>
<value>true</value>
</property>
<property>
<name>yarn.resourcemanager.cluster-id</name>
<value>yrc</value>
</property>
<property>
<name>yarn.resourcemanager.ha.rm-ids</name>
<value>rm1,rm2</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm1</name>
<value>node1</value>
</property>
<property>
<name>yarn.resourcemanager.hostname.rm2</name>
<value>node2</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm1</name>
<value>node1:8088</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address.rm2</name>
<value>node2:8088</value>
</property>
<property>
<name>yarn.resourcemanager.zk-address</name>
<value>node1:2181,node2:2181,node3:2181</value>
</property>
<property>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
# 配置重启后恢复任务状态
<property>
<name>yarn.resourcemanager.store.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
</property>
<!--<property>
<name>yarn.resourcemanager.hostname</name>
<value>node1</value>
</property> -->
</configuration>
需要注意的是:在配置文件过程中会出现数据目录或日志目录等,按需手动创建
启动组件
启动JournalNode组件
# 需要在所有节点上启动journalnode
hdfs --daemon start journalnode
# 启动完毕后,可以通过查看jps判断是否有启动
# 也可以通过netstat -tunlp,来查看8480、8485是否启动
格式化HDFS
# 在节点一上执行
hdfs namenode -format
# 这里需要注意,因为高可用方案需要有两个namenode,但是这两个主备是一个active,一个standby。所以第一次启动的时候,也需要注意这点,备节点的信息也需要有格式化信息
# 首先在节点一已经格式化完毕之后,namenode目录下会创建目录,可以选择手动将namenode的目录信息移到节点二配置的namenode的目录下。
# 还有一种也是比较推荐的,因为咱们journalnode已经启动,可以通过它来实现自动迁移
初始化Zookeeper
# 在节点一上执行
hdfs zkfc -formatZK
启动HDFS与Yarn服务
逐个命令执行
# 在node1上启动namenode,avitve
hdfs --daemon start namenode
# 在node2上执行
# 可能会出现报错,需要手动将namenode目录拷贝一份出来,或者通过hdfs namenode -bootstrapStandby来初始化备份节点
hdfs --daemon start namenode
# 在所有节点执行启动数据节点
hdfs --daemon start datanode
# 执行完毕后,可以通过jps,来查看是否有相关进程
# 在node1、node2节点上启动resourceManager
yarn --daemon start resourcemanager
# 在全部节点上启动NodeManager
yarn --daemon start nodemanager
# 在节点一和节点二上启动ZKFC组件
hdfs --daemon start zkfc
批命令执行
hadoop集群中提供了一键式启动的命令,但是发现在执行过程中出现问题,在节点二没有发现NameNode的启动。
原因分析,发现咱们在节点一使用此命令启动时,发现启动namenode在journalNode之前。默认的重试次数只有10次,导致一直连接不上。
解放办法:增加以下重试次数以及重试间隔时间
需要在core-site.xml增加两个属性
<!-- 增加重试次数和重试时间-->
<property>
<name>ipc.client.connect.max.retries</name>
<value>100</value>
<description>Indicates the number of retries a client will make to establish a server connection.</description>
</property>
<property>
<name>ipc.client.connect.retry.interval</name>
<value>10000</value>
<description>Indicates the number of milliseconds a client will wait forbefore retrying to establish a server connection.</description>
</property>
# 直接在主节点环境上运行
start-dfs.sh
start-yarn.sh
# 验证过程,可以通过jps,按需查看各节点是否启动正常
# 也可以直接输入
hdfs haadmin -getAllServiceState
会直接显示两个节点下的主从角色信息
运维命令
# 查看NameNode主从状态
hdfs haamin -getAllServiceState
# 手动切换主从,将nn1手动切换到standby节点
hdfs haadmin -transitionToStandby --forcemanual nn1
# 手动切换主从,将nn2手动切换到Active节点
hdfs haadmin -transitionToActive --forcemanual nn2
# 查看ResouceManager的状态
yarn rmadmin -getServiceState rm1
yarn rmadmin -getServiceState rm2
yarn rmadmin -transitionToStandby --forcemanual rm1
yarn rmadmin -transitionToActive --forcemanual rm2
问题集锦
问题一: 集群在长时间运行之后,使用停止命令无法关闭。
原因分析:默认集群在启动过程中,会在/tmp目录下创建相关的pid文件,但是tmp目录会被liunx默认按时清理,即下次寻找pid信息时找不到,所以找不到相关的进程信息。
解决办法:停止应用程序,进入安全模式,停止 YARN 的 ResourceManager(主备节点),停止 HDFS 的 NameNode(主备),停止 JournalNode,停止 ZooKeeper(如果在同一节点),然后停止从节点的 DataNode 和 NodeManager,最后清理可能的残留进程。同时,强调使用官方提供的 daemon 脚本,而不是直接 kill,以确保正确释放资源和更新状态。
然后更改配置文件etc/hadoop/hadoop-env.sh中HADOOP_PID_DIR改为自定义目录路径。
问题二:启动完毕后,namenode处于安全模式中
通过执行hdfs dfsadmin -safemode leave可以移除安全模式。