HDFS HA(高可用)

发布 : 2016-03-14 分类 : 大数据 浏览 :

背景

1
2
3
4
5
hadoop2.0之前,在HDFS集群中NameNode存在单点故障(SPOF).

对于只有一个NameNode的集群,若NameNode机器出现故障,则整个集群将无法使用,

直到NameNode重新启动

NameNode主要在以下两个方面影响HDFS集群

1
2
3
4
5
6
7
8
9
NameNode机器发生意外,如宕机,集群将无法使用,直到管理员重启

NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用

HDFS HA功能通过配置Active/Standby两个NameNode实现在集群中对NameNode的热备来解决上述问题。

如果出现故障,如机器崩溃或机器需要升级维护,

这是可通过此种方式将NameNode很快的切换到另外一台机器



NameNode HA架构图(重点)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
1> 确保只有一个NameNode提供服务

Active NameNode与Standby NameNode,同一时刻只应有一个活跃状态、提供服务的

NameNode。要保障统一时刻只有一个Active

2> Standby NameNode与Active NameNode元数据同步机制

Standy NameNode应能够实时访问Active NameNode的edits日志,所以可靠日志的共享机制非常重要

3> 故障检测

如果Active NN失效、宕机或者其依赖的OS、硬件出现故障,如何进行检测?这里就需要FailoverController组件

4> 自动故障转移

故障检测的目的就是期望能够快速的自动切换,使得故障不影响NameNode不影响NameNode的对外服务。而自动检测这里依赖于FailoverController组件

与Zookeeper集群的交互

5> Standby NameNode与Active NameNode之间BLOCK块同步

NamNode启动时将所有HDFS元数据信息从fsimage和edits中导入内存,元数据更新操作写入edits。

但是数据块BLOCK信息不存储到文件,是NameNode启动后与DataNode实时交互获取的。

如果发生故障切换,而新上任的NameNode没有实时的BLOCK信息,依然无法完成服务。

所有要求的DataNode的BLOCK信息要同时汇报给所有的NameNode

NameNode HA对外统一访问接口

1
2
3
4
5
NameNode HA集群使用NameService ID来唯一的标识一个单独的HDFS实例,后台支持多个HA NameNode节点。

另外,添加了新的抽象概念NameNode ID,标示一个NameNode。

为了支持在一个配置文件中配置所有的NameNode,相应的配置参数使用NameService ID与NameNode做前缀
1
2
3
4
5
<!-- mycluster为自定义的NameServiceID -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
1
配置HA NameNodes,须在hdfs-site.xml中添加额外配置选项

隔离机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
来保证同一时刻只有一个NameNode提供服务,三类隔离

1> edits日志共享存储的fencing,确保只有一个NameNode可以写入;

若是QJM方式,存储edits日志的存储由QJM来保证,可以避免元数据因同时多写而损坏,无需额外配置

2> 客户端fencing,确保只有一个NameNode可以响应客户端的请求;

3> DataNode fencing,确保只有一个NameNode可以向DN发命令

客户端和Datanode fencing属于NameNode Fencing级别,要保证这两点,则需要配置在新的NameNode启用前,确保已经不再对外服务

(隔离fencing就是干这事)。

1> sshfence隔离:免密码SSH登录Active NameNode,杀死进程

2> shell隔离:运行任意shell命令

可靠日志共享

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
在Active NameNode和Standby NameNode之间要有个共享的存储日志的地方,

Active NameNode把EditLog写到这个共享的存储日志的地方,

Standby NameNode去读取日志然后执行,这样Active和Standby NameNode内存中的HDFS元数据保持着同步。

一旦发生主从切换Standby NameNode可以尽快接管Active NameNode的工作

(虽然要经历一小段时间让原来Standby追上原来的Active,但是时间很短)

NameNode HA的核心部分,常见的三种方案:

1> shared NAS+NFS:共享存储设备,对NFS依赖

2> QJM/Quorum Journal Manager:分布式日志管理

3> BookKeeper:依赖于Zookeeper

自动转移机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
通过fencing机制,可以通过NameNode HA管理命令手动出发故障转移。

但是尽量保障服务的可用性,需要实现自动故障切换,则依赖于Zookeeper,所以需要一个

Zookeeper Quorums,和ZK FailoverController进程(简称ZKFC)

使用到Zookeeper的功能如下:

1> 故障检测Failure detection:每个Namenode节点通过、ZKFC组件在Zookeeper中维护一个会话,如果该主机宕机,那么Zookeeper会检测到过期,这样就触发

