Hadoop离线计算 复习&&面试笔记

340 阅读28分钟

图片有点小问题,十分抱歉 原文:www.sukidesu.top/index.php/a…

Hadoop 分布式文件系统 - HDFS

简介

分布式存储系统HDFS(Hadoop Distributed File System)。 其实就是一个文件系统,类似于linux的文件系统。有目录,目录下可以存储文件。但它又是一个分布式的文件系统。 基本原理:

  • 将文件切分成等大的数据块,分别存储到多台机器上。
  • 每个数据块存在多个备份。
  • 将数据切分、容错、负载均衡等功能透明化。
  • 可将HDFS看成是一个巨大、具有容错性的磁盘。

优点 : 处理超大文件。 流式的访问数据。 运行于廉价的商用机器集群上 。 缺点 : 不适合存储大量小文件。 不适合低延迟数据访问 。 不支持多用户写入及任意修改文件 。

  • 超大文件 指具有几百MB/GB/TB的文件。
  • 流式数据访问 一次写入,多次读取是最高效的访问模式。数据集通常有数据源生成或从数据源复制而来,接着对其进行分析。每次分析都将涉及数据集的大部分数据,因此读取整个数据集的时间延迟比读取第一条记录的时间延迟要重要。
  • 商用硬件 Hadoop 不需要运行在昂贵且可靠的硬件上。
  • 低时间延迟的数据访问 HDFS是为高数据吞吐量应用优化的,对于低延迟的访问请求,HBase是更好的选择。
  • 大量小文件 namenode将文件系统的元数据存储在内存中,因此文件系统所能存储的文件总数受限于namenode的内存容量
  • 多用户写入,任意修改文件 HDFS中的文件写入只支持单个写入者,而且写操作总是以“只添加”的方式在文件末尾写数据

实现原理

数据块

  • 每个磁盘都有默认的数据块大小,这是磁盘进行数据读/写的最小单位。构建于单个磁盘之上的文件系统通过磁盘块来管理该文件系统中的块,该文件系统块的大小可以是磁盘块的整数倍。
  • HDFS 同样也有块 (block) 的概念,但是大得多,默认为 128 MB 。与单一磁盘上的文件系统相似,HDFS 上的文件也被划分为块大小的多个分块 (chunk) ,作为独立的存储单元。但与其他文件系统不同的是, HDFS 中小于一个块大小的文件不会占据整个块的空间。

优点 :

  • 一个大文件不用存储于整块磁盘上,可以分布式存储。
  • 使用块抽象而非整个文件作为存储单元,大大简化了存储子系统的设计。这对于故障种类繁多的分布式系统尤为重要。 与磁盘管理相似,HDFS提供了fsck命令可以显示块信息。 hdfs fsck / -files -blocks 95838-pqfwnl3wvgl.png

NameNode

namenode是HDFS架构的主节点 功能:

  • 管理各个从节点的状态(DataNode)
  • 记录存储在HDFS上的所有数据的元数据信息。例如,block存储的位置,文件大小,文件权限,文件层级等等。这些信息以两个文件的形式永久保存在本地磁盘。

命名空间镜像文件(FsImage):fsimage是HDFS文件系统存于硬盘中的元数据检查点,里面记录了自最后一次检查点之前HDFS文件系统中所有目录和文件的序列化信息。 编辑日志(edit-logs)文件:保存了自最后一次检查点之后所有针对HDFS文件系统的操作,比如: 增加文件、重命名文件、删除目录等等。

  • 记录了存储在HDFS上文件的所有变化,例如文件被删除,namenode会记录到editlog中。
  • 接受DataNode的心跳和各个datanode上的block报告信息,确保DataNode是否存活。
  • 负责处理所有块的复制因子。
  • 如果DataNode节点宕机,NameNode会选择另外一个DataNode均衡复制因子,并做负载均衡。

Sencondary NameNode

Sencondary NameNode是NameNode的助手,不要将其理解成是NameNode的备份。Secondary NameNode 的整个目的在HDFS中提供一个Checkpoint Node,所以也被叫做checkpoint node。 功能:

  • 定时的从NameNode获取EditLogs,并更新到FsImage上。
  • 一旦它有新的fsimage文件,它将其拷贝回NameNode上,NameNode在下次重启时会使用这个新的fsimage文件,从而减少重启的时间。

