面试强化宝典之hdfs篇_第1页
面试强化宝典之hdfs篇_第2页
面试强化宝典之hdfs篇_第3页
面试强化宝典之hdfs篇_第4页
面试强化宝典之hdfs篇_第5页
已阅读5页,还剩15页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、HDFS 之文件读过程HDFS 是一个分布式文件系统,在 HDFS 上写文件的过程与平时使用的单机文件系统非常不同,从宏观上来看,在 HDFS 文件系统上创建并写一个文件,流程如下图所示:具体过程描述如下:Cnt 调用 DistributedFileSystem 对象的 create 方法,创建一个文件输出流(FSDataOutputStream)对象。通过 DistributedFileSystem 对象与 Hadoop 集群的 NameNode 进行一次 RPC调用,在 HDFS 的 Namespace 中创建一个文件条目(Entry),该条目没有任何的 Block通过 FSDataOut

2、putStream 对象,向 DataNode 写入数据,数据首先被写入 FSDataOutputStream 对象的 Buffer 中,然后数据被分割成一个个 Packet 数据包以 Packet 最小,基于 Socket 连接发送到按特定算法选择的HDFS 集群中一组 DataNode(正常是 3 个,可能大于等于 1)中的一个节点上,在这组 DataNode 组成的 Pipeline 上依次传输 Packet这组 DataNode 组成的 Pipeline 反方向上,发送 ack,最终由 Pipeline中第一个 DataNode 节点将 Pipeline ack 发送给 Cnt完成向文

3、件写入数据,Cnt 在文件输出流(FSDataOutputStream)对象上调用 close 方法,关闭流调用 DistributedFileSystem 对象的 complete 方法,通知 NameNode文件写入成功HDFS 写流程另一种描述客户端要向 HDFS 写数据,首先要跟 namenode 通信以确认可以写文件并获得接收文件 block 的 datanode,然后,客户端按顺序将文件逐个 block 传递给相应 datanode,并由接收到 block 的 datanode 负责向其他 datanode如图:block 的副本写详细步骤:1、根 namenode 通信请求上传文

4、件,namenode 检查目标文件是否已存在,父目录是否存在2、namenode 返回是否可以上传3、cnt 会先对文件进行切分,比如一个 blok 块 128m,文件有 300m就会被切分成 3 个块,一个 128M、一个 128M、一个 44M 请求第一个 block 该传输到哪些 datanode 服务器上4、namenode 返回 datanode 的服务器5、cnt 请求一台 datanode 上传数据(本质上是一个 RPC 调用,建立 pipeline),第一个 datanode 收到请求会继续调用第二个 datanode,然后第二个调用第三个 datanode,将整个 pipel

5、ine 建立完成,逐级返回客户端6、cnt 开始往 A 上传第一个 block(先从磁盘数据放到一个本地内存缓存),以 packet 为(一个 packet 为 64kb),当然在写入的时候 datanode 会进行数据校验,它并不是通过一个 packet 进行一次校验而是以 ck 为进行校验(512byte),第一台 datanode 收到一个 packet 就会传给第二台,第二台传给第三台;第一台每传一个packet 会放入一个应答队列等待应答7、当一个 block 传输完成之后,cblock 的服务器。nt 再次请求 namenode 上传第二个HDFS 读流程描述客户端将要的文件路径发

6、送给 namenode,namenode 获取文件的元信息(主要是 block 的存放位置信息)返回给客户端,客户端根据返回的信息找到相应 datanode 逐个获取文件的block 并在客户端本地进行数据追加合并从而获得整个文件如图读详细步骤:1、跟 namenode 通信查询元数据(block 所在的 datanode 节点),找到文件块所在的 datanode 服务器2、挑选一台 datanode(就近原则,然后随机)服务器,请求建立 socket流3、datanode 开始发送数据(从磁盘里面读取数据放入流,以 packet为单位来做校验)4、客户端以 packet 为单位接收,先在本

7、地缓存,然后写入目标文件,后面的 block 块就相当于是 append 到前面的 block 块最后合成最终需要的文件。HDFS 客户端删除文件用 java 的 api 删除 hdfs 的 文件 Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(conf);Path p = new Path(hdfs:/127.0.0.1:9000/demo021.txt); fs.delete(p,true);fs.close();/ 释放资源System.out.println(删除成功);namenode

8、删除文件1、客户端通过 ClientProtocol.delete(String, boolean)方法来删除文件,最终实现是 NameNodeRpcServer.delete(String, boolean)方法.2、调用了 FSNamesystem 的 delete 来删除namesystem 中的相应的文件.,这里总共分为两步。第一步,从 namespace 删除相应的文件信息并收集删除的文件的数据块.第 二 步 , 将 收 集 到 的 待 删 除 的 数 据 块 加 到 blockmanage 的 invalidateBlocks 中,等待 datanode 下次心跳的时候生成删除命令

