完全解析大数据的高可用集群部署

HA介绍

什么是HA

HA: High Availability,高可用集群,指的是集群7*24小时不间断服务。

为什么需要HA

在HDFS中,有NameNode、DataNode和SecondaryNameNode角色的分布,客户端所有的操作都是要与NameNode交互的,同时整个集群的命名空间信息也都保存在NameNode节点。但是,现在的集群配置中只有一个NameNode,于是就有一个问题: 单点故障

那么,什么是单点故障呢?现在集群中只有一个NameNode,那么假如这个NameNode意外宕机、升级硬件等,导致NameNode不可用了,整个集群是不是也就不可用了?这就是单点故障的问题。

为了解决这样的问题,就需要高可用集群了。

高可用的备份方式

  • 主从模式(冷备) 

准备两台服务器, 准备相同的程序。 一台服务器对外提供服务, 称为主节点(Active节点); 另外一台服务器平时不对外提供服务, 主要负责和Active节点之间进行数据的同步, 称为备份节点(Standby节点). 当主节点出现故障, Standby节点可以自动提升为Active节点, 对外提供服务。
 ZooKeeper实现的集群高可用, 采用的就是这种模式。

我作为一个班级的讲师,在班级负责授课的工作。如果我有一天生病请假了,是不是咱们班级就得自习一天了?为了解决这样的问题,教学部安排另外一个讲师,每天跟着我。我上课讲课,他就在旁边听着;我上课提问问题,他就在旁边看着;我去吃饭,他也在旁边跟着;我去上个厕所,他也在跟着!做为我的一个影子存在着。由于这个同时每天都会跟着我,因此我的一言一行,讲了什么内容,留了什么作业,吃了什么饭,抽了几根烟,他都知道!那么,如果有一天我生病请假了,他是不是就可以直接替代我为班级上课呢?

  • 双主互备(热备)(了解)

 准备两台服务器, 准备相同的程序. 同时对外提供服务(此时, 这两台服务器彼此为对方的备份), 这样, 当一台节点宕机的时候, 另外一台节点还可以继续提供服务. 

小明到肯德基吃饭,找服务员点餐,这是正常的流程。但是,如果服务员只有一个,并且恰好生病了,那么小明是不是将没有办法正常点餐了。为了解决这个问题,肯德基雇了两个服务员,同时提供服务,这样一个服务员出问题了,另外一个服务员依然可以提供服务。

  • 集群多备(了解) 

基本上等同于双主互备, 区别就在于同时对外提供服务的节点数量更多, 备份数量更多  肯德基觉得两个服务员也不保险,有两个同时生病的可能性,于是又多雇了几个服务员。

高可用的实现

我们在这里采用的是主从模式的备份方式,也就是准备两个NameNode,一个对外提供服务,称为Active节点;另外一个不对外提供服务,只是实时的同步Active节点的数据,称为Standby的节点。

为了提供快速的故障转移,Standby节点还必须具有集群中块位置的最新信息。为了实现这一点,DataNodes被配置了两个NameNodes的位置,并向两者发送块位置信息和心跳信号。也就是说,DataNode同时向两个NameNode心跳反馈。

高可用架构图

完全解析大数据的高可用集群部署_第1张图片

JournalNode

  • JournalNode的功能 

Hadoop2.x版本之后, Clouera提出了QJM/QuromJournal Manager, 这是一个基于Paxos算法实现的HA的实现方案
 
 1. 基本的原理就是使用2N+1台JN存储EditLog, 每次写入数据的时候, 有半数以上的JN返回成功的信息, 就表示本次的操作已经同步到了JN
 
 2. 在HA中, SecondaryNameNode这个角色已经不存在了, 保证Standby节点的元数据信息与Active节点的元数据信息一致, 需要通过若干个JN
 
 3. 当有任何的操作发生在Active节点上的时候, JN会记录这些操作到半数以上的节点中. Standby节点检测JN中的log日志文件发生了变化, 会读取JN中的数据到自己的内存中, 维护最新的目录树结构与元数据信息
 
 4. 当发生故障的时候, Active节点挂掉, 此时Standby节点在成为新的Active节点之前, 会将读取到的EditLog文件在自己的内存中进行推演, 得到最新的目录树结构. 此时再升为Active节点, 可以无缝的继续对外提供服务.

  • 防止脑裂的发生 