注意:关于NameNode是什么时候将改动写到edit logs中的?这个操作实际上是由 DataNode的写操作触发的,当我们往 DataNode写文件时,DataNode会跟 NameNode通信,告诉NameNode什么文件的第几个block放在它那里,NameNode 这个时候会将这些元数据信息写到edit logs文件中。

1>.首先,我们做个假设,如果存储在NameNode节点的磁盘中,因为经常需要进行随机访问,还有响应客户请求,必然是效率过低。因此,元数据需要存放在内存中。但如果只存在内存中,一旦断电,元数据丢失,整个集群就无法工作了。因此产生在磁盘中备份元数据的FsImage。 2>.这样又会带来新的问题,当在内存中的元数据更新时,如果同时更新FsImage,就会导致效率过低,但如果不更新,就会发生一致性问题,一旦NameNode节点断电,就会产生数据丢失。因此,引入Edits文件(只进行追加操作,效率很高)。每当元数据有更新或者添加元数据时,修改内存中的元数据并追加到Edits中。这样,一旦NameNode节点断电,可以通过FsImage和Edits的合并,合成元数据。 3>.但是,如果长时间添加数据到Edits中,会导致该文件数据过大,效率降低,而且一旦断电,恢复元数据需要的时间过长。因此,需要定期进行FsImage和Edits的合并,如果这个操作由NameNode节点完成,又会效率过低。因此,引入一个新的节点SecondaryNamenode,专门用于FsImage和Edits的合并。 出处:www.cnblogs.com/yinzhengjie…

DataNode

DataNode是HDFS架构的从节点,管理各自节点的Block信息。 功能

  • 多个数据实际是存储到DataNode上面。
  • DataNode分别运行在独立的节点上。
  • DataNode执行客户端级别的读写请求。
  • 向NameNode发送心跳(默认是3s),报告各自节点的健康状况

复制因子

HDFS为我们提供了可靠的存储,就是因为复制因子。默认复制因子为3.DataNote会定时发送心跳给Namenode,汇报各自节点的block信息。NameNode收集到这些信息后,会对超出复制因子的block删除。复制因子不足的block做添加。

机架感知

分布式的集群通常包含非常多的机器,由于受到机架槽位和交换机网口的限制,通常大型的分布式集群都会跨好 几个机架,由多个机架上的机器共同组成一个分布式集群。机架内的机器之间的网络速度通常都会高于跨机架机器之间的网络速度,并且机架之间机器的网络通信通常受到上层交换机间网络带宽的限制。

Hadoop在设计时考虑到数据的安全与高效,数据文件默认在HDFS上存放三份,存储策略为: 第一个block副本放在客户端所在的数据节点里(如果客户端不在集群范围内,则从整个集群中随机选择一个合适的数据节点来存放)。 第二个副本放置在与第一个副本所在节点相同机架内的其它数据节点上 第三个副本放置在不同机架的节点上

这样如果本地数据损坏,节点可以从同一机架内的相邻节点拿到数据,速度肯定比从跨机架节点上拿数据要快; 同时,如果整个机架的网络出现异常,也能保证在其它机架的节点上找到数据。 为了降低整体的带宽消耗和读取延时,HDFS会尽量让读取程序读取离它最近的副本。 如果在读取程序的同一个机架上有一个副本,那么就读取该副本。 如果一个HDFS集群跨越多个数据中心,那么客户端也将首先读本地数据中心的副本。 那么Hadoop是如何确定任意两个节点是位于同一机架,还是跨机架的呢?答案就是机架感知。

块缓存

DataNode通常直接从磁盘读取数据,但是频繁使用的Block可以在内存中缓存。默认情况下,一个Block只有一个数据节点会缓存。但是可以针对每个文件可以个性化配置。 作业调度器可以利用缓存提升性能,例如MapReduce可以把任务运行在有Block缓存的节点上。 用户或者应用可以向NameNode发送缓存指令(缓存哪个文件,缓存多久), 缓存池的概念用于管理一组缓存的权限和资源。

HDFS读写流程

读流程

1、客户端发送请求,调用DistributedFileSystem API的open方法发送请求到Namenode,获得block的位置信息,因为真正的block是存在Datanode节点上的,而namenode里存放了block位置信息的元数据。 2、Namenode返回所有block的位置信息,并将这些信息返回给客户端。 3、客户端拿到block的位置信息后调用FSDataInputStream API的read方法并行的读取block信息,图中4和5流程是并发的,block默认有3个副本,所以每一个block只需要从一个副本读取就可以。以packet(一个packet为64kb)为单位来做校验 4、datanode返回给客户端。

