詹学伟
詹学伟
Published on 2025-07-21 / 2 Visits
0
0

Hadoop HA高可用分布式集群搭建

本文主要介绍hadoop3.0 HA高可用分布式集群搭建过程,该文章是博主多次实践后而写,亲测有效!!!

需要的朋友可以按照这个步骤来搭建自己的环境~~

一、安装整体架构

主机名

NN

ZkFc

DN

JournalNode

RM

zk集群

hive

node1

✔️

✔️

✔️

✔️

✔️

✔️

node2

✔️

✔️

✔️

✔️

✔️

✔️

node3

✔️

✔️

✔️

✔️

二、配置网络

vim /etc/sysconfig/network-scripts/ifcfg-ens192

TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens192
UUID=4286bc25-a032-4150-9d69-84049c927370
DEVICE=ens192
ONBOOT=yes

IPADDR=192.168.0.23
NETMASK=255.255.255.0
GATEWAY=192.168.0.1
DNS1=8.8.8.8
DNS2=114.114.114.114

vim /etc/sysconfig/network
# Created by anaconda
NETWORKING=yes

三、关闭selinux

vim /etc/sysconfig/selinux 

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

四、主机名设置

hostnamectl set-hostname node1

五、hosts配置

vim /etc/hosts

192.168.110.23 node1
192.168.110.24 node2
192.168.110.25 node3

六、免密登录

ssh-keygen -t rsa

ssh-copy-id -i /root/.ssh/id_rsa.pub root@node1

七、时间同步

yum -y install ntpdate

ntpdate -u ntp1.aliyun.com

八、防火墙关闭

systemctl stop firewalld
systemctl disable firewalld
systemctl status firewalld

九、安装jdk并配置

1.下载

2.解压、安装并配置

十、安装hadoop并配置、启动

解决NameNode无法自动故障切换问题(三台机器都执行):

yum install -y psmisc

1.安装步骤:

1.1 下载

下载地址:

https://archive.apache.org/dist/hadoop/common/hadoop-3.3.0/

1.2 解压

tar -zvxf hadoop-3.3.0.tar.gz

1.3 重命名和移动文件位置

mv hadoop-3.3.0 /usr/local
cd /usr/local/

2.配置步骤:

2.1 hadoop-env.sh

vim hadoop-env.sh

export JAVA_HOME=/usr/local/jdk1.8.0_191
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_JOURNALNODE_USER=root
export HDFS_ZKFC_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root

2.2 core-site.xml

vim core-site.xml

<configuration>
        <!--设置默认使用的文件系统Hadoop支持fi1e、HDFS、GFS、a1i|Amazon云等文件系统-->
        <!-- 用来指定hdfs的namenode名称-->
        <property>
                <name>fs.defaultFS</name>
                <value>hdfs://zcluster</value>
        </property>

        <!-- 用来指定hadoop运行时文件产生目录-->
        <property>
                <name>hadoop.tmp.dir</name>
                <value>/usr/local/hadoop-3.3.0/hdfs/temp</value>
        </property>

        <!-- 指定zookeeper地址-->
        <property>
                <name>ha.zookeeper.quorum</name>
                <value>node1:2181,node2:2181,node3:2181</value>
        </property>

        <!-- 当前用户全设置成root -->
        <property>
                <name>hadoop.http.staticuser.user</name>
                <value>root</value>
        </property>

        <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 for before retrying to establish a server connection.</description>
        </property>

        <!--整合hive用户代理设置-->
        <property>
                <name>hadoop.proxyuser.root.hosts</name>
                <value>*</value>
        </property>

        <property>
                <name>hadoop.proxyuser.root.groups</name>
                <value>*</value>
        </property>

        <!--文件系统垃圾桶保存时间-->
        <property>
                <name>fs.trash.interval</name>
                <value>1440</value>
        </property>
</configuration>

2.3 hdfs-site.xml

vim hdfs-site.xml