对于HA群集的正确操作至关重要,一次只能有一个NameNode处于Active状态。否则,名称空间状态将在两者之间迅速分散,从而有数据丢失或其他不正确结果的风险。为了确保该属性并防止所谓的“裂脑情况”,JournalNode将一次仅允许单个NameNode成为作者。在故障转移期间,变为活动状态的NameNode将仅承担写入JournalNodes的角色,这将有效地防止另一个NameNode继续处于活动状态,从而使新的Active可以安全地进行故障转移。
 
 - 怎么理解脑裂?
  就是Active节点处于网络震荡状态,假死状态,Standby就转为Active。等网络震荡过后,就有两个Active了,这就是脑裂。

  • JournalNode集群正常工作的条件

 - 至少3个Journalnode节点
 - 运行个数建议奇数个(3,5,7等)
 - 满足(n+1)/2个以上,才能正常服务。即能容忍(n-1)/2个故障。

  • JournalNode的缺点

在这种模式下,即使活动节点发生故障,系统也不会自动触发从活动NameNode到备用NameNode的故障转移,必须需要人为的操作才行。要是有一个能监视Active节点的服务功能就好了。
这个时候,我们就可以使用zookeeper集群服务,来帮助我们进行自动容灾了。

自动容灾原理

如果想进行HA的自动故障转移,那么需要为HDFS部署两个新组件:ZooKeeper quorum和ZKFailoverController进程(缩写为ZKFC)

Zookeeper quorum

Apache ZooKeeper是一项高可用性服务,用于维护少量的协调数据,将数据中的更改通知客户端并监视客户端的故障。HDFS自动故障转移的实现依赖ZooKeeper进行以下操作:

 - 故障检测
  集群中的每个NameNode计算机都在ZooKeeper中维护一个持久性会话。如果计算机崩溃,则ZooKeeper会话将终止,通知另一个NameNode应触发故障转移。
 
 - 活动的NameNode选举(HA的第一次启动)
  ZooKeeper提供了一种简单的机制来专门选举一个节点为活动的节点。如果当前活动的NameNode崩溃,则另一个节点可能会在ZooKeeper中采取特殊的排他锁,指示它应成为下一个活动的NameNode。

ZKFC

ZKFailoverController(ZKFC)是一个新组件,它是一个ZooKeeper客户端,它监视和管理namenode的状态。运行namenode的每台机器都会运行一个ZKFC,该ZKFC负责以下内容:

 - 运行状况监视
  ZKFC使用运行状况检查命令定期ping其本地NameNode。只要NameNode以健康状态及时响应,ZKFC就会认为该节点是健康的。如果节点崩溃,冻结或以其他方式进入不正常状态,则运行状况监视器将其标记为不正常。
 
 - ZooKeeper会话管理
  当本地NameNode运行状况良好时,ZKFC会在ZooKeeper中保持打开的会话。如果本地NameNode处于活动状态,则它还将持有一个特殊的“锁定” znode。该锁使用ZooKeeper对“临时”节点的支持。如果会话到期,则锁定节点将被自动删除。
 
 - 基于ZooKeeper的选举
  如果本地NameNode运行状况良好,并且ZKFC看到当前没有其他节点持有锁znode,则它本身将尝试获取该锁。如果成功,则它“赢得了选举”,并负责运行故障转移以使其本地NameNode处于活动状态。故障转移过程类似于上述的手动故障转移:首先,如有必要,将先前的活动节点隔离,然后将本地NameNode转换为活动状态。

