NoSQL-HDFS-基本概念

NoSQL-HDFS-基本概念,第1张

Hadoop

文件系统:文件系统是用来存储和管理文件,并且提供文件的查询、增加、删除等 *** 作。

直观上的体验:在shell窗口输入 ls 命令,就可以看到当前目录下的文件夹、文件。

文件存储在哪里?硬盘

一台只有250G硬盘的电脑,如果需要存储500G的文件可以怎么办?先将电脑硬盘扩容至少250G,再将文件分割成多块,放到多块硬盘上储存。

通过 hdfs dfs -ls 命令可以查看分布式文件系统中的文件,就像本地的ls命令一样。

HDFS在客户端上提供了查询、新增和删除的指令,可以实现将分布在多台机器上的文件系统进行统一的管理。

在分布式文件系统中,一个大文件会被切分成块,分别存储到几台机器上。结合上文中提到的那个存储500G大文件的那个例子,这500G的文件会按照一定的大小被切分成若干块,然后分别存储在若干台机器上,然后提供统一的 *** 作接口。

看到这里,不少人可能会觉得,分布式文件系统不过如此,很简单嘛。事实真的是这样的么?

潜在问题

假如我有一个1000台机器组成的分布式系统,一台机器每天出现故障的概率是01%,那么整个系统每天出现故障的概率是多大呢?答案是(1-01%)^1000=63%,因此需要提供一个容错机制来保证发生差错时文件依然可以读出,这里暂时先不展开介绍。

如果要存储PB级或者EB级的数据,成千上万台机器组成的集群是很常见的,所以说分布式系统比单机系统要复杂得多呀。

这是一张HDFS的架构简图:

client通过nameNode了解数据在哪些DataNode上,从而发起查询。此外,不仅是查询文件,写入文件的时候也是先去请教NameNode,看看应该往哪个DateNode中去写。

为了某一份数据只写入到一个Datanode中,而这个Datanode因为某些原因出错无法读取的问题,需要通过冗余备份的方式来进行容错处理。因此,HDFS在写入一个数据块的时候,不会仅仅写入一个DataNode,而是会写入到多个DataNode中,这样,如果其中一个DataNode坏了,还可以从其余的DataNode中拿到数据,保证了数据不丢失。

实际上,每个数据块在HDFS上都会保存多份,保存在不同的DataNode上。这种是牺牲一定存储空间换取可靠性的做法。

接下来我们来看一下完整的文件写入的流程:

大文件要写入HDFS,client端根据配置将大文件分成固定大小的块,然后再上传到HDFS。

读取文件的流程:

1、client询问NameNode,我要读取某个路径下的文件,麻烦告诉我这个文件都在哪些DataNode上?

2、NameNode回复client,这个路径下的文件被切成了3块,分别在DataNode1、DataNode3和DataNode4上

3、client去找DataNode1、DataNode3和DataNode4,拿到3个文件块,通过stream读取并且整合起来

文件写入的流程:

1、client先将文件分块,然后询问NameNode,我要写入一个文件到某个路径下,文件有3块,应该怎么写?

2、NameNode回复client,可以分别写到DataNode1、DataNode2、DataNode3、DataNode4上,记住,每个块重复写3份,总共是9份

3、client找到DataNode1、DataNode2、DataNode3、DataNode4,把数据写到他们上面

出于容错的考虑,每个数据块有3个备份,但是3个备份快都直接由client端直接写入势必会带来client端过重的写入压力,这个点是否有更好的解决方案呢?回忆一下mysql主备之间是通过binlog文件进行同步的,HDFS当然也可以借鉴这个思想,数据其实只需要写入到一个datanode上,然后由datanode之间相互进行备份同步,减少了client端的写入压力,那么至于是一个datanode写入成功即成功,还是需要所有的参与备份的datanode返回写入成功才算成功,是可靠性配置的策略,当然这个设置会影响到数据写入的吞吐率,我们可以看到可靠性和效率永远是“鱼和熊掌不可兼得”的。

潜在问题

NameNode确实会回放editlog,但是不是每次都从头回放,它会先加载一个fsimage,这个文件是之前某一个时刻整个NameNode的文件元数据的内存快照,然后再在这个基础上回放editlog,完成后,会清空editlog,再把当前文件元数据的内存状态写入fsimage,方便下一次加载。

这样,全量回放就变成了增量回放,但是如果NameNode长时间未重启过,editlog依然会比较大,恢复的时间依然比较长,这个问题怎么解呢?

SecondNameNode是一个NameNode内的定时任务线程,它会定期地将editlog写入fsimage,然后情况原来的editlog,从而保证editlog的文件大小维持在一定大小。

NameNode挂了, SecondNameNode并不能替代NameNode,所以如果集群中只有一个NameNode,它挂了,整个系统就挂了。hadoop2x之前,整个集群只能有一个NameNode,是有可能发生单点故障的,所以hadoop1x有本身的不稳定性。但是hadoop2x之后,我们可以在集群中配置多个NameNode,就不会有这个问题了,但是配置多个NameNode,需要注意的地方就更多了,系统就更加复杂了。

俗话说“一山不容二虎”,两个NameNode只能有一个是活跃状态active,另一个是备份状态standby,我们看一下两个NameNode的架构图。

两个NameNode通过JournalNode实现同步editlog,保持状态一致可以相互替换。