写流程

1、跟NameNode通信请求上传文件,NameNode检查目标文件是否已经存在,父目录是否已经存在 2、NameNode返回是否可以上传 3、Client先对文件进行切分,请求第一个block该传输到哪些DataNode服务器上 4、NameNode返回3个DataNode服务器DataNode 1,DataNode 2,DataNode 3 5、Client请求3台中的一台DataNode 1(网络拓扑上的就近原则,如果都一样,则随机挑选一台DataNode)上传数据(本质上是一个RPC调用,建立pipeline),DataNode 1收到请求会继续调用DataNode 2,然后DataNode 2调用DataNode 3,将整个pipeline建立完成,然后逐级返回客户端 6、Client开始往DataNode 1上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以pocket为单位。写入的时候DataNode会进行数据校验,它并不是通过一个packet进行一次校验而是以chunk为单位进行校验(512byte)。DataNode 1收到一个packet就会传给DataNode 2,DataNode 2传给DataNode 3,DataNode 1每传一个pocket会放入一个应答队列等待应答 7、当一个block传输完成之后,Client再次请求NameNode上传第二个block的服务器. 8、需要注意的是上传文件的拥有者就是客户端上传文件的用户名,举个例子用windows客户端上传文件,那么这个文件的拥有者就是administrator,和linux上的系统用户名不是一样的。

元数据信息维护

一、NameNode启动时如何维护元数据:

1、概念介绍:

Edits文件:NameNode在本地操作hdfs系统的文件都会保存在Edits日志文件中。也就是说当文件系统中的任何元数据产生操作时,都会记录在Edits日志文件中。eg:在HDFS上创建一个文件,NameNode就会在Edits中插入一条记录。同样如果修改或者删除等操作,也会在Edits日志文件中新增一条数据。 FsImage映像文件:包括数据块到文件的映射,文件的属性等等,都存储在一个称为FsImage的文件中,这个文件也是放在NameNode所在的文件系统中。

2、流程介绍:

①、加载fsimage映像文件到内存 ②、加载edits文件到内存 ③、在内存将fsimage映像文件和edits文件进行合并 ④、将合并后的文件写入到fsimage中 ⑤、清空原先edits中的数据,使用一个空的edits文件进行正常操作

3、流程图分析:

4、疑问

因为NameNode只有在启动的阶段才合并fsimage和edits,那么如果运行时间长了,edits文件可能会越来越大,在下一次启动NameNode时会花很长的时间,请问能否让fsimage映像文件和edits日志文件定期合并呢? 答案肯定是可以的,为了解决这个问题我们就要用到Secondary NameNode了,Secondary NameNode主要的作用是什么呢?他是如何将fsimage和edits进行合并的呢?带着疑问再次进行分析。

二、Secondary NameNode工作流程:

1、Secondary NameNode和NameNode的区别:

NameNode: ①、存储文件的metadata,运行时所有数据都保存在内存中,这个的HDFS可存储的文件受限于NameNode的内存。 ②、NameNode失效则整个HDFS都失效了,所以要保证NameNode的可用性。 Secondary NameNode: ①、定时与NameNode进行同步,定期的将fsimage映像文件和Edits日志文件进行合并,并将合并后的传入给NameNode,替换其镜像,并清空编辑日志。如果NameNode失效,需要手动的将其设置成主机。 ②、Secondary NameNode保存最新检查点的目录和NameNode的目录结构相同。所以NameNode可以在需要的时候应用Secondary NameNode上的检查点镜像。

2、什么时候checkpoint

①、连续两次的检查点最大时间间隔,默认是3600秒,可以通过配置“fs.checkpoint.period”进行修改 ②、Edits日志文件的最大值,如果超过这个值就会进行合并即使不到1小时也会进行合并。可以通过“fs.checkpoint.size”来配置,默认是64M;

3、Secondary NameNode的工作流程

①、NameNode通知Secondary NameNode进行checkpoint。 ②、Secondary NameNode通知NameNode切换edits日志文件,使用一个空的。 ③、Secondary NameNode通过Http获取NmaeNode上的fsimage映像文件(只在第一次的时候)和切换前的edits日志文件。 ④、Secondary NameNode在内容中合并fsimage和Edits文件。 ⑤、Secondary NameNode将合并之后的fsimage文件发送给NameNode。 ⑥、NameNode用Secondary NameNode 传来的fsImage文件替换原先的fsImage文件。