9、发给 datanode,然后删除具体的数据块。boolean delete(String src, boolean recursive, boolean logRetryCache)throws IOException waitForLoadingFSImage(); BlocksMapUpdateInfo toRemovedBlocks = null; writeLock();boolean ret = false; try /检查是否有写的权限 checkOperation(OperationCategory.WRITE);/检查是否处于安全模式 checkNameNodeSafeMode

10、(Cannot delete + src);/从命名空间删除相应的文件 toRemovedBlocks = FSDirDeleteOp.delete(this, src, recursive, logRetryCache); ret = toRemovedBlocks != null; catch (AccessControlException e) logAuditEvent(false, delete, src);throw e; finally writeUnlock();/将删除操作记录到 editlog 中getEditLog().logSync();if (toRemovedBlo

11、cks != null) /删除数据块操作 removeBlocks(toRemovedBlocks);blockslogAuditEvent(true, delete, src); return ret;从命名空间删除文件/Incrementaldeletionof通过工具类 FSDirDeleteOp 的静态方法 delete 来删除文件,并且收集该文件的要删除的 block.最 终 通 过 FSDirDeleteOp 类 的 unprotectedDelete(FSDirectory, INodesInPath, BlocksMapUpdateInfo, List, long)方法来执行

12、删除操作.之所以叫做 unprotectedDelet,是因为这个时候删除只是将该文件从命名空间中删除,并没有真正的写入 editlog.删除过程分为以下几个步骤:1.检查文件是否存在2,修改快照记录从 namespace 中移除文件,也就是 FSDirectory 记录的 INodeDirectory类型的 rootDir 中删除;设置父文件夹的最后修改时间更新删除的记录数收集要删除的 blockHDFS HA 方案 hadoop 1.x 与hadoop2.x 对比Hadoop1.xSecondary NameNode:它不是 HA,它只是阶段性的合并 edits 和 fsimage,以缩短

13、集群启动的时间。当 NN 失效的时候,Secondary NN并无法立刻提供服务,Secondary NN 甚至无法保证数据完整性:如果 NN 数据丢失的话,在上一次合并后的文件系统的改动会丢失 Backup NameNode (HADOOP-4539):它在内存中复制了 NN 的当前状态,算是 Warm Standby,可也就仅限于此,并没有 failover 等。它同样是阶段性的做 checkpoint,也无法保证数据完整性手动把 name.dir 指向 NFS(Network File System),这是安全的 ColdStandby,可以保证元数据不丢失,但集群的恢复则完全靠手动ha

14、doop2.X ha:hadoop2.x 之后,Clouera 提出了 QJM/Qurom Journal Manager,这是一个基于 Paxos 算法实现的 HDFS HA 方案,它给出了一种较好的解决思路和方案,示意图如下:基本原理就是用 2N+1 台 JNEditLog,每次写数据操作有大多数(=N+1)返回成功时即认为该次写成功,数据不会丢失了。当然这个算法所能的是最多有 N 台机器挂掉,如果多于 N 台挂掉,这个算法就失效了。这个原理是基于 Paxos 算法在 HA 架构里面SecondaryNameNode 这个冷备角色已经不存在了,为了保持 standby NN 时时的与主 A

15、ctive NN 的元数据保持一致,他们之间交互通过一系列守护的轻量级进程 JournalNode任何修改操作在 Active NN 上执行时,JN 进程同时也会 修改 log 到至少半数以上的 JN 中,这时 Standby NN 监测到 JN 里面的同步 log 发生变化了会 JN 里面的修改 log,然后同步到自己的的目录镜像树里面,如下图:当发生故障时,Active 的NN挂掉后,Standby NN会在它成为Active NN前,所有的 JN 里面的修改日志,这样就能高可靠的保证与挂掉的 NN 的目录镜像树一致,然后无缝的它的职责,来自客户端请求,从而达到一个高可用的目的QJM 方式

16、来实现 HA 的主要优势:1.不需要配置额外的高共享,降低了复杂度和成本2.消除 spof3.系统鲁棒性(Robust:健壮)的程度是可配置4.JN 不会因为其中一台的延迟而影响整体的延迟,而且也不会因为 JN 的数量增多而影响性能(因为 NN 向 JN 发送日志是并行的)hadoop2.x ha详述:datanode 的 fencing:确保只有一个 NN 能命令 DN。HDFS-1972 中详细描述了 DN 如何实现 fencing1.1.号每个 NN 改变状态的时候,向 DN 发送自己的状态和一个序列2.DN 在运行过程中此序列号,当 failover 时,新的 NN 在返回 DN 心跳

17、时会返回自己的 active 状态和一个更大的序列号。DN 接收到这个返回则认为该 NN 为新的 active3.如果这时原来的 active NN 恢复,返回给 DN 的心跳信息包含active 状态和原来的序列号,这时 DN 就会这个 NN令客户端 fencing:确保只有一个 NN 能响应客户端请求,让standby nn 的客户端直接失败。在 RPC 层封装了一层,通过FailovroxyProvider 以重试的方式连接 NN。通过若干次连接一个NN 失败后尝试连接新的 NN,对客户端的影响是重试的时候增加一定的延迟。客户端可以设置重试此时和时间ZKFailoverControlle