因为active的NameNode挂了之后,standby的NameNode要马上接替它,所以它们的数据要时刻保持一致,在写入数据的时候,两个NameNode内存中都要记录数据的元信息,并保持一致。这个JournalNode就是用来在两个NameNode中同步数据的,并且standby NameNode实现了SecondNameNode的功能。

进行数据同步 *** 作的过程如下:

active NameNode有 *** 作之后,它的editlog会被记录到JournalNode中,standby NameNode会从JournalNode中读取到变化并进行同步,同时standby NameNode会监听记录的变化。这样做的话就是实时同步了,并且standby NameNode就实现了SecondNameNode的功能。

优点:

缺点:

概述:

Hadoop是一个能够对大量数据进行分布式处理的软件框架,实现了Google的MapReduce编程模型和框架,能够把应用程序分割成许多的 小的工作单元,并把这些单元放到任何集群节点上执行。在MapReduce中,一个准备提交执行的应用程序称为“作业(job)”,而从一个作业划分出 得、运行于各个计算节点的工作单元称为“任务(task)”。此外,Hadoop提供的分布式文件系统(HDFS)主要负责各个节点的数据存储,并实现了 高吞吐率的数据读写。

在分布式存储和分布式计算方面,Hadoop都是用从/从(Master/Slave)架构。在一个配置完整的集群上,想让Hadoop这头大 象奔跑起来,需要在集群中运行一系列后台(deamon)程序。不同的后台程序扮演不用的角色,这些角色由NameNode、DataNode、 Secondary NameNode、JobTracker、TaskTracker组成。其中NameNode、Secondary  NameNode、JobTracker运行在Master节点上,而在每个Slave节点上,部署一个DataNode和TaskTracker,以便 这个Slave服务器运行的数据处理程序能尽可能直接处理本机的数据。对Master节点需要特别说明的是,在小集群中,Secondary  NameNode可以属于某个从节点;在大型集群中,NameNode和JobTracker被分别部署在两台服务器上。

我们已经很熟悉这个5个进程,但是在使用的过程中,我们经常遇到问题,那么该如何入手解决这些问题。那么首先我们需了解的他们的原理和作用。

1Namenode介绍

Namenode 管理者文件系统的Namespace。它维护着文件系统树(filesystem tree)以及文件树中所有的文件和文件夹的元数据(metadata)。管理这些信息的文件有两个,分别是Namespace 镜像文件(Namespace image)和 *** 作日志文件(edit log),这些信息被Cache在RAM中,当然,这两个文件也会被持久化存储在本地硬盘。Namenode记录着每个文件中各个块所在的数据节点的位置信息,但是他并不持久化存储这些信息,因为这些信息会在系统启动时从数据节点重建。

Namenode结构图课抽象为如图:

客户端(client)代表用户与namenode和datanode交互来访问整个文件系统。客户端提供了一些列的文件系统接口,因此我们在编程时,几乎无须知道datanode和namenode,即可完成我们所需要的功能。

11Namenode容错机制

没有Namenode,HDFS就不能工作。事实上,如果运行namenode的机器坏掉的话,系统中的文件将会完全丢失,因为没有其他方法能够将位于不同datanode上的文件块(blocks)重建文件。因此,namenode的容错机制非常重要,Hadoop提供了两种机制。

第一种方式是将持久化存储在本地硬盘的文件系统元数据备份。Hadoop可以通过配置来让Namenode将他的持久化状态文件写到不同的文件系统中。这种写 *** 作是同步并且是原子化的。比较常见的配置是在将持久化状态写到本地硬盘的同时,也写入到一个远程挂载的网络文件系统。

第二种方式是运行一个辅助的Namenode(Secondary Namenode)。 事实上Secondary Namenode并不能被用作Namenode它的主要作用是定期的将Namespace镜像与 *** 作日志文件(edit log)合并,以防止 *** 作日志文件(edit log)变得过大。通常,Secondary Namenode 运行在一个单独的物理机上,因为合并 *** 作需要占用大量的CPU时间以及和Namenode相当的内存。辅助Namenode保存着合并后的Namespace镜像的一个备份,万一哪天Namenode宕机了,这个备份就可以用上了。

但是辅助Namenode总是落后于主Namenode,所以在Namenode宕机时,数据丢失是不可避免的。在这种情况下,一般的,要结合第一种方式中提到的远程挂载的网络文件系统(NFS)中的Namenode的元数据文件来使用,把NFS中的Namenode元数据文件,拷贝到辅助Namenode,并把辅助Namenode作为主Namenode来运行。

----------------------------------------------------------------------------------------------------------------------------------------------------

2、Datanode介绍

Datanode是文件系统的工作节点,他们根据客户端或者是namenode的调度存储和检索数据,并且定期向namenode发送他们所存储的块(block)的列表。

集群中的每个服务器都运行一个DataNode后台程序,这个后台程序负责把HDFS数据块读写到本地的文件系统。当需要通过客户端读/写某个 数据时,先由NameNode告诉客户端去哪个DataNode进行具体的读/写 *** 作,然后,客户端直接与这个DataNode服务器上的后台程序进行通 信,并且对相关的数据块进行读/写 *** 作。

---------------------------------------------------------------------------------------------------------------------------------------------------

3、Secondary NameNode介绍