4、流程图分析:

12342151-65de25ec06f2c8ab.png

Hadoop分布式计算框架-MR

MapReduce的特点

  • 良好的扩展性。
  • 高容错性。
  • 适合PB级及海量数据的离线处理

序列化

序列化是指将结构化的数据转化为字节流以便在网络上传输或写入到磁盘进行永久存储的过程,反序列化是指将字节流转换为结构化对象的逆过程 Hadoop实现了自己的序列化格式Writeable

MapReduce流程

MapTask阶段: 1.read阶段:当客户端提交job的时候,根据附加的三个信息(切片信息和jar包以及xml文件)去开启相应数量MapTask读取文件。maptask调用InputFormat,InputFormat又调用RecordReader从输入文件中解析出一个个K/V。 2.map阶段:解析出的key/value交给用户编写map()函数处理,并产生一系列新的key/value 3.partition阶段:当map阶段结束后,将切割完成的数据输送到环形缓冲区并分区排序,系统默认按照key排序,按字典顺序排序,排序方式是快排(快速排序)。 4.溢写阶段:就是当环形缓冲区数据达到其大小的**80%**时(默认大小为100M),将数据写入磁盘。 5.combiner阶段:意为数据归并,即将数据进行一定的归并操作。可有可无。在适当时候使用combiner,可以减少网络传输数据量,优化Hadoop框架性能。

ReduceTask阶段

1.Copy阶段:通过远程数据拷贝方式,从MapTask中拷贝已处理好的数据到内存。注意:(MapTask和ReduceTask很大程度不再同一台服务器,这就是为什么需要序列化和反序列化(bean对象))。 2.Meger阶段:即合并阶段。当拷贝过来的多个小文件合并成一个大的文件。当达到内存数据量的阈值(内存大小)时,自动会将数据写入磁盘。 3.sort阶段:就是按照某种需求比如分组排序,与meger阶段同时进行。用户编写reduce()函数输入数据是按key进行聚集的一组数据。为了将key相同的数据聚在一起,Hadoop采用了基于排序的策略。由于各个MapTask已经实现对自己的处理结果进行了局部排序,因此,ReduceTask只需对所有数据进行一次归并排序即可。 4.reduce阶段:将Reduce结果写入到指定的分区文件中。

MapTask的个数由什么决定:

  1. 文件的大小。当块(dfs.block.size)为128m时,如果输入文件为128m,会被划分为1个split;当块为256m,会被划分为2个split。
  2. 文件的个数。FileInputFormat按照文件分割split,并且只会分割大文件,即那些大小超过HDFS块的大小的文件。如果HDFS中dfs.block.size设置为128m,而输入的目录中文件有100个,则划分后的split个数至少为100个。
  3. splitSize的大小。分片是按照splitszie的大小进行分割的,一个split的大小在没有设置的情况下,默认等于hdfs block的大小。 ———————————————— 版权声明:本文为CSDN博主「机器熊技术大杂烩」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/majianxiong…

MapReduce 调优

95629-3wze724ew8q.png

YARN

YARN背景

YARN是在MRv1基础上演化而来的,它克服了MRv1中的各种局限性。

  • 扩展性差:在 MRv1 中,JobTracker 同时兼备了资源管理和作业控制两个功能,这成为系统的一个最大瓶颈,严重制约了 Hadoop 集群扩展性。
  • 可靠性差:MRv1采用了master/slave结构,其中master存在单点故障问题,一旦它出现故障将导致整个集群不可用
  • 资源利用率低:MRv1采用了基于槽位的资源分配模型,槽位是一种粗粒度的资源划分单位,通常一个任务不会用完槽位对应的资源,其他任务也无法使用这些空闲资源。此外,Hadoop将槽位分为Map Slot和Reduce Slot两种,且不允许它们之间共享, 常常会导致一种槽位资源紧张而另外一种闲置(比如一个作业刚刚提交时,只会运行Map Task,此时Reduce Slot闲置)。
  • 无法支持多种计算框架 48637-0vmevxh7rzfl.png

