热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

大数据谢列3:Hdfs的HA实现

在之前的文章:大数据系列:一文初识Hdfs,大数据系列2:Hdfs的读写操作中

在之前的文章:大数据系列:一文初识Hdfs  ,
大数据系列2:Hdfs的读写操作   中Hdfs的组成、读写有简单的介绍。

在里面介绍Secondary NameNode
和Hdfs读写的流程。 
并且在文章结尾也说了,Secondary NameNode
并不是我常说的HA,(High Availability)

本文承接之前的内容,对Hdfs的HA实现做个简单的介绍。


NameNode的重要性

先来看看Hdfs读写的流程图:

读流程
写流程

可以看到无论是读还是写,我们都必须和存储元数据的NameNode
进行交互。

一旦NameNode
出问题,整个集群的读写基本上就凉凉了。

所以,在设计的时候本就有做一些容错的措施。


容错的措施

如果NameNode
出了问题,整个文件Hdfs将不可用。

设想一个场景: 
如果以为某种原因我们运行NameNode
的机器被删除。

此时所有Hdfs的文件都会丢失,因为我们虽然在DataNode
中存储了文件的块信息,但是我们无法通过这些信息重新构建文件。

所以让NameNode
有一定抗拒错误的能力是很重要的。

Hadoop
本身提供了两种机制。


备份元数据

第一种机制: 
将Hdfs元数据中持久化状态的文件做多个备份。

Hadoop
可以进行相关的配置,把这些持久的状态备份到多个文件系统。这个过程是同步且为原子操作的 。
一般都是配置为备份到本地磁盘,同时远程NFS 挂载

Secondary NameNode

第二种机制: 
运行一个Secondary NameNode
,负责定期合并名称namespace iamge
edit log
,以防止edit log
变得过大。

合并流程如下,详细过程之前有介绍过,此处不累赘:

合并流程

存在问题

虽然这两个方式让Hdfs有一定的容错能力,但是还是存在一些问题。

Secondary NameNode
拥有一个合并的namespace iamge
的副本,在NameNode
失败时可以使用该iamge

但是Secondary NameNode
中的状态是滞后于NameNode
的,如果NameNode
是宕机的情况下,数据丢失必不可少。

此时通常的做法是将NFS上的NameNode
元数据文件复制到Secondary NameNode
,并将其作为新的NameNode
运行。

因为NFS中的与NameNode
的元数据是同步的,所以可以通过NFS中的数据恢复。

在多个文件系统上复制NameNode
元数据和使用Secondary NameNode
创建checkpoints
的组合可以防止数据丢失。

然而这种组合的机制并不能提供Hdfs
的高可用性。

主要原因是这种方式恢复太耗时间了。

NameNode
是唯一的存储了文件与Blcok
映射关系的元数据存储库
,一旦它罢工,所有的Client
的作业包括Mapreduce
、读、写、列出文件都无法进行。 
在新的NameNode
上线之前,整个集群处于停止服务的状态

如果NameNode
要重新上线服务需要经过
下的步骤:

  1. 加载命名空间到内存

  2. 重放edit log

  3. DataNode
    接收足够的Block
    报告并离开安全模式。

在具有许多文件和Block
的大型集群上,NameNode
的冷启动所需的时间可能是30分钟或更长。

这么拉垮可不太能接受,无论是日常运维还是计划停机之类的操作。

所以,归根结底就是NameNode
仍然是存在单点故障(SPOF,Single Point Of Failure
)

下面就看看怎么解决这个问题。


HDFS high availability (HA)

一般情况下会有两个场景和HA息息相关。

  1. 在出现计划外事件(如服务器宕机)的情况下,在重新启动NameNode
    之前,集群将不可用。

  2. 有计划的维护事件,例如NameNode
    机器上的软件或硬件升级,将导致集群停机。

为了解决上述的问题,Hadoop
提供了HDFS high availability (HA)
的支持。

通过active-standby
的方式配置两个NameNode
(3.0后可以支持超过两个),在Active/Passive
动配置中使用热备份。

在机器崩溃的情况下,实现快速故障转移到新的NameNode
,  
或者出于计划维护的目的,允许管理员发起优雅的故障转移。