Secondary  NameNode是一个用来监控HDFS状态的辅助后台程序。就想NameNode一样,每个集群都有一个Secondary  NameNode,并且部署在一个单独的服务器上。Secondary  NameNode不同于NameNode,它不接受或者记录任何实时的数据变化,但是,它会与NameNode进行通信,以便定期地保存HDFS元数据的 快照。由于NameNode是单点的,通过Secondary  NameNode的快照功能,可以将NameNode的宕机时间和数据损失降低到最小。同时,如果NameNode发生问题,Secondary  NameNode可以及时地作为备用NameNode使用。

31NameNode的目录结构如下:

${dfsnamedir}/current/VERSION

/edits

/fsimage

/fstime

32Secondary NameNode的目录结构如下:

${fscheckpointdir}/current/VERSION

/edits

/fsimage

/fstime

/previouscheckpoint/VERSION

/edits

/fsimage

/fstime

如上图,Secondary NameNode主要是做Namespace image和Edit log合并的。

那么这两种文件是做什么的?当客户端执行写 *** 作,则NameNode会在edit log记录下来,(我感觉这个文件有些像Oracle的online redo logo file)并在内存中保存一份文件系统的元数据。

Namespace image(fsimage)文件是文件系统元数据的持久化检查点,不会在写 *** 作后马上更新,因为fsimage写非常慢(这个有比较像datafile)。

由于Edit log不断增长,在NameNode重启时,会造成长时间NameNode处于安全模式,不可用状态,是非常不符合Hadoop的设计初衷。所以要周期性合并Edit log,但是这个工作由NameNode来完成,会占用大量资源,这样就出现了Secondary NameNode,它可以进行image检查点的处理工作。步骤如下:

(1)       Secondary NameNode请求NameNode进行edit log的滚动(即创建一个新的edit log),将新的编辑 *** 作记录到新生成的edit log文件;

(2)       通过>

(3)       读取fsimage到内存中,即加载fsimage到内存,然后执行edits中所有 *** 作(类似OracleDG,应用redo log),并生成一个新的fsimage文件,即这个检查点被创建;

(4)       通过>

(5)       NameNode使用新的fsimage替换原来的fsimage文件,让(1)创建的edits替代原来的edits文件;并且更新fsimage文件的检查点时间。

整个处理过程完成。

Secondary NameNode的处理,是将fsimage和edites文件周期的合并,不会造成nameNode重启时造成长时间不可访问的情况。

--------------------------------------------------------------------------------------------------------------------------------------------------

4、JobTracker介绍

JobTracker后台程序用来连接应用程序与Hadoop。用户代码提交到集群以后,由JobTracker决定哪个文件将被处理,并且为 不同的task分配节点。同时,它还监控所有的task,一旦某个task失败了,JobTracker就会自动重新开启这个task,在大多数情况下这 个task会被放在不用的节点上。每个Hadoop集群只有一个JobTracker,一般运行在集群的Master节点上。

下面我们详细介绍:

41JobClient

我们配置好作业之后,就可以向JobTracker提交该作业了,然后JobTracker才能安排适当的TaskTracker来完成该作业。那么MapReduce在这个过程中到底做了那些事情呢?这就是本文以及接下来的一片博文将要讨论的问题,当然本文主要是围绕客户端在作业的提交过程中的工作来展开。先从全局来把握这个过程吧!

在Hadoop中,作业是使用Job对象来抽象的,对于Job,我首先不得不介绍它的一个大家伙JobClient——客户端的实际工作者。JobClient除了自己完成一部分必要的工作外,还负责与JobTracker进行交互。所以客户端对Job的提交,绝大部分都是JobClient完成的,从上图中,我们可以得知JobClient提交Job的详细流程主要如下:

JobClient在获取了JobTracker为Job分配的id之后,会在JobTracker的系统目录(HDFS)下为该Job创建一个单独的目录,目录的名字即是Job的id,该目录下会包含文件jobxml、jobjar、jobsplit等,其中,jobxml文件记录了Job的详细配置信息,jobjar保存了用户定义的关于job的map、reduce *** 纵,jobsplit保存了job任务的切分信息。在上面的流程图中,我想详细阐述的是JobClient是任何配置Job的运行环境,以及如何对Job的输入数据进行切分。

42JobTracker

上面谈到了客户端的JobClient对一个作业的提交所做的工作,那么这里,就要好好的谈一谈JobTracker为作业的提交到底干了那些个事情——一为作业生成一个Job;二接受该作业。

我们都知道,客户端的JobClient把作业的所有相关信息都保存到了JobTracker的系统目录下(当然是HDFS了),这样做的一个最大的好处就是客户端干了它所能干的事情同时也减少了服务器端JobTracker的负载。下面就来看看JobTracker是如何来完成客户端作业的提交的吧!哦。对了,在这里我不得不提的是客户端的JobClient向JobTracker正式提交作业时直传给了它一个改作业的JobId,这是因为与Job相关的所有信息已经存在于JobTracker的系统目录下,JobTracker只要根据JobId就能得到这个Job目录。

对于上面的Job的提交处理流程,我将简单的介绍以下几个过程:

1创建Job的JobInProgress

JobInProgress对象详细的记录了Job的配置信息,以及它的执行情况,确切的来说应该是Job被分解的map、reduce任务。在JobInProgress对象的创建过程中,它主要干了两件事,一是把Job的jobxml、jobjar文件从Job目录copy到JobTracker的本地文件系统(jobxml->/jobTracker/jobidxml,jobjar->/jobTracker/jobidjar);二是创建JobStatus和Job的mapTask、reduceTask存队列来跟踪Job的状态信息。

2检查客户端是否有权限提交Job

