深入理解一个技术的工作机制是灵活运用和快速解决问题的根本方法,也是唯一途径。对于HDFS来说除了要明白它的应用场景和用法以及通用分布式架构之外更重要的是理解关键步骤的原理和实现细节。在看这篇博文之前需要对HDFS以及分布式系统有一些了解。请参考这篇博客。本篇博文首先对HDFS的重要特性和使用场景做一个简要说明,之后对HDFS的数据读写、元数据管理以及NameNode、SecondaryNamenode的工作机制进行深入分析。过程中也会对一些配置参数做一个说明。 一.HDFS的重要特性First. HDFS是一个文件系统,用于存储和管理文件,通过统一的命名空间(类似于本地文件系统的目录树)。是分布式的,服务器集群中各个节点都有自己的角色和职责。 Then. 1.HDFS中的文件在物理上是分块存储(block),块的大小可以通过配置参数( dfs.blocksize)来规定,默认大小在hadoop2.x版本中是128M,之前的版本中是64M。 2.HDFS文件系统会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data 3.目录结构及文件分块位置信息(元数据)的管理由namenode节点承担,namenode是HDFS集群主节点,负责维护整个hdfs文件系统的目录树,以及每一个路径(文件)所对应的数据块信息(blockid及所在的datanode服务器) 4.文件的各个block的存储管理由datanode节点承担,datanode是HDFS集群从节点,每一个block都可以在多个datanode上存储多个副本(副本数量也可以通过参数设置dfs.replication,默认是3) 5.Datanode会定期向Namenode汇报自身所保存的文件block信息,而namenode则会负责保持文件的副本数量,HDFS的内部工作机制对客户端保持透明,客户端请求访问HDFS都是通过向namenode申请来进行。 6.HDFS是设计成适应一次写入,多次读出的场景,且不支持文件的修改。需要频繁的RPC交互,写入性能不好。 二.HDFS写数据分析1.概述 客户端要向HDFS写数据,首先要跟namenode通信以确认可以写文件并获得接收文件block的datanode,然后客户端按顺序将文件逐个block传递给相应datanode,并由接收到block的datanode负责向其他datanode复制block的副本。 2.写数据步骤详解
(图片来自网络,仅供参考) 1)客户端向namenode发送上传文件请求,namenode对要上传目录和文件进行检查,判断是否可以上传,并向客户端返回检查结果。 2)客户端得到上传文件的允许后读取客户端配置,如果没有指定配置则会读取默认配置(例如副本数和块大小默认为3和128M,副本是由客户端决定的)。向namenode请求上传一个数据块。 3)namenode会根据客户端的配置来查询datanode信息,如果使用默认配置,那么最终结果会返回同一个机架的两个datanode和另一个机架的datanode。这称为“机架感知”策略。
4)客户端在开始传输数据块之前会把数据缓存在本地,当缓存大小超过了一个数据块的大小,客户端就会从namenode获取要上传的datanode列表。之后会在客户端和第一个datanode建立连接开始流式的传输数据,这个datanode会一小部分一小部分(4K)的接收数据然后写入本地仓库,同时会把这些数据传输到第二个datanode,第二个datanode也同样一小部分一小部分的接收数据并写入本地仓库,同时传输给第三个datanode,依次类推。这样逐级调用和返回之后,待这个数据块传输完成客户端后告诉namenode数据块传输完成,这时候namenode才会更新元数据信息记录操作日志。 5)第一个数据块传输完成后会使用同样的方式传输下面的数据块直到整个文件上传完成。 细节: a.请求和应答是使用RPC的方式,客户端通过ClientProtocol与namenode通信,namenode和datanode之间使用DatanodeProtocol交互。在设计上,namenode不会主动发起RPC,而是响应来自客户端或 datanode 的RPC请求。客户端和datanode之间是使用socket进行数据传输,和namenode之间的交互采用nio封装的RPC。 b.HDFS有自己的序列化协议。 c.在数据块传输成功后但客户端没有告诉namenode之前如果namenode宕机那么这个数据块就会丢失。 d.在流式复制时,逐级传输和响应采用响应队列来等待传输结果。队列响应完成后返回给客户端。 c.在流式复制时如果有一台或两台(不是全部)没有复制成功,不影响最后结果,只不过datanode会定期向namenode汇报自身信息。如果发现异常namenode会指挥datanode删除残余数据和完善副本。如果副本数量少于某个最小值就会进入安全模式。
三.HDFS读数据分析1.概述 客户端将要读取的文件路径发送给namenode,namenode获取文件的元信息(主要是block的存放位置信息)返回给客户端,客户端根据返回的信息找到相应datanode逐个获取文件的block并在客户端本地进行数据追加合并从而获得整个文件。 2.读数据步骤详解
(图片来源于网络,仅供参考) 1)客户端向namenode发起RPC调用,请求读取文件数据。 2)namenode检查文件是否存在,如果存在则获取文件的元信息(blockid以及对应的datanode列表)。 3)客户端收到元信息后选取一个网络距离最近的datanode,依次请求读取每个数据块。客户端首先要校检文件是否损坏,如果损坏,客户端会选取另外的datanode请求。 4)datanode与客户端简历socket连接,传输对应的数据块,客户端收到数据缓存到本地,之后写入文件。 5)依次传输剩下的数据块,直到整个文件合并完成。
四.HDFS删除数据分析HDFS删除数据比较流程相对简单,只列出详细步骤: 1)客户端向namenode发起RPC调用,请求删除文件。namenode检查合法性。 2)namenode查询文件相关元信息,向存储文件数据块的datanode发出删除请求。 3)datanode删除相关数据块。返回结果。 4)namenode返回结果给客户端。
五.NameNode元数据管理原理分析1.概述 首先明确namenode的职责:响应客户端请求、管理元数据。 namenode对元数据有三种存储方式: 内存元数据(NameSystem) 磁盘元数据镜像文件 数据操作日志文件(可通过日志运算出元数据) 细节:HDFS不适合存储小文件的原因,每个文件都会产生元信息,当小文件多了之后元信息也就多了,对namenode会造成压力。 2.对三种存储机制的进一步解释 内存元数据就是当前namenode正在使用的元数据,是存储在内存中的。 磁盘元数据镜像文件是内存元数据的镜像,保存在namenode工作目录中,它是一个准元数据,作用是在namenode宕机时能够快速较准确的恢复元数据。称为fsimage。 数据操作日志文件是用来记录元数据操作的,在每次改动元数据时都会追加日志记录,如果有完整的日志就可以还原完整的元数据。主要作用是用来完善fsimage,减少fsimage和内存元数据的差距。称为editslog。 3.checkpoint机制分析 因为namenode本身的任务就非常重要,为了不再给namenode压力,日志合并到fsimage就引入了另一个角色secondarynamenode。secondarynamenode负责定期把editslog合并到fsimage,“定期”是namenode向secondarynamenode发送RPC请求的,是按时间或者日志记录条数为“间隔”的,这样即不会浪费合并操作又不会造成fsimage和内存元数据有很大的差距。因为元数据的改变频率是不固定的。 每隔一段时间,会由secondary namenode将namenode上积累的所有edits和一个最新的fsimage下载到本地,并加载到内存进行merge(这个过程称为checkpoint)。
(图片来源于网络,仅供参考) 1)namenode向secondarynamenode发送RPC请求,请求合并editslog到fsimage。 2)secondarynamenode收到请求后从namenode上读取(通过http服务)editslog(多个,滚动日志文件)和fsimage文件。 3)secondarynamenode会根据拿到的editslog合并到fsimage。形成最新的fsimage文件。(中间有很多步骤,把文件加载到内存,还原成元数据结构,合并,再生成文件,新生成的文件名为fsimage.checkpoint)。 4)secondarynamenode通过http服务把fsimage.checkpoint文件上传到namenode,并且通过RPC调用把文件改名为fsimage。 namenode和secondary namenode的工作目录存储结构完全相同,所以,当namenode故障退出需要重新恢复时,可以从secondary namenode的工作目录中将fsimage拷贝到namenode的工作目录,以恢复namenode的元数据。 关于checkpoint操作的配置:
editslog和fsimage文件存储在$dfs.namenode.name.dir/current目录下,这个目录可以在hdfs-site.xml中配置的。这个目录下的文件结构如下:
包括edits日志文件(滚动的多个文件),有一个是edits_inprogress_*是当前正在写的日志。fsimage文件以及md5校检文件。seen_txid是记录当前滚动序号,代表seen_txid之前的日志都已经合并完成。
六.总结深入理解了以上介绍的工作机制就可以尝试运用他们解决工作和学习中遇到的问题了,只要真正理解了核心原理,所有问题都可以自己找到答案。就是要不断的学习、实践、总结,再学习、再实践、再总结。这样才能扎扎实实做的出色。共勉。 接下来会有一篇HDFS常见问题的总结。 参考资料:http://hadoop./docs/stable2/hadoop-project-dist/hadoop-hdfs/HdfsUserGuide.html |
|
来自: 春和秋荣 > 《分布式文件系统HDFS》