配置高可用的Hadoop平台

发布于 2024-09-07 18:45:56 字数 22069 浏览 23 评论 0

1.概述

在 Hadoop2.x 之后的版本,提出了解决单点问题的方案--HA(High Available 高可用)。这篇博客阐述如何搭建高可用的 HDFS 和 YARN,执行步骤如下:

  1. 创建 hadoop 用户
  2. 安装 JDK
  3. 配置 hosts
  4. 安装 SSH
  5. 关闭防火墙
  6. 修改时区
  7. ZK(安装,启动,验证)
  8. HDFS+HA 的结构图
  9. 角色分配
  10. 环境变量配置
  11. 核心文件配置
  12. slave
  13. 启动命令(hdfs 和 yarn 的相关命令)
  14. HA 的切换
  15. 效果截图

下面我们给出下载包的链接地址:

JDK 下载地址

注: 若 JDK 无法下载,请到 Oracle 的官网下载 JDK。

到这里安装包都准备好了,接下来我们开始搭建与配置。

2.搭建

2.1 创建 Hadoop 用户

useradd hadoop
passwd hadoop

然后根据提示,设置密码。接着我给 hadoop 用户设置面免密码权限,也可自行添加其他权限。

chmod +w /etc/sudoers 
hadoop ALL=(root)NOPASSWD:ALL 
chmod -w /etc/sudoers

2.2 安装 JDK

将下载好的安装包解压到 /usr/java/jdk1.7,然后设置环境变量,命令如下:

sudo vi /etc/profile

然后编辑配置,内容如下:

export JAVA_HOME=/usr/java/jdk1.7
export PATH=$PATH:$JAVA_HOME/bin

然后使环境变量立即生效,命令如下:

source /etc/profile

然后验证 JDK 是否配置成功,命令如下:

java -version

若显示对应版本号,即表示 JDK 配置成功。否则,配置无效!

2.3 配置 hosts

集群中所有机器的 hosts 配置要要相同(推荐)。可以避免不必要的麻烦,用域名取代 IP,方便配置。配置信息如下:

10.211.55.12    nna# NameNode Active
10.211.55.13    nns# NameNode Standby
10.211.55.14    dn1# DataNode1
10.211.55.15    dn2# DataNode2
10.211.55.16    dn3# DataNode3

然后用 scp 命令,将 hosts 配置分发到各个节点。命令如下:

# 这里以 NNS 节点为例子
scp /etc/hosts hadoop@nns:/etc/

2.4 安装 SSH

输入如下命令:

ssh-keygen –t rsa

然后一路按回车键,最后在将 id_rsa.pub 写到 authorized_keys,命令如下:

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

在 hadoop 用户下,需要给 authorized_keys 赋予 600 的权限,不然免密码登陆无效。在其他节点只需要使用 ssh-keygen –t rsa 命令,生产对应的公钥,然后将各个节点的 id_rsa.pub 追加到 nna 节点的 authorized_keys 中。最后,将 nna 节点下的 authorized_keys 文件通过 scp 命令,分发到各个节点的 ~/.ssh/ 目录下。目录如下:

# 这里以 NNS 节点为例子
scp ~/.ssh/authorized_keys hadoop@nns:~/.ssh/

然后使用 ssh 命令相互登录,看是否实现了免密码登录,登录命令如下:

# 这里以 nns 节点为例子
ssh nns

若登录过程中木有提示需要输入密码,即表示密码配置成功。

2.5 关闭防火墙

由于 hadoop 的节点之间需要通信(RPC 机制),这样一来就需要监听对应的端口,这里我就直接将防火墙关闭了,命令如下:

chkconfig  iptables off

注:如果用于生产环境,直接关闭防火墙是存在安全隐患的,我们可以通过配置防火墙的过滤规则,即将 hadoop 需要监听的那些端口配置到防火墙接受规则中。关于防火墙的规则配置参见“linux 防火墙配置”,或者通知公司的运维去帮忙配置管理。

同时,也需要关闭 SELinux,可修改 /etc/selinux/config 文件,将其中的 SELINUX=enforcing 改为 SELINUX=disabled 即可。

2.6 修改时区

各个节点的时间如果不同步,会出现启动异常,或其他原因。这里将时间统一设置为 Shanghai 时区。命令如下:

# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
cp: overwrite `/etc/localtime'? yes
修改为中国的东八区
# vi /etc/sysconfig/clock
ZONE="Asia/Shanghai"
UTC=false
ARC=false

2.7ZK(安装,启动,验证)

2.7.1 安装

将下载好的安装包,解压到指定位置,这里为直接解压到当前位置,命令如下:

tar -zxvf zk-{version}.tar.gz

修改 zk 配置,将 zk 安装目录下 conf/zoo_sample.cfg 重命名 zoo.cfg,修改其中的内容:

# The number of milliseconds of each tick
# 服务器与客户端之间交互的基本时间单元(ms) 
tickTime=2000   

# The number of ticks that the initial  
# synchronization phase can take 
# zookeeper 所能接受的客户端数量 
initLimit=10  

# The number of ticks that can pass between  
# sending a request and getting an acknowledgement 
# 服务器和客户端之间请求和应答之间的时间间隔 
syncLimit=5

# the directory where the snapshot is stored. 
# do not use /tmp for storage, /tmp here is just  
# example sakes. 
# 保存 zookeeper 数据,日志的路径
dataDir=/home/hadoop/data/zookeeper

# the port at which the clients will connect 
# 客户端与 zookeeper 相互交互的端口 
clientPort=2181 
server.1= dn1:2888:3888 
server.2= dn2:2888:3888 
server.3= dn3:2888:3888

#server.A=B:C:D
#其中 A 是一个数字,代表这是第几号服务器;B 是服务器的 IP 地址;
#C 表示服务器与群集中的“领导者”交换信息的端口;当领导者失效后,D 表示用来执行选举时服务器相互通信的端口。

接下来,在配置的 dataDir 目录下创建一个 myid 文件,里面写入一个 0-255 之间的一个随意数字,每个 zk 上这个文件的数字要是不一样的,这些数字应该是从 1 开始,依次写每个服务器。文件中序号要与 dn 节点下的 zk 配置序号一直,如:server.1=dn1:2888:3888,那么 dn1 节点下的 myid 配置文件应该写上 1。

2.7.2 启动

分别在各个 dn 节点启动 zk 进程,命令如下:

bin/zkServer.sh start

然后,在各个节点输入 jps 命令,会出现如下进程:

QuorumPeerMain

2.7.3 验证

上面说的输入 jps 命令,若显示对应的进程,即表示启动成功,同样我们也可以输入 zk 的状态命令查看,命令如下:

bin/zkServer.sh status

会出现一个 leader 和两个 follower。

2.8HDFS+HA 的结构图

HDFS 配置 HA 的结构图如下所示:

上图大致架构包括:

1. 利用共享存储来在两个 NN 间同步 edits 信息。以前的 HDFS 是 share nothing but NN,现在 NN 又 share storage,这样其实是转移了单点故障的位置,但中高端的存储设备内部都有各种 RAID 以及冗余硬件,包括电源以及网卡等,比服务器的可靠性还是略有 提高。通过 NN 内部每次元数据变动后的 flush 操作,加上 NFS 的 close-to-open,数据的一致性得到了保证。

2. DN 同时向两个 NN 汇报块信息。这是让 Standby NN 保持集群的最新状态的必须步骤。

3. 用于监视和控制 NN 进程的 FailoverController 进程。显然,我们不能在 NN 进程内部进行心跳等信息同步,最简单的原因,一次 FullGC 就可以让 NN 挂起十几分钟,所以,必须要有一个独立的短小精悍的 watchdog 来专门负责监控。这也是一个松耦合的设计,便于扩展或更改,目前版本里是 用 ZooKeeper(简称 ZK)来做同步锁,但用户可以方便的把这个 Zookeeper FailoverController(简称 ZKFC)替换为其他的 HA 方案或 leader 选举方案。

4. 隔离(Fencing),防止脑裂,就是保证在任何时候只有一个主 NN,包括三个方面:

  共享存储 fencing,确保只有一个 NN 可以写入 edits。

  客户端 fencing,确保只有一个 NN 可以响应客户端的请求。

  DN fencing,确保只有一个 NN 向 DN 下发命令,譬如删除块,复制块等等。

2.9 角色分配

名称

Host

职责

NNA

10.211.55.12

zkfc

NNS

10.211.55.13

zkfc

DN1

10.211.55.14

zookeeper

DN2

10.211.55.15

zookeeper

DN3

10.211.55.16

zookeeper

2.10 环境变量配置

这里列出了所有的配置,后面配置其他组件,可以参考这里的配置。 配置完成后,输入:. /etc/profile(或 source /etc/profile)使之立即生效。严重是否环境变量配置成功与否,输入:echo $HADOOP_HOME,若输出对应的配置路径,即可认定配置成功。

注:hadoop2.x 以后的版本 conf 文件夹改为 etc 文件夹了

配置内容如下所示:

export JAVA_HOME=/usr/java/jdk1.7 
export HADOOP_HOME=/home/hadoop/hadoop-2.6.0 
export ZK_HOME=/home/hadoop/zookeeper-3.4.6 
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOM

2.11 核心文件配置

注:这里特别提醒,配置文件中的路径在启动集群之前,得存在(若不存在,请事先创建)。下面为给出本篇文章需要创建的路径脚本,命令如下:

mkdir -p /home/hadoop/tmp
mkdir -p /home/hadoop/data/tmp/journal
mkdir -p /home/hadoop/data/dfs/name
mkdir -p /home/hadoop/data/dfs/data
mkdir -p /home/hadoop/data/yarn/local
mkdir -p /home/hadoop/log/yarn
  • core-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://cluster1</value>
    </property>

    <property>
        <name>io.file.buffer.size</name>
        <value>131072</value>
    </property>
    <property>
        <name>hadoop.tmp.dir</name>
        <value>/home/hadoop/tmp</value>
    </property>
    <property>
        <name>hadoop.proxyuser.hduser.hosts</name>
        <value>*</value>
    </property>
    <property>
        <name>hadoop.proxyuser.hduser.groups</name>
        <value>*</value>
    </property>
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>dn1:2181,dn2:2181,dn3:2181</value>
    </property>
</configuration>
  • hdfs-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property>
        <name>dfs.nameservices</name>
        <value>cluster1</value>
    </property>
    <property>
        <name>dfs.ha.namenodes.cluster1</name>
        <value>nna,nns</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.cluster1.nna</name>
        <value>nna:9000</value>
    </property>
    <property>
        <name>dfs.namenode.rpc-address.cluster1.nns</name>
        <value>nns:9000</value>
    </property>

    <property>
        <name>dfs.namenode.http-address.cluster1.nna</name>
        <value>nna:50070</value>
    </property>

    <property>
        <name>dfs.namenode.http-address.cluster1.nns</name>
        <value>nns:50070</value>
    </property>
    <property>
        <name>dfs.namenode.shared.edits.dir</name>
        <value>qjournal://dn1:8485;dn2:8485;dn3:8485/cluster1</value>
    </property>

    <property>
        <name>dfs.client.failover.proxy.provider.cluster1</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/hadoop/.ssh/id_rsa</value>
    </property>
    <property>
        <name>dfs.journalnode.edits.dir</name>
        <value>/home/hadoop/data/tmp/journal</value>
    </property>
    <property>
        <name>dfs.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/home/hadoop/data/dfs/name</value>
    </property>
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/home/hadoop/data/dfs/data</value>
    </property>
    <property>
        <name>dfs.replication</name>
        <value>3</value>
    </property>
    <property>
        <name>dfs.webhdfs.enabled</name>
        <value>true</value>
    </property>

    <property>
        <name>dfs.journalnode.http-address</name>
        <value>0.0.0.0:8480</value>
    </property>
    <property>
        <name>dfs.journalnode.rpc-address</name>
        <value>0.0.0.0:8485</value>
    </property>
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>dn1:2181,dn2:2181,dn3:2181</value>
    </property>

</configuration>
  • map-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.address</name>
        <value>nna:10020</value>
    </property>
    <property>
        <name>mapreduce.jobhistory.webapp.address</name>
        <value>nna:19888</value>
    </property>
</configuration>
  • yarn-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property>
        <name>yarn.resourcemanager.connect.retry-interval.ms</name>
        <value>2000</value>
    </property>
    <property>
        <name>yarn.resourcemanager.ha.enabled</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.resourcemanager.ha.rm-ids</name>
        <value>rm1,rm2</value>
    </property>
    <property>
        <name>ha.zookeeper.quorum</name>
        <value>dn1:2181,dn2:2181,dn3:2181</value>
    </property>

    <property>
        <name>yarn.resourcemanager.ha.automatic-failover.enabled</name>
        <value>true</value>
    </property>
    <property>
        <name>yarn.resourcemanager.hostname.rm1</name>
        <value>nna</value>
    </property>

    <property>
        <name>yarn.resourcemanager.hostname.rm2</name>
        <value>nns</value>
    </property>
    <!--在 namenode1 上配置 rm1,在 namenode2 上配置 rm2,注意:一般都喜欢把配置好的文件远程复制到其它机器上,但这个在 YARN 的另一个机器上一定要修改 -->
    <property>
        <name>yarn.resourcemanager.ha.id</name>
        <value>rm1</value>
    </property>
    <!--开启自动恢复功能 -->
    <property>
        <name>yarn.resourcemanager.recovery.enabled</name>
        <value>true</value>
    </property>
    <!--配置与 zookeeper 的连接地址 -->
    <property>
        <name>yarn.resourcemanager.zk-state-store.address</name>
        <value>dn1:2181,dn2:2181,dn3:2181</value>
    </property>
    <property>
        <name>yarn.resourcemanager.store.class</name>
        <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value>
    </property>
    <property>
        <name>yarn.resourcemanager.zk-address</name>
        <value>dn1:2181,dn2:2181,dn3:2181</value>
    </property>
    <property>
        <name>yarn.resourcemanager.cluster-id</name>
        <value>cluster1-yarn</value>
    </property>
    <!--schelduler 失联等待连接时间 -->
    <property>
        <name>yarn.app.mapreduce.am.scheduler.connection.wait.interval-ms</name>
        <value>5000</value>
    </property>
    <!--配置 rm1 -->
    <property>
        <name>yarn.resourcemanager.address.rm1</name>
        <value>nna:8132</value>
    </property>
    <property>
        <name>yarn.resourcemanager.scheduler.address.rm1</name>
        <value>nna:8130</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address.rm1</name>
        <value>nna:8188</value>
    </property>
    <property>
        <name>yarn.resourcemanager.resource-tracker.address.rm1</name>
        <value>nna:8131</value>
    </property>
    <property>
        <name>yarn.resourcemanager.admin.address.rm1</name>
        <value>nna:8033</value>
    </property>
    <property>
        <name>yarn.resourcemanager.ha.admin.address.rm1</name>
        <value>nna:23142</value>
    </property>
    <!--配置 rm2 -->
    <property>
        <name>yarn.resourcemanager.address.rm2</name>
        <value>nns:8132</value>
    </property>
    <property>
        <name>yarn.resourcemanager.scheduler.address.rm2</name>
        <value>nns:8130</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address.rm2</name>
        <value>nns:8188</value>
    </property>
    <property>
        <name>yarn.resourcemanager.resource-tracker.address.rm2</name>
        <value>nns:8131</value>
    </property>
    <property>
        <name>yarn.resourcemanager.admin.address.rm2</name>
        <value>nns:8033</value>
    </property>
    <property>
        <name>yarn.resourcemanager.ha.admin.address.rm2</name>
        <value>nns:23142</value>
    </property>
    <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.nodemanager.local-dirs</name>
        <value>/home/hadoop/data/yarn/local</value>
    </property>
    <property>
        <name>yarn.nodemanager.log-dirs</name>
        <value>/home/hadoop/log/yarn</value>
    </property>
    <property>
        <name>mapreduce.shuffle.port</name>
        <value>23080</value>
    </property>
    <!--故障处理类 -->
    <property>
        <name>yarn.client.failover-proxy-provider</name>
        <value>org.apache.hadoop.yarn.client.ConfiguredRMFailoverProxyProvider</value>
    </property>
    <property>
        <name>yarn.resourcemanager.ha.automatic-failover.zk-base-path</name>
        <value>/yarn-leader-election</value>
    </property>
</configuration>
  • hadoop-env.sh
# The java implementation to use.
export JAVA_HOME=/usr/java/jdk1.7
  • yarn-env.sh
# some Java parameters
export JAVA_HOME=/usr/java/jdk1.7
  • 2.12slave

修改 hadoop 安装目录下的 slave 文件:

dn1
dn2
dn3

2.13 启动命令(hdfs 和 yarn 的相关命令)

由于我们配置了 QJM,所以我们需要先启动 QJM 的服务,启动顺序如下所示:

  1. 进入到 DN 节点,启动 zk 的服务:zkServer.sh start,之后可以输入zkServer.sh status查看启动状态,本次我们配置了三个 DN 节点,会出现一个 leader 和两个 follower。输入jps,会显示启动进程: QuorumPeerMain
  2. 在 NN 节点上(选一台即可,这里我选择的是一台预 NNA 节点),然后启动 journalnode 服务,命令如下:hadoop-daemons.sh start journalnode。或者单独进入到每个 DN 输入启动命令:hadoop-daemon.sh start journalnode。输入 jps 显示启动进程:JournalNode
  3. 接着若是配置后,我们首次启动,需要格式化 HDFS,命令如下:hadoop namenode –format
  4. 之后我们需要格式化 ZK,命令如下:hdfs zkfc –formatZK
  5. 接着我们启动 hdfs 和 yarn,命令如下:start-dfs.shstart-yarn.sh,我们在 nna 输入 jps 查看进程,显示如下:DFSZKFailoverControllerNameNodeResourceManager
  6. 接着我们在 NNS 输入 jps 查看,发现只有DFSZKFailoverController进程,这里我们需要手动启动 NNS 上的namenodeResourceManager进程,命令如下:hadoop-daemon.sh start namenodeyarn-daemon.sh start resourcemanager。需要注意的是,在 NNS 上的 yarn-site.xml 中,需要配置指向 NNS,属性配置为 rm2,在 NNA 中配置的是 rm1。
  7. 最后我们需要同步 NNA 节点的元数据,命令如下:hdfs namenode –bootstrapStandby,若执行正常,日志最后显示如下信息:
15/02/21 10:30:59 INFO common.Storage: Storage directory /home/hadoop/data/dfs/name has been successfully formatted. 
15/02/21 10:30:59 WARN common.Util: Path /home/hadoop/data/dfs/name should be specified as a URI in configuration files. Please update hdfs configuration. 
15/02/21 10:30:59 WARN common.Util: Path /home/hadoop/data/dfs/name should be specified as a URI in configuration files. Please update hdfs configuration. 
15/02/21 10:31:00 INFO namenode.TransferFsImage: Opening connection to http://nna:50070/imagetransfer?getimage=1&txid=0&storageInfo=-60:1079068934:0:CID-1dd0c11e-b27e-4651-aad6-73bc7dd820bd 
15/02/21 10:31:01 INFO namenode.TransferFsImage: Image Transfer timeout configured to 60000 milliseconds 
15/02/21 10:31:01 INFO namenode.TransferFsImage: Transfer took 0.01s at 0.00 KB/s 
15/02/21 10:31:01 INFO namenode.TransferFsImage: Downloaded file fsimage.ckpt_0000000000000000000 size 353 bytes. 
15/02/21 10:31:01 INFO util.ExitUtil: Exiting with status 0 
15/02/21 10:31:01 INFO namenode.NameNode: SHUTDOWN_MSG:  /************************************************************ SHUTDOWN_MSG: Shutting down NameNode at nns/10.211.55.13 ************************************************************/

2.14HA 的切换

由于我配置的是自动切换,若 NNA 节点宕掉,NNS 节点会立即由 standby 状态切换为 active 状态。若是配置的手动状态,可以输入如下命令进行人工切换:

hdfs haadmin -failover --forcefence --forceactive nna  nns

这条命令的意思是,将 nna 变成 standby,nns 变成 active。而且手动状态下需要重启服务。

2.15 效果截图

3.总结

这篇文章就赘述到这里,若在配置过程中有什么疑问或问题,可以加入 QQ 群讨论或发送邮件给我,我会尽我所能为您解答,与君共勉!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

蓝眼泪

暂无简介

文章
评论
27 人气
更多

推荐作者

迎风吟唱

文章 0 评论 0

qq_hXErI

文章 0 评论 0

茶底世界

文章 0 评论 0

捎一片雪花

文章 0 评论 0

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文