JobTracker验证客户端是否有权限提交Job实际上是交给QueueManager来处理的。

3检查当前mapreduce集群能够满足Job的内存需求

客户端提交作业之前,会根据实际的应用情况配置作业任务的内存需求,同时JobTracker为了提高作业的吞吐量会限制作业任务的内存需求,所以在Job的提交时,JobTracker需要检查Job的内存需求是否满足JobTracker的设置。

上面流程已经完毕,可以总结为下图:

 

--------------------------------------------------------------------------------------------------------------------------

5、TaskTracker介绍

TaskTracker与负责存储数据的DataNode相结合,其处理结构上也遵循主/从架构。JobTracker位于主节点,统领 MapReduce工作;而TaskTrackers位于从节点,独立管理各自的task。每个TaskTracker负责独立执行具体的task,而 JobTracker负责分配task。虽然每个从节点仅有一个唯一的一个TaskTracker,但是每个TaskTracker可以产生多个java 虚拟机(JVM),用于并行处理多个map以及reduce任务。TaskTracker的一个重要职责就是与JobTracker交互。如果 JobTracker无法准时地获取TaskTracker提交的信息,JobTracker就判定TaskTracker已经崩溃,并将任务分配给其他 节点处理。

51TaskTracker内部设计与实现

Hadoop采用master-slave的架构设计来实现Map-Reduce框架,它的JobTracker节点作为主控节点来管理和调度用户提交的作业,TaskTracker节点作为工作节点来负责执行JobTracker节点分配的Map/Reduce任务。整个集群由一个JobTracker节点和若干个TaskTracker节点组成,当然,JobTracker节点也负责对TaskTracker节点进行管理。在前面一系列的博文中,我已经比较系统地讲述了JobTracker节点内部的设计与实现,而在本文,我将对TaskTracker节点的内部设计与实现进行一次全面的概述。

TaskTracker节点作为工作节点不仅要和JobTracker节点进行频繁的交互来获取作业的任务并负责在本地执行他们,而且也要和其它的TaskTracker节点交互来协同完成同一个作业。因此,在目前的Hadoop-02020实现版本中,对工作节点TaskTracker的设计主要包含三类组件:服务组件、管理组件、工作组件。服务组件不仅负责与其它的TaskTracker节点而且还负责与JobTracker节点之间的通信服务,管理组件负责对该节点上的任务、作业、JVM实例以及内存进行管理,工作组件则负责调度Map/Reduce任务的执行。这三大组件的详细构成如下:

 

下面来详细的介绍这三类组件:

服务组件

TaskTracker节点内部的服务组件不仅用来为TaskTracker节点、客户端提供服务,而且还负责向TaskTracker节点请求服务,这一类组件主要包括>

        从Hadoop2开始,可以允许有2个NameNode,一个是active(活跃状态),另一个是standby(待命状态),其中active状态的NameNode对外提供服务,Hadoop1没有此特性

在Hadoop1里面只能有一个NameNode,带来的灾难就是单点故障( single point of failure (SPOF)),每个集群只有一个NameNode,如果计算机或者进程不可用,则整个集群不可用,直到NameNode重新启动或者在单独的计算机

这从两个方面影响了HDFS集群的总体可用性:

在发生意外事件(如机器崩溃)的情况下,集群将不可用,直到技术人员把NameNode重新启动之后

如果NameNode对应的计算机节点需要进行硬件或者软件的升级,就需要停止NameNode服务,这又会导致集群宕机

Hadoop的HA就可以允许在计算机崩溃的情况下,快速切换到新的NameNode,或者允许处于计划维护NameNode有运维人员直接切换到standby服务器上面

                                                                               -------以上取自 hadoopapacheorg 官网解答

HA的架构模式其实是有两种,HDFS High Availability Using the Quorum Journal Manager(企业级开发专用)和NFS for the shared storage 共享编辑日志模式(基本上不用)

共享编辑日志模式 -您将需要有一个共享目录,两台NameNode机器都可以对其进行读/写访问。通常,这是一个支持NFS的远程文件管理器,并安装在每个NameNode计算机上。当前仅支持一个共享的edits目录。因此,系统的可用性受到此共享编辑目录的可用性的限制,因此,为了消除所有单点故障,共享编辑目录需要冗余。具体来说,有到存储的多个网络路径,以及存储本身的冗余(磁盘,网络和电源)。 因此,建议共享存储服务器是高质量的专用NAS设备,而不是简单的Linux服务器。

                                                                                -------以上取自 hadoopapacheorg 官网解答         

所有企业开发里面目前还没遇到过使用这种模式的下面详细介绍QJM模式

为了部署高可用性群集,您应该准备以下内容:

NameNode计算机 -运行活动NameNode和Standby NameNode的计算机应具有彼此等效的硬件,以及与非HA群集中将使用的硬件相同的硬件。

JournalNode计算机 -运行JournalNode的计算机。JournalNode守护程序相对较轻,因此可以合理地将这些守护程序与其他Hadoop守护程序(例如NameNode,JobTracker或YARN ResourceManager)并置在计算机上。 注意: 必须至少有3个JournalNode守护程序,因为必须将编辑日志修改写入大多数JN。这将允许系统容忍单个计算机的故障。您可能还会运行3个以上的JournalNode,但是为了实际增加系统可以容忍的故障数量,您应该运行奇数个JN(即3、5、7等)。请注意,当与N个JournalNode一起运行时,系统最多可以容忍(N-1)/ 2个故障,并继续正常运行。

                                                                                -------以上取自 hadoopapacheorg 官网解答 