Yarn的优势

  • 资源利用率高:一种计算框架一个集群模式,往往会出现某段时间,有些计算框架的集群资源紧张而另外一些集群 资源却空闲。共享模式通过多种框架共享资源,使得集群中的资源得到更加充分的利用。
  • 运维成本低:共享模式只需要少数管理员统一管理一个集群即可。
  • 数据共享:跨集群数据移动耗时且硬件成本也高。共享模式使得多种计算框架共享数据和硬件,大大减少成本。

Yarn基本架构

76426-vygza8m81tl.png

  • ResourceManager(RM):全局的资源管理器,负责整个系统资源的管理和分配。由调度器(Scheduler)和应用程序管理(Applications Manager ASM)组成。调度器是纯调度器,只负责资源分配。资源分配单位抽象为Container。ASM用于应用提交,启动 ApplicationMaster、监控AM运行状态并在失败时重启它。
  • NodeManager(NM):NM是每个节点上的资源和任务管理器,一方面定时向RM汇报本节点的资源使用情况和各个Container的运行状态,另一方面,接受 来自AM的Container启停请求。
  • ApplictionMaster(AM):每个应用程序对应一个AM。 主要负责向RM请求资源、与NM通信来启停任务、 监控所有任务的运行状态,并在任务运行失败时重 新为任务申请资源并重启。
  • Container:是YARN的资源抽象,封装了某节点的多维度资源,例如内存、CPU、网络、磁盘等(目前只支持CPU和内存)。

Yarn工作流程

51647-i35uv2rymab.png

Spark on Yarn

13478-8xrf0dwd90v.png

Yarn容错

ResourceManager的单点故障

  • ResourceManager有备份节点,当主节点出现故障,将切换到从节点继续工作。

NodeManager

  • 失败之后,ResourceManager将失败任务告诉对应的ApplicationMaster
  • ApplicationMaster 决定如何去处理失败任务。

ApplicationMaster

  • 失败后,由ResourceManager负责重启。
  • ApplicationMaster需要处理内部任务的容错问题。
  • ResourceManager会保存已经运行的task,重启后无需重新运行。

Yarn 资源调度模型

YARN采用了双层资源调度模型:在第一层中,ResourceManager中的资源调度器将资源分配给各个 ApplicationMaster;在第二层中,ApplicationMaster再进一步将资源分配给它内部的各个任务. YARN采用的是pull-base通信模型。资源调度器将资源分配给一个应用程序后,它不会立刻push给对应的ApplicationMaster,而是暂时放到一个缓冲区中,等待ApplicationMaster 通过周期性的心跳主动来取。 27854-4k1rbftqltt.png

Yarn资源保证机制

增量资源分配 当应用程序申请的资源暂时无法保证时,是优先为应用程序预留一个节点上的资源直到累计释放的空闲资源满足应用程序的需求。这种资源分配方式,预留资源会造成资源的浪费,降低集群资源利用率。 一次性资源分配 当应用程序申请的资源暂时无法保证时,会放弃当前资源,直到出现一个节点剩余资源一次性满足应用程序需求。这种资源分配方式会出现饿死现象。即应用程序可能永远也等不到满足资源需求的节点出现。 YARN采用增量资源分配机制,尽管这种机制会造成浪费,但不会造成饿死现象。(假设应用程序不会永久占用某个资源,它会在一定时间内释放占用的资源)。

Yarn调度器

在资源调度器中,每个队列可设置一个最小资源量和最大资源量,其中,最小资源量是资源紧缺情况下每个队列需保证的资源量,而最大资源量则是极端情况下队列也不能超过的资源使用量。 资源抢占发生的原因则完全是由于“最小资源量”这一概念。 通常而言,为了提高资源利用率,资源调度器(包括Capacity Scheduler和Fair Scheduler)会将负载较轻的队列的资源暂时分配给负载重的队列 ,仅当负载较轻队列突然收到新提交的应用程序时,调度器才进一步将本属于该队列的资源分配给它。 但由于此时资源可能正被其他队列使用,因此调度器必须等待其他队列释放资源后,才能将这些资源“物归原主”,这通常需要一段不确定的等待时间。 为了防止应用程序等待时间过长,调度器等待一段时间后若发现资源并未得到释放,则进行资源抢占。