通知另一个节点做故障切换

2> 活跃NameNode选举:Zookeeper提供了一个简单的机制,来选出一个活跃节点。如果当前活跃NameNode宕机,另一个节点可以获取Zookeeper中一个排他锁,

来表明其成为活跃节点

自动转移机制

1
2
3
4
5
6
7
8
9
10
11
12
13
ZK Failver Controller(ZKFC)是一个新的组件,它是Zookeeper的一个客户端,监控和管理Namenode的状态

每个Namenode节点上都运行一个ZKFC,ZKFC作用:

1> 健康检查:通过健康检查的命令定期检查本地的NameNode。如果检测到不健康的状态,则标示该节点不健康!

2> Zookeeper会话管理:如果本地NameNode健康,那么ZKFC会保持一个Zookeeper会话。如果它是活跃的,ZKFC还会维持一个临时的znode锁。如果会话失效,

则该znode会自动删除

3> 选举:如果ZKFC检测到NameNode健康,而Zookeeper中的锁znode不存在,则会尝试获取这个锁。成功则选举成功,负责进行故障切换。故障切换与手动操作类似;

先fenced,然后升级为活跃状态。

自动转移机制

1
2
3
4
5
6
7
8
9
10
11
进行自动切换的配置,在hdfs-site.xml文件中添加
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node1:8485;node2:8485;node3:8485;node5:8485/mycluster</value>
</property>

Zookeeper中的HA状态需要先进行初始化,命令如下:

hdfs zkfc -formatZK

在任意一个NameNode上运行即可。在Zookeeper上创建一个znode用于自动故障转移

Hadoop2.0产生背景

1
2
3
4
5
6
7
8
9
Hadoop1.0中HDFS和MapReduce在高可用、拓展性等方面存在问题

HDFS存储的问题
NameNode单点故障,难以应用在线场景
NameNode压力存在,且内存受限,影响系统拓展性

MapReduce存在的问题
JobTracker访问压力大,影响系统拓展性
难以支持除MapReduce之外的计算框架,比如Spark、Storm

#注意事项

1
2
3
4
5
6
7
HDFS ZKFC 和 NameNode两个服务的启动顺序没有影响,谁先启动都可以

配置自动切换后,应添加对HDFS ZKFC的监控。

有些情况下的Zookeeper异常会导致ZKFC异常退出,应该重启以便保证自动切换机制的可用

如果Zookeeper集群失败,并不会导致HDFS集群不可用,只是不能触发自动故障切换而已。Zookeeper集群恢复正常后,自动切换机制可以恢复

NameNode HA管理命令

1
2
3
4
5
6
7
8
9
10
11
hdfs haadmin

-failover [--forcefence][--forceactive]手动切换,从第一个NN切换到第二个NN。如果前一个是Standby状态,则命令仅仅将第二个切换为Active,

不会抱错。如果前一个是Active状态,则先尝试将其转换为Standby状态,不行则使用dfs.ha.fencing.methods进行关闭操作。

只有确保前一处理成功后才会将后一转换为Active

-getServiceState 查看自定NameNode是Active还是Standby

-checkHealth 检查指定NameNode的健康情况,返回0则为健康。注:这个选项目前暂未完全实现,除非NameNode完全停止,否则都是返回0

HDFS元数据同步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
格式化HDFS

1> 在HDFS启用前,namenode必须格式化!格式化只需要执行一次,在NameNode中创建文件系统元数据

2> 执行完毕后,会创建空的fsimage文件和edit log,以及随机生成的storage ID。DataNode连接到NameNode后会获取这个storage ID,

这样以后就拒绝连接到其他namenode

3> 如果要重新格式化namenode,那么必须删除所有datanode的数据,因为其保护了storage ID信息

元数据同步

1> 当Active NameNode完成格式化后,StandBy NameNode不能通过相同的方式进行格式化,因为这样会导致出现不一致的namespace id,

使得DataNode不能同时与两个NameNode交互

2> StandBy NameNode需要与Active NameNode进行同步,同步可以通过命令:hadoop namenode -bootstrapStandby

也可以通过直接复制Active NameNode下的完整内容

HDFS QJM(Quorum Journal Manager)

1
2
3
4
5
Quorum:分布式系统

Quorom机制,是一种分布式系统中常用的,用来保证数据亢余和最终一致性的投票算法

Journal:日报,日志,日记;定期刊物,期刊,杂志


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
基于Paxos算法实现的HDFS HA方案