这里解释一下,JournalNode上面之所以建议是奇数台,是因为HDFS底层算法他是(N-1)/2的故障,假如是偶数台,4台,(4-1)/2=1,也就是1台挂了,就会导致所有的JournalNode都不能正常运行,但是其实我只挂了一台而已,另外三台完全可以支撑完运行,如果是奇数3台的话,(3-1)/2=1台,挂了一台,还剩下两台,这时候就不能正常运行,但是,再挂一台是不是就超过了过半性原则,这个奇数过半性原理在整个Hadoop中使用很广泛

以三台服务器为例:

dachun001 :zookeeper    nn(NameNode)    zkfc(ZookeeperFailoverControl)       JournalNode  dn(DataNode)

dachun002 :zookeeper    nn(NameNode)    zkfc(ZookeeperFailoverControl)       JournalNode  dn(DataNode)

dachun003 :zookeeper                                  zkfc(ZookeeperFailoverControl)       JournalNode  dn(DataNode)

active NameNode:

接收client的rpc请求,同时自己的editlog写一条日志记录,同时发送给JournalNode日志集群写一条记录,同时接收DataNode的心跳和块报告

standby NameNode:

同时接收JournalNode日志集群的的记录,在自己本身执行,使得自己的元数据和active NameNode是一致的,这步叫做重演

同时也接受DataNode的心跳报告(这个是为了在进行从standby演变到active状态时候更加平滑)

也随时等待从standby-->active状态,对外提供服务。

JournalNode:

JouralNode守护进程相当的轻量级,可以和Hadoop的其他进程部署在一起

active NameNode -->  standby  NameNode的同步数据进程

datanode: 

同时向两个nn发送 心跳 and 块报告

 zkfc(ZookeeperFailoverControl)进程:

监控NameNode的健康状态,可以理解为NameNode和zookeeper的桥梁,standby-active或者active-standby是通过zkfc进程  

NameNode通过zkfc向zookeeper集群定期发送心跳,使得自己被选举上,

当被zookeeperk集群选举为active时,

zkfc进程通过rpc调用NameNode状态变为active。

在典型的HA群集中,将两个单独的计算机配置为NameNode。在任何时间点,恰好其中一个NameNode处于 活动 状态,而另一个处于 Standby 状态。Active NameNode负责群集中的所有客户端 *** 作,而Standby只是充当从属,并保持足够的状态以在必要时提供快速故障转移。

为了使Standby节点保持其状态与Active节点同步,两个节点都与称为“ JournalNodes”(JN)的一组单独的守护程序进行通信。当活动节点执行任何名称空间修改时,它会持久地将修改记录记录到这些JN的大多数中。Standby节点能够从JN读取编辑内容,并不断监视它们以查看编辑日志的更改。当“备用节点”看到编辑内容时,会将其应用到自己的名称空间。发生故障转移时,备用服务器将确保在将自身升级为活动状态之前,已从JournalNode读取所有编辑内容。这样可确保在发生故障转移之前,名称空间状态已完全同步。

为了提供快速故障转移,备用节点还必须具有有关集群中块位置的最新信息。为了实现这一点,DataNode被配置了两个NameNode的位置,并向两者发送块位置信息和心跳。

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

yarn的HA相对于HDFS的HA就没有这么复杂,他的NM(NodeManager)只会向active的RM(ResourceManager)发送心跳信息,

zkfc是和ResourceManager在同一个进程中,即ZKFC是一个 线程 在 ResourceManager 进程中,如果这个ResourceManager进程挂了,这个ZKFC线程就挂了

RM(ReourceManager)进程:

a启动时会向zk(zookeeper)集群的hadoop-ha目录写个lock文件,

写成功就标识为active,否则为standby。

standby rm(ResourceManager)会一直监控lock文件是否存在,如果不存在就尝试去创建,争取为active。

b会接收client客户端的请求,接收和监控nm的资源汇报,

负责资源的分配和调度,启动和监控application master。

rmstore:

arm的作业信息是存储在zk(zookeeper)的/rmstore,

active rm会向这个目录写作业app信息。

b当active rm挂了,另外一个standby rm成功转为active状态,

就会从这里读取对应的作业的信息,

重新构建作业的内存信息,启动内部服务,

开始接收NM(NodeManager)心跳,构建集群资源信息,且开始接收客户端提交的作业的请求。

1 hdfs基本工作流程

1 hdfs初始化目录结构

hdfs namenode -format 只是初始化了namenode的工作目录

而datanode的工作目录是在datanode启动后自己初始化的

namenode在format初始化的时候会形成两个标识:

blockPoolId:

clusterId:

新的datanode加入时,会获取这两个标识作为自己工作目录中的标识

一旦namenode重新format后,namenode的身份标识已变,而datanode如果依然

持有原来的id,就不会被namenode识别

2 hdfs的工作机制

hdfs集群分为两大角色:NameNode,DataNode (Secondary NameNode)

NameNode负责管理整个文件的元数据(命名空间信息,块信息) 相当于Master

DataNode负责管理用户的文件数据块 相当于Salve

文件会按照固定的大小(block=128M)切成若干块后分布式存储在若干个datanode节点上

每一个文件块有多个副本(默认是三个),存在不同的datanode上

DataNode会定期向NameNode汇报自身所保存的文件block信息,而namenode则会负责保持文件副本数量