自动容灾的过程描述

  ZKFC(是一个进程,和NN在同一个物理节点上)有两只手,分别拽着NN和Zookeeper。(监控NameNode健康状态,并向Zookeeper注册NameNode);集群一启动,2个NN谁是Active?谁又是Standby呢?
  2个ZKFC先判断自己的NN是否健康,如果健康,2个ZKFC会向zoopkeeper集群抢着创建一个节点,结果就是只有1个会最终创建成功,从而决定active地位和standby位置。如果ZKFC1抢到了节点,ZKFC2没有抢到,ZKFC2也会监控watch这个节点。如果ZKFC1的Active NN异常退出,ZKFC1最先知道,就访问ZK,ZK就会把曾经创建的节点删掉。删除节点就是一个事件,谁监控这个节点,就会调用callback回调,ZKFC2就会把自己的地位上升到active,但在此之前要先确认ZKFC1的节点是否真的挂掉?这就引入了第三只手的概念。
 
  ZKFC2通过ssh远程连接NN1尝试对方降级,判断对方是否挂了。确认真的不健康,才会真的 上升地位之active。所以ZKFC2的步骤是:
  1.创建新节点。
  2.第三只手把对方降级。
  3.把自己升级
  那如果NN都没毛病,ZKFC挂掉了呢?Zoopkeeper有一个客户端session机制,集群启动之后,2个ZKFC除了监控自己的NN,还要和Zoopkeeper建立一个tcp长连接,并各自获取自己的session。只要一方的session失效,Zoopkeeper 就会删除该方创建的节点,同时另一方创建节点,上升地位。

HA的配置

守护进程布局

qianfeng01: NameNode、DataNode、JournalNode、QuorumPeerMain、ZKFC
qianfeng02: NameNode、DataNode、JournalNode、QuorumPeerMain、ZKFC
qianfeng03: DataNode、JournalNode、QuorumPeerMain

现在,先停止HDFS的进程,修改如下的配置文件吧!

hdfs-site.xml


 
     
     
     
         dfs.nameservices
         supercluster
     
 
     
     
         dfs.ha.namenodes.supercluster
         nn1,nn2
     
 
     
     
         dfs.namenode.rpc-address.supercluster.nn1
         qianfeng01:9820
     
     
         dfs.namenode.rpc-address.supercluster.nn2
         qianfeng02:9820
     
 
     
     
         dfs.namenode.http-address.supercluster.nn1
         qianfeng01:9870
     
     
         dfs.namenode.http-address.supercluster.nn2
         qianfeng02:9870
     
     
     
     
         dfs.journalnode.edits.dir
         /usr/local/hadoop-3.3.1/tmp
     
 
     
     
     
         dfs.namenode.shared.edits.dir
         qjournal://qianfeng01:8485;qianfeng02:8485;qianfeng03:8485/journalData
     
 
     
     
         dfs.client.failover.proxy.provider.supercluster
         org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
     
 
     
     
         dfs.ha.fencing.methods
         sshfence
     
     
     
         dfs.ha.fencing.ssh.private-key-files
         /root/.ssh/id_rsa
     
     
      
         dfs.ha.fencing.ssh.connect-timeout 
         30000 
     
 
     
     
         dfs.ha.automatic-failover.enabled
         true
     
     
     
     
         dfs.replication
         3
     
 

core-site.xml


     
     
         fs.defaultFS
         hdfs://supercluster
     
     
     
     
         hadoop.tmp.dir
         /usr/local/hadoop-3.3.1/tmp
     
 
     
     
         ha.zookeeper.quorum
         qianfeng01:2181,qianfeng02:2181,qianfeng03:2181
     
 

hadoop-env.sh

# 添加两行
export HDFS_JOURNALNODE_USER=root
export HDFS_ZKFC_USER=root

分发配置文件到其他节点

 [root@qianfeng01 ~]# cd $HADOOP_HOME/etc
 [root@qianfeng01 hadoop]# scp -r hadoop qianfeng02:$PWD
 [root@qianfeng01 hadoop]# scp -r hadoop qianfeng03:$PWD

启动集群

现在,集群已经搭建成为了高可用的集群了。在启动集群之前,我们需要先明确一件事情: 集群现在的状态有两种:

  • 这个集群我之前使用过,NameNode已经存储有数据了(fsimage和edits已生成)
  • 这个集群是我新搭建的,我直接搭建集群的时候就搭建的高可用的集群,之前从来没有启动过