18、r 主要职责:Hadoop 提供了 ZKFailoverController 角色,部署在每个 NameNode的节点上,作为一个 deamon 进程, 简称 zkfc,示例图如下:FailoverController 主要包括三个组件:HealthMonitor:NameNode 是否处于 unavailable 或 unhealthy状态。当前通过 RPC 调用 NN 相应的方法完成ActiveStandbyElector: 管理和自己在 ZK 中的状态ZKFailoverController 它订阅 HealthMonitor 和 ActiveStandbyElector的事件,并管理

19、NameNode 的状态健康监测:周期性的向它的 NN 发送健康探测命令,从而来确定某个 NameNode 是否处于健康状态,如果机器宕机,心跳失败,那么 zkfc 就会标记它处于一个不健康的状态会话管理:如果 NN 是健康的,zkfc 就会在 zookeeper 中保持一个打开的会话,如果 NameNode 同时还是 Active 状态的,那么 zkfc 还会在 Zookeeper 中占有一个类型为短暂类型的 znode,当这个 NN 挂掉时,这个 znode 将会被删除,然后备用的 NN,将会得到这把锁,升级为主 NN,同时标记状态为 Active当宕机的NN 新启动时,它会再次 zook

20、eper,发现已经有znode锁了,便会自动变为 Standby 状态,如此往复循环,保证高可靠,需要注意,目前仅仅支持最多配置 2 个 NNmaster:如上所述,通过在 zookeeper 中维持一个短暂类型的 znode,来实现抢占式的锁机制,从而判断那个 NameNode 为 Active状态hadoop2.x Federation:单 Active NN 的架构使得 HDFS 在集群扩展性和性能上都有潜在的问题,当集群大到一定程度后,NN 进程使用的内存可能会达到上百 G, NN 成为了性能的瓶颈多个 NN 共用一个集群里的资源,每个 NN 都可以单独对外提供服务每个 NN 都会定义

21、一个池,有单独的 id,每个 DN 都为所有池提供DN 会按照池 id 向其对应的 NN 汇报块信息,同时,DN 会向所有 NN 汇报本地可用资源情况常用的估算公式为 1G 对应 1 百万个块,按缺省块大小计算的话,大概是 64T (这个估算比例是有比较大的富裕的,其实,即使是每个文件只有一个块,所有元数据信息也不会有 1KB/block)为了解决这个问题,Hadoop 2.x 提供了 HDFS Federation, 示意图如下:HDFS 缓存管理HDFS 提供了一个高效的缓存加速机制Centralized Cache Management,可以将一些经常被的文件(例如 Hive 中的 fa

22、ct 表) pin 到内存中。这些 DataNode 的缓存也是由 NameNode 所管理的(NameNode 所管理的 cache 依然是以 block 形式,而 DataNode 也会定期向 NameNode 汇报缓存状态),而客户端可以高效得 被缓存的数据块;为了能锁定内存,该实现依赖于 JNI 使用 libhadoop.so,所以 IX 资源限制也要进行相应的设置(ulimit -l),并确保下面如果需要在客户端方便的若干个 NN 上的资源,可以使用客户端挂载表,把不同的目录到不同的 NN,但 NN 上必须存在相应的目录的参数被设置。A. 参数设置HDFS FEDERATION 的原

23、理结构HDFS Federation 意味着在集群中将会有多个 namenode/namespace,这样的方式好处呢?dfs.datanode.max.locked.memory该参数用于确定每个 DataNode 给缓存使用的最大内存量。设置这个参数和 ulimit -l 时,需要注意内存空间还需要一些内存用于做其他事情,比如,DataNode 和应用程序 JVM 堆内存、以及操作系统的页缓存,以及计算框架的任务。所以不要使用太高的内存百分比。多 namespace 的方式可以直接减轻单一 NameNode 的压力.HDFS Federation 是解决 NameNode 单点问题的水平横

24、向扩展方案.这时候在 DataNode 上就不仅仅一个 Block Pool 下的数据了,而是多个(大家可以在DataNode 的datadir 所在目录里面查看BP-.xx打头的目录).它们还是在同一个集群内的.HDFSFederation 原理结构图如下:可以拿这种图与上一小节的图做对比,可以得出这样一个结论:一个典型的例子就是上面提到的 NameNode 内存过高问题,完全可以将上面部分大的文件目录移到另外一个 NameNode 上做管理.更重要的一点在于,这些 NameNode 是共享集群中所有的 DataNode 的,HDFS 的 viewFs 是 namespace 完全独立(私人化)的 Federation 方案,可以这么说,viewFs 是 Federation 的一

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论