为了实现这个目标,在架构层面需要做一些改变:

  1. NameNode
    之间必须要通过一些高可用的共享内存共享edit log
    ,一旦standby NameNode
    接管工作的时候,它通过读取共享edit log
    直至结尾以保持它的状态与active NameNode
    一致,然后继续读取由active NameNode
    写入的新条目。

  2. DataNodes
    必须向两个NameNode
    发送Block
    报告,因为Block
    映射关系是存储在DataNode
    的内存而不是磁盘。

  3. 客户端必须使用一种机制来处理NameNode
    失效问题,让用户对于NameNode
    的切换是透明的。(就是不需要用户自己去切换NameNode

  4. standby NameNode
    应该承担之前Secondary NameNode
    的角色,定期为active NameNode
    的命名空间创建检查点。

在典型的HA集群中,会配置两个或更多的NameNodes
,但是在任何时候,都只能有一个NameNode
处于活动状态,其他NameNode
处于备用状态。 
Active状态的NameNode
负责集群中的所有Client的操作,
Standby状态的NameNode
仅需要保存足够的状态的即可。

有两种实现方式


Quorum Journal Manager (QJM)

QJM
是一个专用的HDFS
实现,设计的唯一目的是提供高度可用的编辑日志,并且是大多数HDFS
安装的推荐选择。

QJM
作为一组journalnodes(JNs)
独立守护进程运行,每次编辑都必须写入大部分JNs
节点。

为了使备节点与主节点保持状态同步,两个节点都与JNs
进程通信。

Active NameNode
执行任何关于名称空间修改时,它会持久地记录修改记录到大部分的JNs

通常,有三个journal
节点,因此系统可以容忍其中一个节点的丢失。 
尽管这种方式类似ZooKeeper
工作方式,但是必须说明的是QJM
实现没有使用ZooKeeper

同时还要注意,HDFS的HA确实使用了ZooKeeper来选择active NameNode
,后续会介绍

standby NameNode
能够从JNs
中读取edits
,并不断监视它们对edit log
的修改。

standby NameNode
看到这edits时,它将它们应用到自己的名称空间。

standby NameNode
必须持有集群中Block
位置的最新信息。 
所以,DataNodes
需要配置所有NameNode
的位置,并向所有NameNode
发送Block
 位置信息和心跳。

因为standby NameNode
在内存中有最新的状态:最新的edit log
和最新的Block
映射
所以Active NameNode
发生故障时,standby NameNode
可以很快接管(在几十秒内)。

实际观察到的故障转移时间要长一些(大约一分钟左右),因为系统需要保守地判断active NameNode
是否发生了故障。


NFS

QJM
方共享不同,edit log
记录到JNs
不同,

此处的共享内存一般使用过一个支持NFS
(Network File System
:网络文件系统)的NAS
(Network Attached Storage
:网络附属存储)创建应共享文件,通常会挂载在每一个NameNode
的机器上,NameNode
可以对其进行读、写操作。

但是,目前只支持一个共享edit
目录。 
因此,系统的可用性受到共享edit
目录的可用性的限制,  
为了消除所有单点故障,共享编辑目录需要有冗余。

具体来说,就是到存储的多条网络路径,以及存储本身的冗余(磁盘、网络和电源)。 
所以,建议使用高质量的专用NAS
设备作为共享存储服务器,而不是简单的Linux
服务器。


故障转移和规避

HA
集群中,standby NameNode
还执行名称空间状态检查点操作,  
因此在HA集群中没有必要运行 Secondary NameNode, CheckpointNode, or BackupNode

同时无论是QJM
还是NFS
中,  
在同一时刻只有一个NameNode
处于Active
是至关重要的。 
否则,名称空间状态将很快在两者之间出现分歧(脑裂),可能导致数据丢失或其他不正确的结果。 
为了避免这个情况,同一时间只允许一个NameNode
JournalNodes
NFS
的共享内存写入。

在故障转移期间,即将成为Active
状态的NameNode
将接管向共享eidt文件写入数据的角色,  
这将有效地阻止其他NameNode
继续处于Active
状态,从而允许新的Active
状态安全地进行故障转移。

但是要如何实现呢?


故障转移

active NameNode
standby NameNode
的过渡由系统中称为故障转移控制器(failover controller)的新实体进行管理。

可以理解为active NameNode
挂了standby NameNode
上位的过程

有各种各样的故障转移控制器,但是默认的实现是使用ZooKeeper来确保只有一个NameNode
active
的。

每个NameNode
运行一个轻量级的故障转移控制器进程,  
它的任务是监视它的NameNode
是否出现故障(使用一个简单的心跳机制),  
并在NameNode
出现故障时触发故障转移。

故障转移也可以由管理员手动启动,  
例如,在例行维护的情况下。 
这被称为优雅的故障转移( graceful failover
),因为故障转移控制器为两个NameNode
安排了有序的角色转换。

但是,  
在意料之外的故障转移的情况下,不可能确保失败的NameNode
已经停止运行。

例如,网络或网络分区速度较慢的情况下,  
即使以前active

NameNode
仍然在运行  
也可能会触发故障转移。

为了避免这种情况,HA实现了确保以前active NameNode
不会造成任不良影响的方法称为规避(fencing
)。


规避

JNs一次只允许一个NameNode
写入编辑日志;  
但是,以前活跃的NameNode
仍然可能向客户端提供过时的读请求,  
因此可以设置一个SSH 规避命令来杀死NameNode
进程。

对于使用NFS文件的共享edit log
,因为很难控制一次只允许一个NameNode
写入,  
需要更强有力地规避方法,一般可以选择如下方法:

  1. 撤销NameNode
    对共享存储目录的访问(通常使用特定于供应商的NFS命令)

  2. 通过远程管理命令屏蔽相应网络端口(port)

  3. 做绝一点可以通过一个叫做“一枪爆头”方式进行规避(STONITH,short the other node in the head
    ),通过一个特定的供电单元对相应的NameNode
    进行断电操作。

这就是推荐使用QJM的主要原因。

有了上述只是储备,我们很容易就可以把这个架构图画出来,以QJM
为例

QJM 结构

那么转移过程大致如下:

故障转移流程

客户端故障转移

对于客户端而言,我们要让用户对于故障转移是无感的。 
可以通过配置文件实现一个故障转移

在配置文件中通过配置几个参数实现故障转移:

dfs.nameservices
:Hdfs逻辑名称

<property>
  <name>dfs.nameservicesname>
  <value>myclustervalue>
property>

dfs.ha.NameNodes.[nameservice ID]
:nameservice中每个NameNode
的唯一标识符

<property>
  <name>dfs.ha.NameNodes.myclustername>
  <value>nn1,nn2, nn3value>
property>

dfs.NameNode.rpc-address.[nameservice ID].[name node ID]
:每个NameNode
监听的完全限定RPC地址

<property>
  <name>dfs.NameNode.rpc-address.mycluster.nn1name>
  <value>machine1.example.com:8020value>
property>
<property>
  <name>dfs.NameNode.rpc-address.mycluster.nn2name>
  <value>machine2.example.com:8020value>
property>
<property>
  <name>dfs.NameNode.rpc-address.mycluster.nn3name>
  <value>machine3.example.com:8020value>
property>

更多的配置可以查看  
NameNode
HA With QJM  
NameNode
HA With NFS


关于HA暂时介绍到这里,后续有空再进行详细的介绍。
之后会写一下关于Yarn的文章,感兴趣可以关注【兔八哥杂谈】  




推荐阅读
  • Presto:高效即席查询引擎的深度解析与应用
    本文深入解析了Presto这一高效的即席查询引擎,详细探讨了其架构设计及其优缺点。Presto通过内存到内存的数据处理方式,显著提升了查询性能,相比传统的MapReduce查询,不仅减少了数据传输的延迟,还提高了查询的准确性和效率。然而,Presto在大规模数据处理和容错机制方面仍存在一定的局限性。本文还介绍了Presto在实际应用中的多种场景,展示了其在大数据分析领域的强大潜力。 ... [详细]
  • Hadoop的分布式架构改进与应用
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • SecureCRT是一款功能强大的终端仿真软件,支持SSH1和SSH2协议,适用于在Windows环境下高效连接和管理Linux服务器。该工具不仅提供了稳定的连接性能,还具备丰富的配置选项,能够满足不同用户的需求。通过SecureCRT,用户可以轻松实现对远程Linux系统的安全访问和操作。 ... [详细]
  • 小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限
    小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限 ... [详细]
  • 本文探讨了 Kafka 集群的高效部署与优化策略。首先介绍了 Kafka 的下载与安装步骤,包括从官方网站获取最新版本的压缩包并进行解压。随后详细讨论了集群配置的最佳实践,涵盖节点选择、网络优化和性能调优等方面,旨在提升系统的稳定性和处理能力。此外,还提供了常见的故障排查方法和监控方案,帮助运维人员更好地管理和维护 Kafka 集群。 ... [详细]
  • 全面解析:Hadoop技术栈中的Linux操作系统概览
    全面解析:Hadoop技术栈中的Linux操作系统概览 ... [详细]
  • 本文详细介绍了HDFS的基础知识及其数据读写机制。首先,文章阐述了HDFS的架构,包括其核心组件及其角色和功能。特别地,对NameNode进行了深入解析,指出其主要负责在内存中存储元数据、目录结构以及文件块的映射关系,并通过持久化方案确保数据的可靠性和高可用性。此外,还探讨了DataNode的角色及其在数据存储和读取过程中的关键作用。 ... [详细]
  • 2012年9月12日优酷土豆校园招聘笔试题目解析与备考指南
    2012年9月12日,优酷土豆校园招聘笔试题目解析与备考指南。在选择题部分,有一道题目涉及中国人的血型分布情况,具体为A型30%、B型20%、O型40%、AB型10%。若需确保在随机选取的样本中,至少有一人为B型血的概率不低于90%,则需要选取的最少人数是多少?该问题不仅考察了概率统计的基本知识,还要求考生具备一定的逻辑推理能力。 ... [详细]
  • 第二章:Kafka基础入门与核心概念解析
    本章节主要介绍了Kafka的基本概念及其核心特性。Kafka是一种分布式消息发布和订阅系统,以其卓越的性能和高吞吐量而著称。最初,Kafka被设计用于LinkedIn的活动流和运营数据处理,旨在高效地管理和传输大规模的数据流。这些数据主要包括用户活动记录、系统日志和其他实时信息。通过深入解析Kafka的设计原理和应用场景,读者将能够更好地理解其在现代大数据架构中的重要地位。 ... [详细]
  • 在搭建Hadoop集群以处理大规模数据存储和频繁读取需求的过程中,经常会遇到各种配置难题。本文总结了作者在实际部署中遇到的典型问题,并提供了详细的解决方案,帮助读者避免常见的配置陷阱。通过这些经验分享,希望读者能够更加顺利地完成Hadoop集群的搭建和配置。 ... [详细]
  • 在前一篇文章《Hadoop》系列之“踽踽独行”(二)中,我们详细探讨了云计算的核心概念。本章将重点转向物联网技术,全面解析其基本原理、应用场景及未来发展前景。通过深入分析物联网的架构和技术栈,我们将揭示其在智能城市、工业自动化和智能家居等领域的广泛应用潜力。此外,还将讨论物联网面临的挑战,如数据安全和隐私保护等问题,并展望其在未来技术融合中的重要角色。 ... [详细]
  • Hadoop 2.6 主要由 HDFS 和 YARN 两大部分组成,其中 YARN 包含了运行在 ResourceManager 的 JVM 中的组件以及在 NodeManager 中运行的部分。本文深入探讨了 Hadoop 2.6 日志文件的解析方法,并详细介绍了 MapReduce 日志管理的最佳实践,旨在帮助用户更好地理解和优化日志处理流程,提高系统运维效率。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了在sqoop1.4.*版本中,如何实现自定义分隔符的方法及步骤。通过修改sqoop生成的java文件,并重新编译,可以满足实际开发中对分隔符的需求。具体步骤包括修改java文件中的一行代码,重新编译所需的hadoop包等。详细步骤和编译方法在本文中都有详细说明。 ... [详细]
  •     这里使用自己编译的hadoop-2.7.0版本部署在windows上,记得几年前,部署hadoop需要借助于cygwin,还需要开启ssh服务,最近发现,原来不需要借助cy ... [详细]
author-avatar
dafeige
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有