如果你是第一种情况,请跳转到 普通集群转HA

如果你是第二种情况,请跳转到 直接搭建HA

启动: 普通集群转HA

# 1. 启动集群的JournalNode服务。
#    注意事项: 如果之前集群还在运行,需要先将其停止!使用命令 stop-dfs.sh
[root@qianfeng01 ~]# hdfs --daemon start journalnode
[root@qianfeng02 ~]# hdfs --daemon start journalnode
[root@qianfeng03 ~]# hdfs --daemon start journalnode

# 2. 启动以前节点上的namenode进程
[root@qianfeng01 ~]# hdfs --daemon start namenode

# 3. 在新的namenode节点上拉取镜像文件
[root@qianfeng02 ~]# hdfs namenode -bootstrapStandby

# 4. 同步日志到journalnode集群上,再启动集群
#    先关namenode
[root@qianfeng01 ~]# hdfs --daemon stop namenode
# 再同步日志
[root@qianfeng01 ~]# hdfs namenode -initializeSharedEdits

# 5. 格式化zkfc
# 5.1. 前提QuorumPeerMain服务必须处于开启状态,客户端zkfc才能格式化成功
[root@qianfeng01 ~]# zkServer.sh start
[root@qianfeng02 ~]# zkServer.sh start
[root@qianfeng03 ~]# zkServer.sh start
# 5.2. 选择其中一个namenode节点进行格式化zkfc
[root@qianfeng01 ~]# hdfs zkfc -formatZK

# 6. 你就可以快乐的开启HA集群进行测试了
[root@qianfeng01 ~]# start-all.sh

# 查看NameNode的状态
[root@qianfeng01 ~]# hdfs haadmin -getServiceState nn1

# 注意: 以后开HA集群时,要先开zookeeper服务,再开HDFS。

启动: 直接搭建HA

# 1. 启动三个节点上的journalnode服务
[root@qianfeng01 ~]# hdfs --daemon start journalnode
[root@qianfeng02 ~]# hdfs --daemon start journalnode
[root@qianfeng03 ~]# hdfs --daemon start journalnode

# 2. 格式化namenode
#    - 先删除所有节点的${hadoop.tmp.dir}/tmp/的数据(可选,这一步表示弃用fsimage.)
#    - 选择其中一个namenode进行格式化
[root@qianfeng01 ~]# hdfs namenode -format
#    - 并启动namenode进程
[root@qianfeng01 ~]# hdfs --daemon start namenode

# 3. 在另一台namenode上拉取已格式化的那台机器的镜像文件(数据的一致性)
[root@qianfeng02 ~]# hdfs namenode -bootstrapStandby

# 4. 然后关闭已经启动的namenode
[root@qianfeng01 ~]# hdfs --daemon stop namenode

# 5. 格式化zkfc
# 5.1. 前提QuorumPeerMain服务必须处于开启状态,客户端zkfc才能格式化成功
[root@qianfeng01 ~]# zkServer.sh start
[root@qianfeng02 ~]# zkServer.sh start
[root@qianfeng03 ~]# zkServer.sh start
# 5.2. 选择其中一个namenode节点进行格式化zkfc
[root@qianfeng01 ~]# hdfs zkfc -formatZK

# 6. 你就可以快乐的开启HA集群进行测试了
[root@qianfeng01 ~]# start-all.sh

# 注意:以后开HA集群时,要先开zookeeper服务,再开HDFS。

自动容灾测试

由于CentOS7的minimal版本缺少容灾切换ActiveNameNode节点时所需要的组件,因此需要手动安装一下:

yum install -y psmisc

 1. 首先查看当前活跃的Active节点是谁
 2. Kill掉活跃节点上的NameNode进程,模拟宕机
 3. 观察另外一个节点,是否已经变成Active的状态


帮助到你的话就点个关注吧~

你可能感兴趣的:(大数据,hadoop,java)