【Hadoop】详解HDFS
Hadoop 分布式文件系统(HDFS)被设计成适合运行在通用硬件上的分布式文件系统,它是一个高度容错性的系统,适合部署在廉价的机器上,能够提供高吞吐量的数据访问,非常适合大规模数据集上的应用。为了做到可靠性,HDFS创建了多份数据块的副本,并将它们放置在服务器群的计算节点中,MapReduce 可以在它们所在的节点上处理这些数据。
1. HDFS 的设计目标
- 存储大规模数据:HDFS 可以存储并管理 PB 级甚至 EB 级的数据。
- 高容错性:数据自动保存多个副本,副本丢失自动恢复
- 高吞吐量:适合流式数据访问,支持高并发读写,一次写入,可多次读取,确保数据的一致性。
- 低成本:可以在普通硬件上运行,降低存储成本。
2. HDFS 的设计思想和体系架构
HDFS采用主从架构。一个HDFS集群是由一个NameNode和一定数目的DataNodes 组成。其中 NameNode 是一个中心服务器,负责文件系统的名字空间(namespace)管理以及客户端对文件的访问。集群中的DataNode一般是一个节点一个,负责管理它所在节点上的存储。
HDFS设计思想
从内部看,一个文件其实被分成一个或多个数据块,这些块存储在一组DataNode(server)之上。NameNode执行文件系统的名字空间操作,比如打开、关闭、重命名文件或目录,同时它也负责确定数据块到具体DataNode节点的映射。DataNode负责处理文件系统客户端的读写请求,在NameNode的统一调度下进行数据块的创建、删除和复制。
HDFS框架结构
HDFS使用Java语言开发,因此任何支持Java的机器都可以部署NameNode或DataNode。 由于采用了可移植性极强的Java语言,这就使得HDFS可以部署到几乎所有类型的机器上。
三.NameNode
1.NameNode的作用
- 元数据管理:Namenode 是HDFS的元数据节点,负责文件系统的名字空间(Namespace)管理以及客户端对文件的访问。
- 文件元数据操作:NameNode 负责文件元数据的操作,如创建、删除、重命名文件或目录。
- 数据块管理:NameNode 决定数据块的副本存放在哪些 DataNode 上。读取文件时,NameNode 会尽量让用户先读取最近的副本(通过网络拓扑距离来衡量),以降低带宽消耗和读取时延。
- 心跳机制:NameNode 周期性地从每个 DataNode 接收心跳信号和块状态报告。心跳信号表示 DataNode 工作正常,块状态报告包含 DataNode 上所有数据块的信息列表。
2. NameNode 的目录结构
NameNode 的元数据存储在本地文件系统的以下目录中:${dfs.name.dir}/current/
包含以下文件:
- VERSION:是Java properties 文件,保存 HDFS 的版本信息
- edits:修改日志(Edit Log),记录对文件系统元数据的修改。存储在本地文件系统中。
- fsimage:命名空间镜像文件,保存整个文件系统的命名空间包括数据块映射信息,文件属性等等。存储在本地文件系统中。
- fstime:记录最后一次检查点(checkpoint)的时间。
3. NameNode 的启动与检查点
NameNode 在内存中保存着整个文件系统的命名空间和文件数据块映射的映像,这个关键的元数据结构设计得非常紧凑,因而一个有4G内存的NameNode就足以支撑巨大量的文件和目录。
(1)启动过程:
- NameNode 从硬盘读取 FsImage 和 Edit Log。
- 将 Edit Log 中的事务应用到内存中的 FsImage。
- 将更新后的 FsImage 保存到本地磁盘,并删除旧的 Edit Log。
(2)检查点(Checkpoint):
- 定期将内存中的元数据保存到 FsImage,并清理 Edit Log。
- 由 Secondary NameNode 辅助完成。
4. Secondary NameNode 的作用
(1)辅助 NameNode:
- Secondary NameNode 不是 NameNode 的备用节点,而是辅助 NameNode 完成检查点。
- 主要功能是定期合并 FsImage 和 Edit Log,防止 Edit Log 过大。
(2)检查点过程:
- Secondary NameNode 通知 NameNode 生成新的 Edit Log。
- 从 NameNode 获取 FsImage 和旧的 Edit Log。
- 将 FsImage 加载到内存,并应用 Edit Log 中的事务,生成新的 FsImage。
- 将新的 FsImage 传回 NameNode。
- NameNode 更新 FsImage 和 Edit Log,并记录检查点时间。
Secondary NameNode并不是NameNode出现问题时候的备用节点,它和NameNode负责不同的事情。其主要功能就是周期性地将NameNode的命名空间镜像文件和修改日志合并,以防日志文件过大。合并过后的命名空间镜像文件也在Secondary NameNode保存了一份,以防止在 NameNode失败的时候,可以安全恢复。Secondary NameNode 通常在一个独立的机器上运行,它的内存要求和主 NameNode 是一样的。Secondary NameNode在配置后通过 start-dfs.sh 启动。
四.DateNode
1.DataNode的作用
- 数据存储:DataNode是文件系统中真正存储数据的地方,一个数据块在DataNode磁盘存储时,会存储数据块本身,以及元数据包括数据块的长度、块数据的校验和、以及时间戳。
- 数据块管理:DataNode是HDFS文件系统的工作节点,DataNode会按照客户端或者是NameNode的调度来存储和检索数据,并定期向NameNode发送它所存储的数据块列表。
- 与 NameNode 通信:DataNode启动后向NameNode注册,注册成功后,周期性每小时向NameNode上报所有的块信息,心跳频率每3秒一次,心跳返回结果带有 NameNode 给该 DataNode 的命令,如复制块数据到另一台机器,或删除某个数据块等等。
- 节点状态:如果 NameNode超过10分钟没有收到某个DataNode的心跳,则认为该节点不可用。集群在运行中可以安全地加入或剔除状态异常的机器。
2. DataNode 的目录结构
DataNode 的数据存储目录结构如下:${dfs.data.dir}/current/
包含以下内容:
- VERSION:存储 DataNode 的版本信息。
blk_<id>
:存储数据块的二进制数据。blk_<id>.meta
:存储数据块的元数据,包括校验和、长度和时间戳。
五 .HDFS数据块
1.数据块大小:默认情况下,HDFS 的数据块大小为 128MB(Hadoop 2.x 及以上版本)或 64MB(Hadoop 1.x 版本)。用户可以根据需要调整块大小。
2.数据块分布:HDFS 通过数据块副本机制实现高容错性。默认情况下,每个数据块会被复制到 3 个不同的 DataNode 上。
而在传统的块存储介质中,块是读写的最小数据单位(扇区),传统文件系统是基于存储块进行操作 的,为了节省文件分配表空间,一般会对物理存储块进行整合,通常为 4KB 或 64KB。
那为什么HDFS 的块远远大于传统文件系统的块?
- 块大小较小,文件会被分割成更多的数据块,导致元数据量大幅增加,占用大量 NameNode 内存。较大的块大小可以减少元数据量,降低 NameNode 的内存压力。NameNode 的元数据管理更加高效。
- 减少寻址开销:在传统文件系统中,较小的块大小会导致更多的磁盘寻址操作,增加 I/O 开销。HDFS 的较大块大小可以减少寻址次数,提高数据访问效率。
- HDFS 设计用于处理大规模数据,适合流式数据访问(即顺序读取大文件)。较大的块大小可以减少数据块的切换频率,提高数据读取的吞吐量。