HDFS HA架构

HA背景

对于HDFS、YARN的每个角色都是一个进程,


比如HDFS:NN/SNN/DN   老大是NN


YARN:RM/NM   老大是RM


对于上面,都会存在单点故障的问题,假如老大NN或者RM挂了,那么就不能提供对外服务了,会导致整个集群都不能使用。


大数据几乎所有的组建都是主从架构(master-slave)。比如hdfs的读写请求都是先经过NN节点。(但是hbase的读写请求不是经过老大的master)。


hdfs:由NN/SNN/DN组成,SNN每小时会做一次checkpoint的操作,如果NN挂了,只能恢复到上次checkpoint的那一刻,不能实时。现在如果把SNN的角色再提升一个等级,让它和NN一样,如果NN挂了,SNN能立即切换过来就好了。


HDFS HA 架构 有两个NN节点,一个是active活跃状态,一个是standby准备状态,Active NameNode对外提供服务,比如处理来自客户端的RPC请求,而Standby NameNode则不对外提供服务,仅同步Active NameNode的状态,对Active NameNode进行实时备份,以便能够在它失败时快速进行切换。


HA介绍

HDFS High Availability (HA) 


假定:


NN1 active       ip1

NN2 standby    ip2


假如说在我们代码或者shell脚本里,写了:hdfs dfs -ls hdfs://ip1:9000/   ,那么如果NN1挂了,NN2切换到active状态了,但是在脚本里还是ip1,这个时候不可能手动去修改。肯定有问题。那么该怎么解决?


用命名空间来解决。命名空间不是进程。比如:命名空间的名称为:ruozeclusterg7


脚本里可以这样写:hdfs dfs -ls hdfs://ruozeclusterg7/


当代码执行到这一行时,它会去core-site.xml、hdfs-site.xml里面查找。在这两个配置文件里面,配置了ruozeclusterg7命名空间下挂了NN1和NN2。当它找到NN1,它会尝试着连接第一个机器NN1,如果发现它不是active状态,它会尝试着连接第二个机器NN2,如果发现NN1是active状态,就直接用了。


HA 进程:(假定我们现在有三台机器)

hadoop001:ZK    NN  ZKFC  JN    DN

hadoop002:ZK    NN  ZKFC  JN    DN

hadoop003:ZK                       JN    DN


NN节点有fsimage、editlog(读和写请求的记录)两个文件,有专门的进程去管理的,这个进程是JN(journalnode)日志节点,要保证NN1和NN2能实时同步,需要JN这个角色。


如果NN1挂了,需要把NN2从standby状态切换到active状态,那它是怎么切换的呢?需要ZKFC。


ZKFC: 是单独的进程,它监控NN健康状态,向zk集群定期发送心跳,使得自己可以被选举;当自己被zk选举为active的时候,zkfc进程通过RPC协议调用使NN节点的状态变为active。对外提供实时服务,是无感知的。


所以在上面,需要在三台机器上都部署一下zookeeper,作为一个集群,ZK集群,是用于做选举的。选举谁来做老大(active),谁做standby。集群中ZK的个数是2n+1,这样能投票保证最后有一个胜出。


生产上zookeeper部署的个数经验:如果集群中有20台节点,那么可以在5台上部署zk。如果总共有七八台,也部署5台zk。如果总共有20~100台节点,可以部署7台/9台/11台 zk。如果大于100台,可以部署11台zk。如果有很多,比如上万台那看情况可以多部署几台。但是,不是说zk节点越多越好。因为做投票选举动作的时候,投票谁做active,谁做standby是需要时间的,时间间隔太长会影响对外服务,对外服务会很慢,对于即时性 的服务来说,这是不允许的。


他们的集群有很多台,比如几百台几千台,zk部署的机器上就它一个进程,不部署其它进程了。在这里是学习或者机器很少,所以一台机器上部署多个进程。如果几百台节点,任务很重,如果部署zk的机器上有其它进程,那么它会消耗很多机器上的资源(无外乎cpu、内存、文件数、进程数),这都会影响zk响应的速度,所以一般都会把它独立出来。但是如果机器是256G内存,但是zk只用到32G,那其他的就浪费了,那么买机器的时候,可以单独给zk买32G内存的机器就可以了。