<configuration>
        <!--配置分片的数量-->
        <property>
                <name>dfs.replication</name>
                <value>3</value>
                <description>分片数量</description>
        </property>

        <!--指定hdfs的nameservice为ns1,需要和core-site.xml中的保持一致 -->
        <property>
                <name>dfs.nameservices</name>
                <value>zcluster</value>
                <description>为namenode集群定义一个services name</description>
        </property>

        <!-- ns1下面有两个NameNode,分别是nn1,nn2 -->
        <property>
                <name>dfs.ha.namenodes.zcluster</name>
                <value>nn1,nn2</value>
                <description>nameservice包含哪些namenode,为各个namenode起名</description>
        </property>

        <property>
                <name>dfs.namenode.rpc-address.zcluster.nn1</name>
                <value>node1:8020</value>
                <description> 名为nn1的namenode 的rpc地址和端口号,rpc用来和datanode通讯</description>
        </property>

        <property>
                <name>dfs.namenode.rpc-address.zcluster.nn2</name>
                <value>node2:8020</value>
                <description> 名为nn2的namenode 的rpc地址和端口号,rpc用来和datanode通讯</description>
        </property>

        <property>
                <name>dfs.namenode.http-address.zcluster.nn1</name>
                <value>node1:50070</value>
                <description> 名为nn1的namenode 的http地址和端口号,web客户端</description>
        </property>

        <property>
                <name>dfs.namenode.http-address.zcluster.nn2</name>
                <value>node2:50070</value>
                <description> 名为nn2的namenode 的http地址和端口号,web客户端</description>
        </property>

        <!--默认情况下,hadoop 在NameNode所在机器里运行SecondaryNameNode,http监听端口是50090,在浏览器输入NameNode的地址和50090端口号,为了安全分别放到两台机器上,在浏览器输入NameNode的地址和50090端口号,就可看到其信息-->
        <property>
                <name>dfs.namenode.secondary.http-address</name>
                <value>node2:50090</value>
                <description>命名空间和事务在本地文件系统永久存储的路径</description>
        </property>

        <!-- 指定NameNode的元数据在JournalNode上的存放位置,这样nameNode2可以从Jn集群中获得最新的nameNode信息 -->
        <property>
                <name>dfs.namenode.shared.edits.dir</name>
                <value>qjournal://node1:8485;node2:8485;node3:8485/zcluster</value>
                <description>namenode间用于共享编辑日志的journal节点列表</description>
        </property>

        <!-- 指定journal的存放位置 -->
        <property>
                <name>dfs.journalnode.edits.dir</name>
                <value>/usr/local/hadoop-3.3.0/hdfs/journaldata</value>
                <description>journalnode上用于存放edits日志的目录</description>
        </property>

        <!--配置nameNode数据存放位置-->
        <property>
                <name>dfs.namenode.name.dir</name>
                <value>/usr/local/hadoop-3.3.0/hdfs/name</value>
                <description>在本地文件系统所在的NameNode的存储空间和持续化处理日志</description>
        </property>

        <property>
                <name>dfs.datanode.data.dir</name>
                <value>/usr/local/hadoop-3.3.0/hdfs/data</value>
                <description>数据节点的块本地存放目录</description>
        </property>

        <!-- HDFS的HA功能的防脑裂方法。可以是内建的方法(例如shell和sshfence)或者用户定义的方法。建议使用sshfence(hadoop:9922),括号内的是用户名和端口,注意,这需要NN的2台机器之间能够免密码登陆fences是防止脑裂的方法,保证NN中仅一个是Active的,如果2者都是Active的,新的会把旧的强制Kill。 -->
        <!-- 配置隔离机制 -->
        <property>
                <name>dfs.ha.fencing.methods</name>
                <value>sshfence</value>
                <description>配置隔离机制</description>
        </property>

        <!-- ssh 登录秘钥坐在位置 -->
        <property>
                <name>dfs.ha.fencing.ssh.private-key-files</name>
                <value>/root/.ssh/id_rsa</value>
                <description>密钥认证文件</description>
        </property>

        <!-- nameNode故障时自动切换-->
        <property>
                <name>dfs.ha.automatic-failover.enabled</name>
                <value>true</value>
                <description>是否开启自动故障转移。建议开启,true</description>
        </property>

        <!-- 配置切换实现方式-->
        <property>
                <name>dfs.client.failover.proxy.provider.zcluster</name>
                <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
                <description>客户端连接可用状态的NameNode所用的代理类</description>
        </property>

        <!--namenode的hdfs-site.xml是必须将dfs.webhdfs.enabled属性设置为true,否则就不能使用webhdfs的LISTSTATUS、LISTFILESTATUS等需要列出文件、文件夹状态的命令,因为这些信息都是由namenode来保存的。-->
        <property>
                <name>dfs.webhdfs.enabled</name>
                <value>true</value>
        </property>

        <property>
                <!-- JournalNode的HTTP地址和端口。-->
                <name>dfs.journalnode.http-address</name>
                <value>0.0.0.0:8480</value>
        </property>

        <property>
                <!-- JournalNode RPC服务地址和端口-->
                <name>dfs.journalnode.rpc-address</name>
                <value>0.0.0.0:8485</value>
        </property>

        <!-- 配置hdfs的操作权限,false表示任何人都有权限 -->
        <property>
                <!-- 是否在HDFS中开启权限检查。为了避免权限检查可以设置为false或使用命令hadoop fs -chmod -R 777 /-->
                <name>dfs.permissions.enabled</name>
                <value>true</value>
        </property>

        <!-- 默认情况下ACLs是关闭的,想要开启此功能需要在hdfs-site.xml的配置项里找到dfs.namenode.acls.enabled把属性设为true才可以。文件系统提供更精细化的权限控制。/-->
        <property>
                <!-- 是否在hdfs开启acl,默认为false-->
                <name>dfs.namenode.acls.enabled</name>
                <value>true</value>
        </property>
        
        <property>
                <name>dfs.qjournal.write-txns.timeout.ms</name>
                <value>60000</value>
        </property>

        <!-- 默认情况下,用户在HDFS上创建的文件和目录的权限是rwxr-xr-x,即732,x表示有ls权限。032表示屏蔽位,默认权限是777-屏蔽位对应的数字,因此,777-032=745, 745是权限位 /-->
        <property>
                <name>fs.permissions.umask-mode</name>
                <value>032</value>
        </property>