基本原理,与Zookeeper集群的原理相似,就是用2N+1台JournalNode存储EditLog,每次写数据操作有大多数(>=N+1)返回成功时即认为该次写成功,

数据不会丢失了。

当然这个算法所能容忍的是最多有N台机器挂掉,如果多余N台挂掉,这个算法就失效了。

QJM方式NameNode HA优点

不需要配置额外的高共享存储,这样对于基于commodity hardware的云计算数据中心来说,降低了复杂度和维护成本

不在需要单独配置fencing实现,QJM本身内置了fencing的功能

不存在Single Point Of Failure;

系统的鲁棒性的程度是可配置的(QJM基于Paxos算法,所以如果配置2N+1台JournalNode组成的集群,能容忍最多N台机器挂掉)

QJM中存储日志的JournalNode不会因为其中一台的延迟而影响整体的延迟,而且也不会因为JournalNode的数量增多而影响性能(因为NameNode向JournalNode发送是并行的)

QJM HA配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
NameNode HA基本配置(core-site.xml,hdfs-site.xml)

Active NameNode与Standby NameNode地址配置

NameNode 与 DataNode本地存储路径位置

HDFS Namespace访问配置

隔离fencing配置(配置两节点之间的互相SSH无密钥登陆)

QJM配置(hdfs-site.xml)

QJM管理编辑日志

编辑日志存储目录

手动故障转移(无需配置)

QJM HA启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
1> 在各个JournalNode节点上,输入以下命令启动Journalnode服务

./sbin/hadoop-daemon.sh start journalnode

2> 在[nn1]上,对其进行格式化,并启动

./bin/hdfs namenode -format

./sbin/hadoop-daemon.sh satrt namenode

3> 在[nn2]上,同步nn1的元数据信息

./bin/hdfs namenode -bootstrapStandby

4> 启动[nn2]:

./sbin/hadoop-daemon.sh start namenode

5> 将[nn1]切换为Active

./bin/hdfs haadmin -transitionToActive nn1

6> 在[nn1]上,启动所有datanode

./sbin/hadoop-daemons.sh start datanode

NameNode HA自动故障转移

HDFS HA中关于fsimage与edits合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
过程归纳如下:

1> 配置好HA后,客户端所有的更新操作将会写到共享目录中

2> Active NameNode和Standby NameNode从JournalNode的edits共享目录中同步edits

到自己edits目录中

3> Standby NameNode中的StandbyCheckpointer类会定期的检查合并的条件是否成立,如果成交会合并fsiamge和edits文件

4> Standy NameNode中的StandbyCheckpointer类合并完之后,将合并之后的fsimage上传到Active NameNode相应目录中

5> Active NameNode接到最新的fsiamge文件之后,将旧的fsimage和edits文件清理掉

6> fsimage和edits文件就完成了合并,由于HA机制,会使得Standby NameNode和Active NameNode都拥有最新的fsiamge和edits文件

集中式缓存管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Hadoop从2.3.0版本开始支持HDFS缓存机制,HDFS允许用户将一部分目录或文件缓存在HDFS当中,NameNode会通知拥有对应快的DataNode

其缓存在DataNode的内存当中。

优势:

1> 防止那些被频繁使用的数据从内存中清除

2> 因为DataNode的缓存由NameNode来管理,applications在任务安排时可以查询这个缓存的列表,使用过一个被缓存的块副本能够提高读性能

3> 当块被DataNode缓存之后,客户端可以使用一个新的、高效的zero-copy的读API,因为缓存中的数据已经被计算过checksum,当使用新API时,

客户端基本上是零开销的

4> 可以提高集群的内存利用率。当时操作系统的缓存时,对一个块的重复会导致所有的副本都会被放到缓冲区当中,当使用集中式缓存时,用户可以指定

n个副本中的m个才会被缓存,可以节约n-m的内存

使用场景:

集中式缓存对那些频繁访问的文件是非常有用的,例如hive中经常被使用的fact表就非常适合缓存

另一方面,缓存一年的查询结果可能没那么有用了,因为这个结果可能只会被查看一次

有助于提供混合类型作业的SLA性能,把高优先级的数据缓存起来可以确保它不会与低优先级的数据竞争磁盘IO
本文作者 : Matrix
原文链接 : https://matrixsparse.github.io/2016/03/14/HDFS-HA/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

知识 & 情怀 | 二者兼得

微信扫一扫, 向我投食

微信扫一扫, 向我投食

支付宝扫一扫, 向我投食

支付宝扫一扫, 向我投食

留下足迹