zk是最底层的,如果zk太繁忙,就可能导致standby状态不能切换到active状态,这个时候机器可能就会夯住。所以当机器夯住,standby不能切换到active的时候,有可能就是zk出问题了。


HDFS HA 架构图

截图.png.jpeg


关于HA 架构的官方文档https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html


Architecture
In a typical HA cluster, two or more separate machines are configured as NameNodes. At any point in time, exactly one of the NameNodes is in an Active state, and the others are in a Standby state. The Active NameNode is responsible for all client operations in the cluster, while the Standbys are simply acting as workers, maintaining enough state to provide a fast failover if necessary.
In order for the Standby node to keep its state synchronized with the Active node, both nodes communicate with a group of separate daemons called “JournalNodes” (JNs). When any namespace modification is performed by the Active node, it durably logs a record of the modification to a majority of these JNs. The Standby node is capable of reading the edits from the JNs, and is constantly watching them for changes to the edit log. As the Standby Node sees the edits, it applies them to its own namespace. In the event of a failover, the Standby will ensure that it has read all of the edits from the JournalNodes before promoting itself to the Active state. This ensures that the namespace state is fully synchronized before a failover occurs.
In order to provide a fast failover, it is also necessary that the Standby node have up-to-date information regarding the location of blocks in the cluster. In order to achieve this, the DataNodes are configured with the location of all NameNodes, and send block location information and heartbeats to all.
It is vital for the correct operation of an HA cluster that only one of the NameNodes be Active at a time. Otherwise, the namespace state would quickly diverge between the two, risking data loss or other incorrect results. In order to ensure this property and prevent the so-called “split-brain scenario,” the JournalNodes will only ever allow a single NameNode to be a writer at a time. During a failover, the NameNode which is to become active will simply take over the role of writing to the JournalNodes, which will effectively prevent the other NameNode from continuing in the Active state, allowing the new Active to safely proceed with failover.


翻译:


一个典型的HA集群,NameNode会被配置在2台或更多 独立的机器上,在任何时间上,一个NameNode处于活动状态,而另一个NameNode处于备份状态,活动状态的NameNode会响应集群中所有的客户端,备份状态的NameNode只是作为一个副本,保证在必要的时候提供一个快速的转移。


为了让Standby Node与Active Node保持同步,这两个Node都与一组称为JNS的互相独立的进程保持通信(Journal Nodes)。当Active Node上更新了namespace,它将记录修改日志发送给JNS的多数派。Standby noes将会从JNS中读取这些edits,并持续关注它们对日志的变更。Standby Node将日志变更应用在自己的namespace中,当failover发生时,Standby将会在提升自己为Active之前,确保能够从JNS中读取所有的edits,即在failover发生之前Standy持有的namespace应该与Active保持完全同步。


为了支持快速failover,Standby node持有集群中blocks的最新位置是非常必要的。为了达到这一目的,DataNodes上需要同时配置这两个Namenode的地址,同时和它们都建立心跳链接,并把block位置发送给它们。


任何时刻,只有一个Active NameNode是非常重要的,否则将会导致集群操作的混乱,那么两个NameNode将会分别有两种不同的数据状态,可能会导致数据丢失,或者状态异常,这种情况通常称为“split-brain”(脑裂,三节点通讯阻断,即集群中不同的Datanodes却看到了两个Active NameNodes)。对于JNS而言,任何时候只允许一个NameNode作为writer;在failover期间,原来的Standby Node将会接管Active的所有职能,并负责向JNS写入日志记录,这就阻止了其他NameNode基于处于Active状态的问题。



首先要部署三台zk,然后要两台NN节点,然后三台DN节点。两个NN节点之间的编辑日志需要jn来维护,做共享数据存储。


