共计 3094 个字符,预计需要花费 8 分钟才能阅读完成。
这篇文章给大家介绍怎么理解 Hadoop 中的 HDFS,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
一、HDFS 的基本概念 1.1、数据块(block)
HDFS(Hadoop Distributed File System)默认的最基本的存储单位是 64M 的数据块。
和普通文件系统相同的是,HDFS 中的文件是被分成 64M 一块的数据块存储的。
不同于普通文件系统的是,HDFS 中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间。
1.2、元数据节点 (Namenode) 和数据节点(datanode)
元数据节点用来管理文件系统的命名空间
其将所有的文件和文件夹的元数据保存在一个文件系统树中。
这些信息也会在硬盘上保存成以下文件:命名空间镜像 (namespace image) 及修改日志(edit log)
其还保存了一个文件包括哪些数据块,分布在哪些数据节点上。然而这些信息并不存储在硬盘上,而是在系统启动的时候从数据节点收集而成的。
数据节点是文件系统中真正存储数据的地方。
客户端 (client) 或者元数据信息 (namenode) 可以向数据节点请求写入或者读出数据块。
其周期性的向元数据节点回报其存储的数据块信息。
从元数据节点(secondary namenode)
从元数据节点并不是元数据节点出现问题时候的备用节点,它和元数据节点负责不同的事情。
其主要功能就是周期性将元数据节点的命名空间镜像文件和修改日志合并,以防日志文件过大。这点在下面会相信叙述。
合并过后的命名空间镜像文件也在从元数据节点保存了一份,以防元数据节点失败的时候,可以恢复。
1.2.1、元数据节点文件夹结构
VERSION 文件是 java properties 文件,保存了 HDFS 的版本号。
layoutVersion 是一个负整数,保存了 HDFS 的持续化在硬盘上的数据结构的格式版本号。
namespaceID 是文件系统的唯一标识符,是在文件系统初次格式化时生成的。
cTime 此处为 0
storageType 表示此文件夹中保存的是元数据节点的数据结构。
namespaceID=1232737062
cTime=0
storageType=NAME_NODE
layoutVersion=-18
1.2.2、文件系统命名空间映像文件及修改日志
当文件系统客户端 (client) 进行写操作时,首先把它记录在修改日志中(edit log)
元数据节点在内存中保存了文件系统的元数据信息。在记录了修改日志后,元数据节点则修改内存中的数据结构。
每次的写操作成功之前,修改日志都会同步 (sync) 到文件系统。
fsimage 文件,也即命名空间映像文件,是内存中的元数据在硬盘上的 checkpoint,它是一种序列化的格式,并不能够在硬盘上直接修改。
同数据的机制相似,当元数据节点失败时,则最新 checkpoint 的元数据信息从 fsimage 加载到内存中,然后逐一重新执行修改日志中的操作。
从元数据节点就是用来帮助元数据节点将内存中的元数据信息 checkpoint 到硬盘上的
checkpoint 的过程如下:
从元数据节点通知元数据节点生成新的日志文件,以后的日志都写到新的日志文件中。
从元数据节点用 http get 从元数据节点获得 fsimage 文件及旧的日志文件。
从元数据节点将 fsimage 文件加载到内存中,并执行日志文件中的操作,然后生成新的 fsimage 文件。
从元数据节点奖新的 fsimage 文件用 http post 传回元数据节点
元数据节点可以将旧的 fsimage 文件及旧的日志文件,换为新的 fsimage 文件和新的日志文件(第一步生成的),然后更新 fstime 文件,写入此次 checkpoint 的时间。
这样元数据节点中的 fsimage 文件保存了最新的 checkpoint 的元数据信息,日志文件也重新开始,不会变的很大了。
1.2.3、从元数据节点的目录结构
1.2.4、数据节点的目录结构
数据节点的 VERSION 文件格式如下:
namespaceID=1232737062
storageID=DS-1640411682-127.0.1.1-50010-1254997319480
cTime=0
storageType=DATA_NODE
layoutVersion=-18
blk_ id 保存的是 HDFS 的数据块,其中保存了具体的二进制数据。
blk_ id .meta 保存的是数据块的属性信息:版本信息,类型信息,和 checksum
当一个目录中的数据块到达一定数量的时候,则创建子文件夹来保存数据块及数据块属性信息。
二、数据流(data flow)2.1、读文件的过程
客户端 (client) 用 FileSystem 的 open()函数打开文件
DistributedFileSystem 用 RPC 调用元数据节点,得到文件的数据块信息。
对于每一个数据块,元数据节点返回保存数据块的数据节点的地址。
DistributedFileSystem 返回 FSDataInputStream 给客户端,用来读取数据。
客户端调用 stream 的 read()函数开始读取数据。
DFSInputStream 连接保存此文件第一个数据块的最近的数据节点。
Data 从数据节点读到客户端(client)
当此数据块读取完毕时,DFSInputStream 关闭和此数据节点的连接,然后连接此文件下一个数据块的最近的数据节点。
当客户端读取完毕数据的时候,调用 FSDataInputStream 的 close 函数。
在读取数据的过程中,如果客户端在与数据节点通信出现错误,则尝试连接包含此数据块的下一个数据节点。
失败的数据节点将被记录,以后不再连接。
2.2、写文件的过程
客户端调用 create()来创建文件
DistributedFileSystem 用 RPC 调用元数据节点,在文件系统的命名空间中创建一个新的文件。
元数据节点首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件。
DistributedFileSystem 返回 DFSOutputStream,客户端用于写数据。
客户端开始写入数据,DFSOutputStream 将数据分成块,写入 data queue。
Data queue 由 Data Streamer 读取,并通知元数据节点分配数据节点,用来存储数据块(每块默认复制 3 块)。分配的数据节点放在一个 pipeline 里。
Data Streamer 将数据块写入 pipeline 中的第一个数据节点。第一个数据节点将数据块发送给第二个数据节点。第二个数据节点将数据发送给第三个数据节点。
DFSOutputStream 为发出去的数据块保存了 ack queue,等待 pipeline 中的数据节点告知数据已经写入成功。
如果数据节点在写入的过程中失败:
关闭 pipeline,将 ack queue 中的数据块放入 data queue 的开始。
当前的数据块在已经写入的数据节点中被元数据节点赋予新的标示,则错误节点重启后能够察觉其数据块是过时的,会被删除。
失败的数据节点从 pipeline 中移除,另外的数据块则写入 pipeline 中的另外两个数据节点。
元数据节点则被通知此数据块是复制块数不足,将来会再创建第三份备份。
当客户端结束写入数据,则调用 stream 的 close 函数。此操作将所有的数据块写入 pipeline 中的数据节点,并等待 ack queue 返回成功。最后通知元数据节点写入完毕。
关于怎么理解 Hadoop 中的 HDFS 就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。