hdfs的内部工作机制会对客户的保持透明,客户端请求方法hdfs都是通过向namenode申请来进行访问

SecondaryNameNode有两个作用,一是镜像备份,二是日志与镜像的定期合并

3 hdfs写入数据流程

1客户端要向hdfs写入数据,首先要跟namenode通信以确认可以写文件并获得接收文件block的datanode,然后,客户端按照顺序将文件block逐个传给相应datanode,并由接收到block的datanode负责向其他datanode复制block副本

4 写入数据步骤详细解析

客户端向namenode通信,请求上传文件,namenode检查目标文件是否已经存在,父目录是否存在

namenode返回给客户端,告知是否可以上传

客户端请求第一个block该传输到那些datanode服务器上

namenode返回3个datanode服务器abc

客户端请求3台datanode的一台a上传数据(本质上是一个rpc调用,建立pipeline),A收到请求后会继续调用b,然后b调用c,将整个pipeline建立完成,逐级返回客户端。

客户端开始忘a上传第一个block(先从磁盘读取数据放入本地内存缓存),以packet为单位,a收到一个packet将会传给b,b传给c,a每传一个packet会放入一个应答队列等待应答

宕一个block传输完之后,客户端再次请求namenode上传第二个block的服务器

1 Hadoop HA架构详解

11 HDFS HA背景

HDFS集群中NameNode 存在单点故障(SPOF)。对于只有一个NameNode的集群,如果NameNode机器出现意外情况,将导致整个集群无法使用,直到NameNode 重新启动。

影响HDFS集群不可用主要包括以下两种情况:一是NameNode机器宕机,将导致集群不可用,重启NameNode之后才可使用;二是计划内的NameNode节点软件或硬件升级,导致集群在短时间内不可用。

为了解决上述问题,Hadoop给出了HDFS的高可用HA方案:HDFS通常由两个NameNode组成,一个处于active状态,另一个处于standby状态。Active NameNode对外提供服务,比如处理来自客户端的RPC请求,而Standby NameNode则不对外提供服务,仅同步Active NameNode的状态,以便能够在它失败时快速进行切换。

12 HDFS HA架构

一个典型的HA集群,NameNode会被配置在两台独立的机器上,在任何时间上,一个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状态的问题。

基于QJM的HDFS HA方案如上图所示,其处理流程为:集群启动后一个NameNode处于Active状态,并提供服务,处理客户端和DataNode的请求,并把editlog写到本地和share editlog(这里是QJM)中。另外一个NameNode处于Standby状态,它启动的时候加载fsimage,然后周期性的从share editlog中获取editlog,保持与Active节点的状态同步。为了实现Standby在Active挂掉后迅速提供服务,需要DataNode同时向两个NameNode汇报,使得Stadnby保存block to DataNode信息,因为NameNode启动中最费时的工作是处理所有DataNode的blockreport。为了实现热备,增加FailoverController和Zookeeper,FailoverController与Zookeeper通信,通过Zookeeper选举机制,FailoverController通过RPC让NameNode转换为Active或Standby。

13 HDFS HA配置要素

NameNode机器:两台配置对等的物理机器,它们分别运行Active和Standby Node。

JouralNode机器:运行JouralNodes的机器。JouralNode守护进程相当的轻量级,可以和Hadoop的其他进程部署在一起,比如NameNode、DataNode、ResourceManager等,至少需要3个且为奇数,如果你运行了N个JNS,那么它可以允许(N-1)/2个JNS进程失效并且不影响工作。

在HA集群中,Standby NameNode还会对namespace进行checkpoint *** 作(继承Backup Namenode的特性),因此不需要在HA集群中运行SecondaryNameNode、CheckpointNode或者BackupNode。

14 HDFS HA配置参数

需要在hdfsxml中配置如下参数:

dfsnameservices:HDFS NN的逻辑名称,例如myhdfs。

dfshanamenodesmyhdfs:给定服务逻辑名称myhdfs的节点列表,如nn1、nn2。

dfsnamenoderpc-addressmyhdfsnn1:myhdfs中nn1对外服务的RPC地址。

dfsnamenode>

dfsnamenodesharededitsdir:JournalNode的服务地址。

dfsjournalnodeeditsdir:JournalNode在本地磁盘存放数据的位置。

dfshaautomatic-failoverenabled:是否开启NameNode失败自动切换。

dfshafencingmethods :配置隔离机制,通常为sshfence。

15 HDFS自动故障转移

HDFS的自动故障转移主要由Zookeeper和ZKFC两个组件组成。

Zookeeper集群作用主要有:一是故障监控。每个NameNode将会和Zookeeper建立一个持久session,如果NameNode失效,那么此session将会过期失效,此后Zookeeper将会通知另一个Namenode,然后触发Failover;二是NameNode选举。ZooKeeper提供了简单的机制来实现Acitve Node选举,如果当前Active失效,Standby将会获取一个特定的排他锁,那么获取锁的Node接下来将会成为Active。

ZKFC是一个Zookeeper的客户端,它主要用来监测和管理NameNodes的状态,每个NameNode机器上都会运行一个ZKFC程序,它的职责主要有:一是健康监控。ZKFC间歇性的ping NameNode,得到NameNode返回状态,如果NameNode失效或者不健康,那么ZKFS将会标记其为不健康;二是Zookeeper会话管理。当本地NaneNode运行良好时,ZKFC将会持有一个Zookeeper session,如果本地NameNode为Active,它同时也持有一个“排他锁”znode,如果session过期,那么次lock所对应的znode也将被删除;三是选举。当集群中其中一个NameNode宕机,Zookeeper会自动将另一个激活。