journalnode(jn): 部署多少合适?取决于HDFS请求量及数据量,比如说BT级的数据量,或者小文件很多,读写请求很频繁,那么journalnode就部署多一点,如果HDFS很悠闲,那就部署少一点,比如7个、9个这样,可以大致和zk部署的保持一致(见上面)。具体要看实际情况。(也是2n+1,可以看官网上介绍)


ZKFC:zookeeperfailovercontrol


客户端或者程序代码在提交的时候,去namespace找,找NN节点,如果第一次找的NN节点就是active,那么就用这个节点,如果发现它是standby,就到另外一台机器。


比如说客户端现在执行put、get、ls、cat命令,这些操作命令的记录,active NN节点会写到自己的edit log日志里面。这些操作记录,NN自己会写一份,同时,它会把这些操作记录,写给journalnode的node集群。


而另外的,standby NN节点,会实时的读journalnode的node集群,读了之后会把这些记录应用到自己的本身。这个大数据的专业名词叫做:重演。 相当于standby NN节点把active NN节点的active状态的操作记录在自己身上重演一遍。


journalnode:它是一个集群,就是用于active NN节点和standby NN节点之间同步数据的。它是单独的进程。


NN和ZKFC在同一台机器上面。


整个过程描述:当通过client端提交请求的时候,无论读和写,我们是通过命名空间RUOZEG6,去找谁是active状态,找到了就在那台机器上面,提交请求,然后就是HDFS的读写流程,读和写的操作记录,edit log,它自己会写一份,同时会把读写请求的操作记录,写一份到journalnode集群日志,进行同步之后,另外一个节点,standby 节点会把它拿过来实时的应用到自己的本身。专业的名称叫重演。同时每个DataNode会向NameNode节点发送心跳的块报告(心跳的间隔时间3600s,就是1小时,参数是什么(面试))。当active NN节点挂了,通过zk集群选举(它存储了NN节点的状态),通知ZKFC,把standby NN节点切换到active状态。ZKFC会定期的发送心跳。


ps:


HA是为了解决单点故障问题。


通过journalnode集群共享状态,也就是共享hdfs读和写的操作记录。


通过ZKFC集群选举谁是active。


监控状态,自动备援。


DN: 同时向NN1 NN2发送心跳和块报告。

ACTIVE NN: 读写的操作记录写到自己的editlog

                     同时写一份到JN集群

                     接收DN的心跳和块报告

STANDBY NN: 同时接收JN集群的日志,显示读取执行log操作(重演),使得自己的元数据和active nn节点保持一致。

                        接收DN的心跳和块报告


JounalNode: 用于active nn和 standby nn节点的数据同步, 一般部署2n+1


ZKFC: 单独的进程

           监控NN监控健康状态

           向zk集群定期发送心跳,使得自己可以被选举;

           当自己被zk选举为active的时候,zkfc进程通过RPC协议调用使NN节点的状态变为active,只有是

active状态才能对外提供服务。

           对外提供实时服务,是无感知的,用户是感觉不到的。

总结

HDFS HA架构图 以三台机器 为例

HA使用active NN,standby NN两个节点解决单点问题。

两个NN节点通过JN集群,共享状态,

通过ZKFC选举active,监控状态,自动备援。

DN会同时向两个NN节点发送心跳


active nn:

接收client的rpc请求并处理,同时自己editlog写一份,也向JN的共享存储上的editlog写一份。

也同时接收DN的block report,block location updates 和 heartbeat


standby nn:

同样会接受到从JN的editlog上读取并执行这些log操作,使自己的NN的元数据和activenn的元数据是同步的,

使用说standby是active nn的一个热备。一旦切换为active状态,就能够立即马上对外提供NN角色的服务。

也同时接收DN的block report,block location updates 和 heartbeat


jn:

用于active nn,standby nn 的同步数据,本身由一组JN节点组成的集群,奇数,CDH3台起步,是支持Paxos协议。

保证高可用


ZKFC作用:

1.监控NameNode状态,ZKFC会定期向ZK发送心跳,使自己被选举,当自己被ZK选举为主时,我们的ZKFC进程通过rpc调用,让nn转换为active状态。






猜你喜欢

转载自blog.51cto.com/wangyichao/2440403