HDFS工作原理

HDFS工作原理

1、NameNode 和 DataNode

​ HDFS采用master/slave架构。一个HDFS集群是由一个NameNode和一定数目的DataNode组成。NameNode是一个中心服务器,负责管理文件系统的名字空间(namespace)以及客户端对文件的访问。集群中的DataNode一般是一个节点一个,负责管理它所在节点上的存储。HDFS暴露了文件系统的名字空间,用户能够以文件的形式在上面存储数据。

​ 从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组DataNode上。NameNode执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录。它也负责确定数据块到具体DataNode节点的映射。DataNode负责处理文件系统客户端的读写请求。在Namenode的统一调度下进行数据块的创建、删除和复制。

​ NameNode负责维护文件系统的名字空间,任何对文件系统名字空间或属性的修改都将被NameNode记录下来。应用程序可以设置HDFS保存的文件的副本数目。文件副本的数目称为文件的副本系数,这个信息也是由NameNode保存的。

2、HDFS启动流程

2.1、NameNode加载和持久化

1、NameNode在启动时,会先加载name目录下最近的fsimage文件,将fsimage里保存的元数据加载到内存中,这样内容里就有之前检查点里保存的所有元数据,但是还少了从最近一次检查时间点到关闭系统时的部分数据,也就是edit日志文件里存储的数据。
2、加载edit日志文件,将从最近一次检查点到目前为止的所有日志文件加载到内容里,重演一次客户端的操作,这样内容里就是最新的文件系统的元数据了。
3、进行检查点设置,NameNode汇总之前使用的edit文件,创建一个新的日志文件,然后将所有未合并的edit日志文件和fsimage文件进行合并,并产生一个新的fsimage
4、处于安全模式下,等待DataNode节点的心跳反馈,当收到99.9%的块至少有一个副本后,退出安全模式,开始转为正常状态

2.2、安全模式

​ Namenode启动后会进入一个称为安全模式的特殊状态。处于安全模式的Namenode是不会进行数据块的复制的。Namenode从所有的 Datanode接收心跳信号和块状态报告。块状态报告包括了某个Datanode所有的数据块列表。每个数据块都有一个指定的最小副本数。当Namenode检测确认某个数据块的副本数目达到这个最小值,那么该数据块就会被认为是副本安全(safely replicated)的;在一定百分比(这个参数可配置)的数据块被Namenode检测确认是安全之后(加上一个额外的30秒等待时间),Namenode将退出安全模式状态。接下来它会确定还有哪些数据块的副本没有达到指定数目,并将这些数据块复制到其他Datanode上。

2.3、Secondary NameNode

​ NameNode将对文件系统的改动追加保存到本地文件系统上的一个日志文件(edits)。当一个NameNode启动时,它首先从一个映像文件(fsimage)中读取HDFS的状态,接着应用日志文件中的edits操作。然后它将新的HDFS状态写入(fsimage)中,并使用一个空的edits文件开始正常操作。因为NameNode只有在启动阶段才合并fsimage和edits,所以久而久之日志文件可能会变得非常庞大,特别是对大型的集群。日志文件太大的另一个副作用是下一次NameNode启动会花很长时间。

Secondary NameNode定期合并fsimage和edits日志,将edits日志文件大小控制在一个限度下。因为内存需求和NameNode在一个数量级上,所以通常secondary NameNode和NameNode运行在不同的机器上。Secondary NameNode通过bin/start-dfs.sh在conf/masters中指定的节点上启动。
Secondary NameNode的检查点进程启动,是由两个配置参数控制的:
1、fs.checkpoint.period,指定连续两次检查点的最大时间间隔, 默认值是1小时。
2、fs.checkpoint.size,定义了edits日志文件的最大值,一旦超过这个值会导致强制执行检查点(即使没到检查点的最大时间间隔)。默认值是64MB。