16 YARN HA架构

YARN的HA架构和HDFSHA类似,需要启动两个ResourceManager,这两个ResourceManager会向ZooKeeper集群注册,通过ZooKeeper管理它们的状态(Active或Standby)并进行自动故障转移。

2 高可用集群规划

21 集群规划

根据Hadoop的HA架构分析,规划整个集群由5台主机组成,具体情况如下表所示:

主机名

IP地址

安装的软件

JPS

hadoop-master1

172162081

Jdk/hadoop

Namenode/zkfc/resourcemanager/

JobHistoryServer

hadoop-master2

172162082

Jdk/hadoop

Namenode/zkfc/resourcemanager/

WebProxyServer

hadoop-slave1

172162083

Jkd/hadoop/zookeepe

Datanode/journalnode/nodemanager/

quorumPeerMain

hadoop-slave2

172162084

Jkd/hadoop/zookeeper

Datanode/journalnode/nodemanager/

quorumPeerMain

hadoop-slave3

172162085

Jkd/hadoop/zookeeper

Datanode/journalnode/nodemanager/

quorumPeerMain

需要说明以下几点:

HDFS HA通常由两个NameNode组成,一个处于Active状态,另一个处于Standby状态。Active NameNode对外提供服务,而Standby NameNode则不对外提供服务,仅同步Active NameNode的状态,以便能够在它失败时快速进行切换。

Hadoop 20官方提供了两种HDFS HA的解决方案,一种是NFS,另一种是QJM。这里我们使用简单的QJM。在该方案中,主备NameNode之间通过一组JournalNode同步元数据信息,一条数据只要成功写入多数JournalNode即认为写入成功。通常配置奇数个JournalNode,这里还配置了一个Zookeeper集群,用于ZKFC故障转移,当Active NameNode挂掉了,会自动切换Standby NameNode为Active状态。

YARN的ResourceManager也存在单点故障问题,这个问题在hadoop-241得到了解决:有两个ResourceManager,一个是Active,一个是Standby,状态由zookeeper进行协调。

YARN框架下的MapReduce可以开启JobHistoryServer来记录历史任务信息,否则只能查看当前正在执行的任务信息。

Zookeeper的作用是负责HDFS中NameNode主备节点的选举,和YARN框架下ResourceManaer主备节点的选举。

22 软件版本

*** 作系统:CentOS Linux release 701406

JDK:Java(TM)SE Runtime Environment (build 170_79-b15)

Hadoop:Hadoop 260-cdh571

ZooKeeper:zookeeper-345-cdh571

3 Linux环境准备

集群各节点进行如下修改配置:

31 创建用户并添加权限

// 切换root用户

$ su root

// 创建hadoop用户组

# groupadd hadoop

// 在hadoop用户组中创建hadoop用户

# useradd -g hadoop hadoop

// 修改用户hadoop密码

# passwd hadoop

// 修改sudoers配置文件给hadoop用户添加sudo权限

# vim /etc/sudoers

hadoop    ALL=(ALL)       ALL

// 测试是否添加权限成功

# exit

$ sudo ls /root

32 修改IP地址和主机名

// 切换root用户

$ su root

// 修改本机IP地址

# vim /etc/sysconfig/network-scripts/ifcfg-eth0

// 重启网络服务

# service network restart

// 修改主机名

# hostnamectl set-hostname 主机名

// 查看主机名

# hostnamectl status

33 设置IP地址与主机名映射

// 切换root用户

$ su root

// 编辑hosts文件

# vim /etc/hosts

172162081    hadoop-master1

172162082    hadoop-master2

172162083    hadoop-slave1

172162084    hadoop-slave2

172162085    hadoop-slave3

34 关闭防火墙和Selinux

// 切换root用户

$ su root

// 停止firewall防火墙

# systemctl stop firewalldservice

// 禁止firewall开机启动

# systemctl disable firewalldservice

// 开机关闭Selinux

# vim /etc/selinux/config

SELINUX=disabled

// 重启机器后root用户查看Selinux状态

# getenforce

35 配置SSH免密码登录

// 在hadoop-master1节点生成SSH密钥对

$ ssh-keygen -t rsa

// 将公钥复制到集群所有节点机器上

$ ssh-copy-id hadoop-master1

$ ssh-copy-id hadoop-master2

$ ssh-copy-id hadoop-slave1

$ ssh-copy-id hadoop-slave2

$ ssh-copy-id hadoop-slave3

// 通过ssh登录各节点测试是否免密码登录成功

$ ssh hadoop-master2

备注:在其余节点上执行同样的 *** 作,确保集群中任意节点都可以ssh免密码登录到其它各节点。

36 安装JDK

// 卸载系统自带的openjdk

$ suroot

# rpm-qa | grep java

# rpm-e --nodeps java-170-openjdk-17075-2542el7_0x86_64

# rpm-e --nodeps java-170-openjdk-headless-17075-2542el7_0x86_64

# rpm-e --nodeps tzdata-java-2015a-1el7_0noarch

# exit

// 解压jdk安装包

$ tar-xvf jdk-7u79-linux-x64targz

// 删除安装包

$ rmjdk-7u79-linux-x64targz

// 修改用户环境变量

$ cd ~

$ vimbash_profile

exportJAVA_HOME=/home/hadoop/app/jdk170_79