Capacity Scheduler主要有以下几个特点。

  • 容量保证: 每个队列可以设定最低资源保证和最高资源使用上限,而提交到该队列的任务则共享该队列的资源。
  • 灵活性: 如果一个队列资源有剩余,而其他队列资源紧张,可以先借用资源给其他队列。而一旦该队列有应用程序提交,则其他队列释放资源后会归还给该队列。
  • 多种租赁: 支持多用户共享集群和多应用程序同时运行。管理员可以为之增加多种约束(某队列最大运行的任务数等)。
  • 安全保证: 每个队列都有严格的ACL列表规定它的访问用户,每个用户可以指定哪些用户可以查看自己应用程序的状态或者控制应用程序(例如杀死应用程序)。管理员可以指定队列管理员和系统管理员。
  • 动态配置更新: 管理员可以根据需要动态修改配置参数。 64174-w7fs5ayeje.png

Hadoop高可用

HA存在的背景:

85656-atrmwfgyad.png 46422-bj5yp25h6o.png

HA的工作原理图:

99970-cktcg9hzeps.png

HDFS HA高可用性 1、active namenode对外提供服务和standby namenode时刻待机准备的 2、保证两个namenode任何时候都是元数据同步的 3、standby namenode同样需要去读取fsimage和edits文件 -》edits变化后的数据文件同样也是需要实时同步的 4、如何同步日志信息 cloudera公司提出一个方案,分布式存储日志文件 编辑日志文件写入,一写写多份,结合之前讲解的ZK的2n+1的概念 策略:写多份,再读取,前提条件节点数目必须是奇数个 active namenode和standby namenode有一块共享存储日志的区域

5、JounralNode日志节点:专门管理编辑日志文件的 QJM全称是Quorum Journal Manager, 由JournalNode(JN)组成,一般是奇数点结点组成。每个JournalNode对外有一个简易的RPC接口,以供NameNode读写EditLog到JN本地磁盘。当写EditLog时,NameNode会同时向所有JournalNode并行写文件,只要有N/2+1结点写成功则认为此次写操作成功,遵循Paxos协议。 -》注意在HA的架构下,就不需要secondarynamenode了 -》JN日志节点是一个轻量级的,所以可以和Hadoop的其他守护线程放在一起 6、datanode需要向standby namenode实时汇报块的状态信息 7、如何帮助客户端判断HDFS正在提供服务的namenode -》通过代理的方式判断 8、在任何时刻下,必须要保证只有一个namenode对外提供服务 -》当两个namenode启动以后,由ZK来完成选举,选举出一个active namenode -》隔离机制

JournalNodes:

29635-nfahlu94y0f.png 主备切换机制:

37401-ap49iyifkww.png

从图中可以看出,整个切换过程是由ZKFC来控制的,具体又可分为HealthMonitor、ZKFailoverController和ActiveStandbyElector三个组件。 58364-tke5u1e145.png

ZKFailoverController: 是HealthMontior和ActiveStandbyElector的母体,执行具体的切换操作 HealthMonitor: 监控NameNode健康状态,若状态异常会触发回调ZKFailoverController进行自动主备切换 ActiveStandbyElector: 通知ZK执行主备选举,若ZK完成变更,会回调ZKFailoverController相应方法进行主备状态切换 在故障切换期间,ZooKeeper主要是发挥什么作用呢,有以下几点:

失败保护:集群中每一个NameNode都会在ZooKeeper维护一个持久的session,机器一旦挂掉,session就会过期,故障迁移就会触发 Active NameNode选择:ZooKeeper有一个选择ActiveNN的机制,一旦现有的ANN宕机,其他NameNode可以向ZooKeeper申请排他成为下一个Active节点 防脑裂: ZK本身是强一致和高可用的,可以用它来保证同一时刻只有一个活动节点 那在哪些场景会触发自动切换呢,从HDFS-2185中归纳了以下几个场景:

ActiveNN JVM奔溃:ANN上HealthMonitor状态上报会有连接超时异常,HealthMonitor会触发状态迁移至SERVICE_NOT_RESPONDING, 然后ANN上的ZKFC会退出选举,SNN上的ZKFC会获得Active Lock, 作相应隔离后成为Active结点。 ActiveNN JVM冻结:这个是JVM没奔溃,但也无法响应,同奔溃一样,会触发自动切换。 ActiveNN 机器宕机:此时ActiveStandbyElector会失去同ZK的心跳,会话超时,SNN上的ZKFC会通知ZK删除ANN的活动锁,作相应隔离后完成主备切换。 ActiveNN 健康状态异常: 此时HealthMonitor会收到一个HealthCheckFailedException,并触发自动切换。 Active ZKFC奔溃:虽然ZKFC是一个独立的进程,但因设计简单也容易出问题,一旦ZKFC进程挂掉,虽然此时NameNode是OK的,但系统也认为需要切换,此时SNN会发一个请求到ANN要求ANN放弃主结点位置,ANN收到请求后,会触发完成自动切换。 ZooKeeper奔溃:如果ZK奔溃了,主备NN上的ZKFC都会感知断连,此时主备NN会进入一个NeutralMode模式,同时不改变主备NN的状态,继续发挥作用,只不过此时,如果ANN也故障了,那集群无法发挥Failover, 也就不可用了,所以对于此种场景,ZK一般是不允许挂掉到多台,至少要有N/2+1台保持服务才算是安全的。 归纳起来主要是两块:元数据同步和主备选举。元数据同步依赖于QJM共享存储,主备选举依赖于ZKFC和Zookeeper。

HA模式下Checkpoint机制分析 在HA模式下checkpoint过程由StandBy NameNode来进行,以下简称为SBNN,Active NameNode简称为ANN。HA模式下的edit log文件会同时写入多个JournalNodes节点的dfs.journalnode.edits.dir路径下,JournalNodes的个数为大于1的奇数,类似于Zookeeper的节点数,当有不超过一半的JournalNodes出现故障时,仍然能保证集群的稳定运行。 SBNN会读取FSImage文件中的内容,并且每隔一段时间就会把ANN写入edit log中的记录读取出来,这样SBNN的NameNode进程中一直保持着hdfs文件系统的最新状况namespace。当达到checkpoint条件的某一个时,就会直接将该信息写入一个新的FSImage文件中,然后通过HTTP传输给ANN。 47851-eebwgrvypg.png 如上图所示,主要由4个步骤:

  1. SBNN检查是否达到checkpoint条件:离上一次checkpoint操作是否已经有一个小时,或者HDFS已经进行了100万次操作。
  2. SBNN检查达到checkpoint条件后,将该namespace以fsimage.ckpt_txid格式保存到SBNN的磁盘上,并且随之生成一个MD5文件。然后将该fsimage.ckpt_txid文件重命名为fsimage_txid。
  3. 然后SBNN通过HTTP联系ANN。
  4. ANN通过HTTP从SBNN获取最新的fsimage_txid文件并保存为fsimage.ckpt_txid,然后也生成一个MD5,将这个MD5与SBNN的MD5文件进行比较,确认ANN已经正确获取到了SBNN最新的fsimage文件。然后将fsimage.ckpt_txid文件重命名为fsimage_txit。   通过上面一系列的操作,SBNN上最新的FSImage文件就成功同步到了ANN上。

———————————————— 版权声明:本文为CSDN博主「weixin_40652340」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/weixin_4065…

Hadoop 数据倾斜

数据倾斜:就是大量的相同key被partition分配到一个分区里,map /reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,

这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完。

解决方案:

1.增加jvm内存,这适用于第一种情况(唯一值非常少,极少数值有非常多的记录值(唯一值少于几千)),这种情况下,往往只能通过硬件的手段来进行调优,增加jvm内存可以显著的提高运行效率。

2.增加reduce的个数,这适用于第二种情况(唯一值比较多,这个字段的某些值有远远多于其他值的记录数,但是它的占比也小于百分之一或千分之一),我们知道,这种情况下,

  最容易造成的结果就是大量相同key被partition到一个分区,从而一个reduce执行了大量的工作,而如果我们增加了reduce的个数,这种情况相对来说会减轻很多,毕竟计算的节点多了,就算工作量还是不均匀的,那也要小很多。

3.自定义分区,这需要用户自己继承partition类,指定分区策略,这种方式效果比较显著。

4.重新设计key,有一种方案是在map阶段时给key加上一个随机数,有了随机数的key就不会被大量的分配到同一节点(小几率),待到reduce后再把随机数去掉即可。

5.使用combinner合并,combinner是在map阶段,reduce之前的一个中间阶段,在这个阶段可以选择性的把大量的相同key数据先进行一个合并,可以看做是local reduce,然后再交给reduce来处理,

  这样做的好处很多,即减轻了map端向reduce端发送的数据量(减轻了网络带宽),也减轻了map端和reduce端中间的shuffle阶段的数据拉取数量(本地化磁盘IO速率),推荐使用这种方法。