Secondary NameNode保存最新检查点的目录与NameNode的目录结构相同。 所以NameNode可以在需要的时候读取Secondary NameNode上的检查点镜像。
如果NameNode上除了最新的检查点以外,所有的其他的历史镜像和edits文件都丢失了, NameNode可以引入这个最新的检查点。以下操作可以实现这个功能:
1、在配置参数dfs.name.dir指定的位置建立一个空文件夹;
2、把检查点目录的位置赋值给配置参数fs.checkpoint.dir;
3、启动NameNode,并加上-importCheckpoint。

NameNode会从fs.checkpoint.dir目录读取检查点, 并把它保存在dfs.name.dir目录下。 如果dfs.name.dir目录下有合法的镜像文件,NameNode会启动失败。 NameNode会检查fs.checkpoint.dir目录下镜像文件的一致性,但是不会去改动它。

3、HDFS文件上传和下载

3.1、HDFS访问方式

3.1.1、Web接口

​ NameNode和DataNode各自启动了一个内置的Web服务器,显示了集群当前的基本状态和信息。在默认配置下NameNode的首页地址是http://namenode-name:50070/。这个页面列出了集群里的所有DataNode和集群的基本状态。这个Web接口也可以用来浏览整个文件系统(使用NameNode首页上的"Browse the file system"链接)。也可以通过JAVA API的方式访问。

3.1.2、Shell命令

​ Hadoop包括一系列的类shell的命令,可直接和HDFS以及其他Hadoop支持的文件系统进行交互。bin/hadoop fs -help 命令列出所有Hadoop Shell支持的命令。而 bin/hadoop fs -help command-name 命令能显示关于某个命令的详细信息。这些命令支持大多数普通文件系统的操作,比如复制文件、改变文件权限等。它还支持一些HDFS特有的操作,比如改变文件副本数目。

3.2、HDFS文件上传

3.1中的访问方式,浏览器、JAVA程序、执行Shell命令服务器,在访问HDFS文件系统时,都可以视为HDFS文件系统的客户端。客户端可上传文件到HDFS系统,流程如下
1、客户端向NameNode发送文件上传请求
2、NameNode检查是否有权限写入、文件父目录是否存在、当前目录下文件是否存在等,如果检查通过,则进入第3步,否则抛出异常
3、客户端发送文件请求,请求中包含文件大小
4、NameNode收到请求后,根据文件大小和块大小(dfs.blocksize),再结合配置块的副本数(dfs.replication),计算出文件需要占用的块数量,NameNode将文件存在哪些DataNode和DataNode哪个位置的信息,返回给客户端。
注:在大多数情况下,副本系数(dfs.replication)是3,HDFS的存放策略是将一个副本存放在本地机架的节点上,一个副本放在同一机架的另一个节点上,最后一个副本放在不同机架的节点上,可提高效率。
5、客户端收到信息后,将待上传的文件进行切块,每块大小为dfs.blocksize
6、开始上传第一个数据块,构建数据块上传通道pipeline,客户端以packet为单位(dfs.write.packet.size默认为64K),将数据传给DataNode01,DataNode01传给DataNode02,DataNode02传给DataNode03。packet数据存储成功后,DataNode3反馈结果给DataNode2,DataNode2反馈结果给DataNode1(pipeline通道本质是RPC调用,客户端传给DataNode01,DataNode01传给DataNode02、DataNode02传给DataNode03,至此pipeline通道建立完成),客户端每传一个packet都会放入一个应答队列等待应答,待整个块传输完成,清空队列,关闭通道pipeline。
7、后面的数据块,重复第6步,直至文件传输完成(每传输完一个块,都会新建一个通道pipeline)。
8、传输完成一个block块后,DataNode会向NameNode响应,然后NameNode记录下DataNode中的block块信息

3.3、HDFS文件下载

1、客户端向NameNode发送文件下载的请求
2、NameNode检查文件是否存在、权限等,检查通过,通过元数据,将需要下载的文件元数据返回给客户端,元数据包括数据在哪些节点的哪个位置。
3、客户端根据元数据,根据就近原则下载第一个块的数据,然后将下载的第二个块的数据,追加到第一个块中。
4、文件下载完成,客户端向NameNode响应。

你可能感兴趣的:(hadoop,hadoop,hdfs)