exportPATH=$PATH:$JAVA_HOME/bin

// 使修改的环境变量生效

$ sourcebash_profile

// 测试jdk是否安装成功

$ java-version

4 集群时间同步

如果集群节点时间不同步,可能会出现节点宕机或引发其它异常问题,所以在生产环境中一般通过配置NTP服务器实现集群时间同步。本集群在hadoop-master1节点设置ntp服务器,具体方法如下:

// 切换root用户

$ su root

// 查看是否安装ntp

# rpm -qa | grep ntp

// 安装ntp

# yum install -y ntp

// 配置时间服务器

# vim /etc/ntpconf

# 禁止所有机器连接ntp服务器

restrict default ignore

# 允许局域网内的所有机器连接ntp服务器

restrict 17216200 mask 2552552550 nomodify notrap

# 使用本机作为时间服务器

server 12712710

// 启动ntp服务器

# service ntpd start

// 设置ntp服务器开机自动启动

# chkconfig ntpd on

集群其它节点通过执行crontab定时任务,每天在指定时间向ntp服务器进行时间同步,方法如下:

// 切换root用户

$ su root

// 执行定时任务,每天00:00向服务器同步时间,并写入日志

# crontab -e

0       0                           /usr/sbin/ntpdate hadoop-master1>> /home/hadoop/ntpdlog

// 查看任务

# crontab -l

5 Zookeeper集群安装

Zookeeper是一个开源分布式协调服务,其独特的Leader-Follower集群结构,很好的解决了分布式单点问题。目前主要用于诸如:统一命名服务、配置管理、锁服务、集群管理等场景。大数据应用中主要使用Zookeeper的集群管理功能。

本集群使用zookeeper-345-cdh571版本。首先在hadoop-slave1节点安装Zookeeper,方法如下:

// 新建目录

$ mkdir app/cdh

// 解压zookeeper安装包

$ tar -xvf zookeeper-345-cdh571targz -C app/cdh/

// 删除安装包

$ rm -rf zookeeper-345-cdh571targz

// 配置用户环境变量

$ vim bash_profile

export ZOOKEEPER_HOME=/home/hadoop/app/cdh/zookeeper-345-cdh571

export PATH=$PATH:$ZOOKEEPER_HOME/bin

// 使修改的环境变量生效

$ sourcebash_profile

// 修改zookeeper的配置文件

$ cd app/cdh/zookeeper-345-cdh571/conf/

$ cp zoo_samplecfg zoocfg

$ vim zoocfg

# 客户端心跳时间(毫秒)

tickTime=2000

# 允许心跳间隔的最大时间

initLimit=10

# 同步时限

syncLimit=5

# 数据存储目录

dataDir=/home/hadoop/app/cdh/zookeeper-345-cdh571/data

# 数据日志存储目录

dataLogDir=/home/hadoop/app/cdh/zookeeper-345-cdh571/data/log

# 端口号

clientPort=2181

# 集群节点和服务端口配置

server1=hadoop-slave1:2888:3888

server2=hadoop-slave2:2888:3888

server3=hadoop-slave3:2888:3888

# 以下为优化配置

# 服务器最大连接数,默认为10,改为0表示无限制

maxClientCnxns=0

# 快照数

autopurgesnapRetainCount=3

# 快照清理时间,默认为0

autopurgepurgeInterval=1

// 创建zookeeper的数据存储目录和日志存储目录

$ cd

$ mkdir -p data/log

// 在data目录中创建一个文件myid,输入内容为1

$ echo "1" >> data/myid

// 修改zookeeper的日志输出路径(注意CDH版与原生版配置文件不同)

$ vim libexec/zkEnvsh

if [ "x${ZOO_LOG_DIR}" = "x" ]

then

ZOO_LOG_DIR="$ZOOKEEPER_HOME/logs"

fi

if [ "x${ZOO_LOG4J_PROP}" = "x" ]

then

ZOO_LOG4J_PROP="INFO,ROLLINGFILE"

fi

// 修改zookeeper的日志配置文件

$ vim conf/log4jproperties

zookeeperrootlogger=INFO,ROLLINGFILE

// 创建日志目录

$ mkdir logs

将hadoop-slave1节点上的Zookeeper目录同步到hadoop-slave2和hadoop-slave3节点,并修改Zookeeper的数据文件。此外,不要忘记设置用户环境变量。

// 在hadoop-slave1中将zookeeper目录复制到其它节点

$ cd ~

$ scp -r app/cdh/zookeeper-345-cdh571hadoop-slave2:/home/hadoop/app/cdh

$ scp -r app/cdh/zookeeper-345-cdh571 hadoop-slave3:/home/hadoop/app/cdh

//在hadoop-slave2中修改data目录中的myid文件

$ echo "2" >app/cdh/zookeeper-345-cdh571/data/myid

//在hadoop-slave3中修改data目录中的myid文件

$ echo "3" >app/cdh/zookeeper-345-cdh571/data/myid

最后,在安装了Zookeeper的各节点上启动Zookeeper,并查看节点状态,方法如下:

// 启动

$ zkServersh start

// 查看状态

$ zkServersh status

// 关闭

以上就是关于NoSQL-HDFS-基本概念全部的内容,包括:NoSQL-HDFS-基本概念、hadoop中主机有多少个进程是对的、Hadoop的HA等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/9342239.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-27
下一篇 2023-04-27

发表评论

登录后才能评论

评论列表(0条)

保存