Hadoop学习笔记(二)hdfs工作机制
一.HDFS的重要特性
1. HDFS是一个文件系统,用于存储和管理文件,通过统一的命名空间(类似于本地文件系统的目录树)。它是分布式的,服务器集群中各个节点都有自己的角色和职责。
2. HDFS中的文件在物理上是分块存储(block),块的大小可以通过配置参数( dfs.blocksize)来规定,默认大小在hadoop2.x版本中是128M,之前的版本中是64M。
3. HDFS文件系统会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data
4. 目录结构及文件分块位置信息(元数据)的管理由namenode节点承担,namenode是HDFS集群主节点,负责维护整个hdfs文件系统的目录树,以及每一个路径(文件)所对应的数据块信息(blockid及所在的datanode服务器)
5. 文件的各个block的存储管理由datanode节点承担,datanode是HDFS集群从节点,每一个block都可以在多个datanode上存储多个副本(副本数量也可以通过参数设置dfs.replication,默认是3)
6. Datanode会定期向Namenode汇报自身所保存的文件block信息,而namenode则会负责保持文件的副本数量,HDFS的内部工作机制对客户端保持透明,客户端请求访问HDFS都是通过向namenode申请来进行。
7. 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。这称为“机架感知”策略。(datanode的剩余空间大小与节点的距离决定)
4)客户端在开始传输数据块之前会把数据缓存在本地,当缓存大小超过了一个数据块的大小,客户端就会从namenode获取要上传的datanode列表。之后会在客户端和第一个datanode建立连接开始流式的传输数据,这个datanode会一小部分一小部分(4K)的接收数据然后写入本地仓库,同时会把这些数据传输到第二个datanode,第二个datanode也同样一小部分一小部分的接收数据并写入本地仓库,同时传输给第三个datanode,依次类推。这样逐级调用和返回之后,待这个数据块传输完成客户端后告诉namenode数据块传输完成,这时候namenode才会更新元数据信息记录操作日志。
5)第一个数据块传输完成后会使用同样的方式传输下面的数据块直到整个文件上传完成。
细节:
请求和应答是使用RPC的方式,客户端通过ClientProtocol与namenode通信,namenode和datanode之间使用DatanodeProtocol交互。在设计上,namenode不会主动发起RPC,而是响应来自客户端或 datanode 的RPC请求。客户端和datanode之间是使用socket进行数据传输,和namenode之间的交互采用nio封装的RPC。
三.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返回结果给客户端。
当用户或应用程序删除某个文件时,这个文件并没有立刻从HDFS中删除。实际上,HDFS会将这个文件重命名转移到/trash目录。只要文件还在/trash目录中,该文件就可以被迅速地恢复。文件在/trash中保存的时间是可配置的,当超过这个时间时,Namenode就会将该文件从名字空间中删除。删除文件会使得该文件相关的数据块被释放。
五.NameNode元数据管理原理分析
- 概述
首先明确namenode的职责:响应客户端请求、管理元数据。
namenode对元数据有三种存储方式:
- 内存元数据(NameSystem)
- 磁盘元数据镜像文件
- 数据操作日志文件(可通过日志运算出元数据)
- 对三种存储机制的进一步解释
内存元数据就是当前namenode正在使用的元数据,是存储在内存中的。
磁盘元数据镜像文件是内存元数据的镜像,保存在namenode工作目录中,它是一个准元数据,作用是在namenode宕机时能够快速较准确的恢复元数据。称为fsimage。
数据操作日志文件是用来记录元数据操作的,在每次改动元数据时都会追加日志记录,如果有完整的日志就可以还原完整的元数据。主要作用是用来完善fsimage,减少fsimage和内存元数据的差距。称为editslog。
-
checkpoint机制分析
1).客户端更新或者查询元数据请求,-------->更新namenode内存中的元数据(元数据在内存中是一个对象)
2).更新后记录操作日志文件(edits),每次更新后都是追加文件。
3).为什么要有日志文件? -------> 更新元数据后不能直接更新fsimage,fsimage是一个文件,要修改一个文件的内容先找到文件对应的内容,然后在修改文件,效率非常不好。所以引入日志文件(edits),每次元数据更新后,操作日志都是追加到eidits文件(这样不影响性能),通过追加的操作的日志可以恢复元数据。
4). 如果namenode死了,数据是否能恢复?
当namenode死了后,内存中的元数据就没有了,要恢复,可以将edits的日志还原加载到内存中,如果namenode运行很久了,edits非常多,如果重启namenode,会加载很久,所以要定期将edits与fsimage合并。当namenode死了重新加载fsimage会很快的,最坏情况下,可以吧secondnamenode的fsimage拷入到namenode中,重启namenode进行数据恢复
5).为什么不直接在namenode上合并,要在secondnamenode上做合并?
合并首先是down 下镜像(fsimage),然后将edits还原,最后把还原的数据和下载下来的fsimage合并。操作非常耗性能,占内存,所以借助secondnamenode
6). secondnamenode触发条件?
定时与安装edits中的记录数量, -
namenode向secondarynamenode发送RPC请求,请求合并editslog到fsimage。
-
secondarynamenode收到请求后从namenode上读取(通过http服务)editslog(多个,滚动日志文件)和fsimage文件。
-
secondarynamenode会根据拿到的editslog合并到fsimage。形成最新的fsimage文件。(中间有很多步骤,把文件加载到内存,还原成元数据结构,合并,再生成文件,新生成的文件名为fsimage.checkpoint)。
-
secondarynamenode通过http服务把fsimage.checkpoint文件上传到namenode,并且通过RPC调用把文件改名为fsimage。
-
namenode和secondary namenode的工作目录存储结构完全相同,所以,当namenode故障退出需要重新恢复时,可以从secondary namenode的工作目录中将fsimage拷贝到namenode的工作目录,以恢复namenode的元数据。
问题:
Namenode服务器的磁盘故障导致namenode宕机,如何挽救集群及数据?
六 namenode的工作原理####
-
datanode工作职责:
存储管理用户的文件块数据
定期向namenode汇报自身所持有的block信息(通过心跳信息上报)<property> <name>dfs.blockreport.intervalMsec</name> <value>3600000</value> <description>Determines block reporting interval in milliseconds.</description> </property>
-
datanode断线判断时限参数
datanode进程死亡或者网络故障造成datanode无法与namenode通信,namenode不会立即把该节点判定为死亡,要经过一段时间,这段时间暂称作超时时长。HDFS默认的超时时长为10分钟+30秒。 -
问题
集群容量不够,怎么扩容?
如果有一些datanode宕机,该怎么办?
rk,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d0emht,size_16,color_FFFFFF,t_70)