</configuration>

2.4 mapred-site.xml

vim mapred-site.xml

<configuration>
        <property>
                <name>mapreduce.framework.name</name>
                <value>yarn</value>
        </property>
        
        <property>
                <name>yarn.app.mapreduce.am.env</name>
                <value>HADOOP_MAPRED_HOME=/usr/local/hadoop-3.3.0</value>
        </property>
        
        <property>
                <name>mapreduce.map.env</name>
                <value>HADOOP_MAPRED_HOME=/usr/local/hadoop-3.3.0</value>
        </property>
        
        <property>
                <name>mapreduce.reduce.env</name>  
                <value>HADOOP_MAPRED_HOME=/usr/local/hadoop-3.3.0</value>
        </property>
    
        <property>
                <name>mapreduce.jobhistory.address</name>
                <value>node1:10020</value>
        </property>
    
        <property>
                <name>mapreduce.jobhistory.webapp.address</name>
                <value>node1:19888</value>
        </property>
</configuration>

2.5 yarn-site.xml

vim yarn-site.xml

<configuration>
        <!--启用resourcemanager的HA-->
        <property>
                <name>yarn.resourcemanager.ha.enabled</name>
                <value>true</value>
        </property>

        <!--集群标识-->
        <property>
                <name>yarn.resourcemanager.cluster-id</name>
                <value>cluster-yarn</value>
        </property>

        <!--resourcemanager的主机名标识符-->
        <property>
                <name>yarn.resourcemanager.ha.rm-ids</name>
                <value>rm1,rm2</value>
        </property>

        <!--resourcemanager的主机名-->
        <property>
                <name>yarn.resourcemanager.hostname.rm1</name>
                <value>node1</value>
        </property>

        <property>
                <name>yarn.resourcemanager.hostname.rm2</name>
                <value>node2</value>
        </property>

        <!--对每个rm-id指定RM https webapp相应的host:port。-->
        <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>

        <!--开启ResourceManager故障自动切换-->
        <property>
                <name>yarn.resourcemanager.ha.automatic-failover.enabled</name>
                <value>true</value>
        </property>

        <!--RM故障自动恢复-->
        <property>
                <name>yarn.resuorcemanager.recovery.enabled</name>
                <value>true</value>
        </property>

        <!--zookeeper的地址,使用ZK集群保存状态信息,指定zookeeper队列。-->
        <property>
                <name>yarn.resourcemanager.zk-address</name>
                <value>node1:2181,node2:2181,node3:2181</value>
        </property>

        <!--配置RM状态信息存储方式,有MemStore和ZKStore-->
        <property>
                <name>yarn.resourcemanager.store.class</name>
                <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
        </property>

        <!-- NodeManager上运行的附属服务。需配置成mapreduce_shuffle,才可运行MapReduce程序-->
        <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.log-aggregation-enable</name>
                <value>true</value>
        </property>
       
        <!--日志聚合存放时间-->
        <property>
                <name>yarn.log-aggregation.retain-seconds</name>
                <value>604800</value>
        </property>
        
        <!--日志聚合服务器URL-->
        <property>
            <name>yarn.log.server.url</name>
            <value>http://node1:19888/jobhistory/logs</value>
        </property>
        
        <!--日志聚合目录-->
        <property>
                <name>yarn.nodemanager.remote-app-log-dir</name>
                <value>hdfs://zcluster/tmp/yarn-logs</value>
        </property>
</configuration>

配置workers

vim workers
node1
node2
node3

注意:配置完成后,记得分发文件到各个节点。

3.启动步骤:

第一次启动需要格式化操作,格式化操作只需要执行一次,后面再次启动不需要格式化

3.1 启动zookeeper(三台机器)

zkServer.sh start

3.2 启动journalnode(三台机器)

hdfs --daemon start journalnode

3.3 格式化namenode(master节点执行)

hdfs namenode -format

3.4 启动namenode(master节点执行,第一台namenode节点执行)

hdfs --daemon start namenode

3.5 secondarynamenode同步namenode信息(第二台namenode节点执行)

hdfs namenode -bootstrapStandby

3.6 启动第二个namenode(第二台namenode节点执行)

hdfs --daemon start namenode

3.7 格式化zk(master节点执行)

hdfs zkfc -formatZK

3.8 启动hdfs

start-dfs.sh

3.9 启动yarn

start-yarn.sh

3.8、3.9可以合并:start-all.sh

启动jobhistory

mr-jobhistory-daemon.sh start historyserver

3.10 访问

3.10.1 hdfs网页

http://node3:50070/dfshealth.html#tab-overview
http://node4:50070/dfshealth.html#tab-overview

3.10.2 yarn网页

http://node4:8088/cluster

测试高可用

咱们可以停掉active状态的namenode,看standby的namenode是否可以自动接管变为active状态:

hadoop-daemon.sh start namenode
hadoop-daemon.sh sttop namenode


Comment