1.分布式文件系统

1.1计算机集群结构

  • 分布式文件系统把文件分布存储到多个计算机节点上,成千上万的计算机节点构成计算机集群
  • 与之前使用多个处理器和专用高级硬件的并行化处理装置不同的是,目前的分布式文件系统所采用的计算机集群,都是由普通硬件构成的,这就大大降低了硬件上的开销。
    在这里插入图片描述

1.2分布式文件系统的结构

分布式文件系统在物理结构上是由计算机集群中的多个节点构成的,这些节点分为两类,一类叫“主节点”(Master Node)或者也被称为“名称结点”(NameNode),另一类叫“从节点”(Slave Node)或者也被称为“数据节点”(DataNode)。
在这里插入图片描述

1.2.1分布式文件系统读文件

  1. 客户端请求主节点:客户端向主节点发送文件读取请求,获取文件元数据(如文件块位置信息)。
  2. 主节点返回元数据:主节点根据文件元数据,查询数据节点中文件块的存储位置,返回给客户端。
  3. 客户端直接读取数据:客户端根据主节点返回的位置,直接连接对应数据节点,读取所需文件块数据。

1.2.2分布式文件系统写文件

  1. 客户端请求主节点:客户端向主节点发送写文件请求,主节点规划数据存储策略(如副本分布),选择目标数据节点。
  2. 客户端写入数据:客户端将数据写入主节点指定的第一个数据节点(通常优先选择本地机架节点)。
  3. 数据节点复制副本:第一个数据节点接收数据后,按策略将数据块复制到其他数据节点(跨机架或本机架),完成多副本存储,确保数据可靠性。

2.HDFS简介

HDFS 即 Hadoop 分布式文件系统(Hadoop Distributed File System),是 Hadoop 生态系统中的核心组成部分。

特性 详细说明 局限性 原因/影响
兼容廉价硬件设备 设计时以硬件故障为常态,支持普通服务器集群运行,通过冗余机制保障数据完整性。 不适合低延迟应用 采用高吞吐数据读取方式导致较高延迟(如流式访问机制)。
支持流数据读写 为批量处理优化,放宽POSIX要求,采用顺序流式读写提升吞吐率。 1. 无法高效存储/处理大量小文件
2. 读取大量小文件速度慢
1. 元数据占用大量名称节点内存
2. MapReduce任务过多增加开销
3. 跨节点频繁跳转降低访问速度。
支持超大规模数据集 单文件可达GB/TB级,数百节点集群支持千万级大文件存储。 不支持多用户写入及任意修改文件 仅允许单用户追加写入,文件一旦关闭不可修改。
采用简单文件模型 “一次写入、多次读取”,文件创建关闭后无法再写入,只能读取。
强大的跨平台兼容性 用Java语言开发,支持Java虚拟机,具有很好的跨平台兼容性。

3.HDFS相关概念

3.1块

HDFS默认一个块64MB,一个文件被分成多个块,以块作为存储单位。块的大小远远大于普通文件系统,可以最小化寻址开销。HDFS采用抽象的块概念可以带来以下几个明显的好处:

  • 支持大规模文件存储:文件以块为单位进行存储,一个大规模文件可以被分拆成若干个文件块,不同的文件块可以被分发到不同的节点上,因此,一个文件的大小不会受到单个节点的存储容量的限制,可以远远大于网络中任意节点的存储容量
  • 简化系统设计:首先,大大简化了存储管理,因为文件块大小是固定的,这样就可以很容易计算出一个节点可以存储多少文件块;其次,方便了元数据的管理,元数据不需要和文件块一起存储,可以由其他系统负责管理元数据
  • 适合数据备份:每个文件块都可以冗余存储到多个节点上,大大提高了系统的容错性和可用性。

3.2名称结点和数据结点

组件 功能 存储位置 映射关系
NameNode 存储元数据 内存 保存文件、block、datanode之间的映射关系
DataNode 存储文件内容 磁盘 维护了block id到datanode本地文件的映射关系

3.2.1FsImage文件和EditLog文件

文件类型 描述 用途 特点
FsImage 文件 存储文件系统元数据的快照,包括文件目录树、文件属性以及块与数据节点的映射关系。 1. 系统启动时加载
2. 恢复文件系统状态
1. 定期生成
2. 结构紧凑
3. 只读文件,避免误修改。
EditLog 文件 记录文件系统元数据的变更操作(如创建、删除、修改文件等),用于增量更新元数据。 1. 记录元数据变更
2. 支持数据恢复
1. 顺序写入
2. 支持追加操作
3. 与 FsImage 结合使用,确保元数据一致性。
  1. FsImageEditLog 是分布式文件系统(如 HDFS)中 NameNode 的核心文件,用于维护和管理文件系统的元数据。
  2. FsImage 是元数据的完整快照,而 EditLog 记录增量变更,两者结合可以高效恢复文件系统状态。
  3. 在系统启动时,NameNode 会加载 FsImage 并应用 EditLog 中的变更,以确保元数据的最新性和一致性。

3.2.2第二名称结点

HDFS(Hadoop 分布式文件系统) 中,第二名称节点(Secondary NameNode) 是一个重要的辅助组件,其主要职责是帮助 NameNode 减轻负载并优化元数据管理。以下是第二名称节点的详细介绍:

第二名称节点的功能
  1. 定期合并 FsImage 和 EditLog
    • NameNode 使用 FsImage(文件系统元数据快照)和 EditLog(元数据变更日志)来管理文件系统的元数据。
    • 第二名称节点定期从 NameNode 获取 FsImage 和 EditLog,将它们合并成一个新的 FsImage,并将合并后的 FsImage 返回给 NameNode。
    • 这样可以减少 EditLog 的大小,避免 NameNode 启动时加载过大的日志文件。
  2. 辅助 NameNode 恢复
    • 如果 NameNode 发生故障,第二名称节点保存的 FsImage 可以作为备用元数据,帮助 NameNode 快速恢复文件系统状态。
    • 注意:第二名称节点并不是 NameNode 的热备节点,不能直接接管 NameNode 的工作。
  3. 优化元数据管理
    • 通过定期合并 FsImage 和 EditLog,第二名称节点减少了 NameNode 的内存和磁盘负载,提升了系统的稳定性和性能。
第二名称节点的局限性
  1. 非高可用性组件
    • 第二名称节点并不能提供 NameNode 的高可用性(HA)。如果需要高可用性,需要使用 HA NameNodeZooKeeper 等机制。
  2. 依赖定期合并
    • 第二名称节点的合并操作是周期性的,如果 NameNode 在两次合并之间发生故障,可能会丢失部分元数据变更。
二名称节点的工作流程
  1. 第二名称节点定期从 NameNode 下载 FsImageEditLog
  2. 在本地合并 FsImage 和 EditLog,生成一个新的 FsImage。
  3. 将合并后的 FsImage 上传到 NameNode,替换旧的 FsImage。
  4. NameNode 使用新的 FsImage 继续管理文件系统。

4.HDFS体系结构

4.1 HDFS 体系结构概述

HDFS(Hadoop 分布式文件系统)是一个分布式、高容错的文件系统,专为处理大规模数据集而设计。其核心架构包括以下组件:

  1. NameNode
    • 负责管理文件系统的元数据(如文件目录树、文件属性、块与数据节点的映射关系)。
    • 是 HDFS 的主节点,存储元数据在内存中,同时持久化到磁盘(FsImage 和 EditLog)。
  2. DataNode
    • 负责存储实际的数据块,并定期向 NameNode 报告块的状态。
    • 是 HDFS 的从节点,分布在集群中的多个物理机器上。
  3. Secondary NameNode
    • 辅助 NameNode 定期合并 FsImage 和 EditLog,减轻 NameNode 的负载。
    • 并非 NameNode 的热备节点,不提供高可用性。

HDFS 的设计目标是支持高吞吐量的数据访问,适合处理大规模数据集,但不适合低延迟的实时应用。

4.2 HDFS 命名空间管理

HDFS 的命名空间管理由 NameNode 负责,主要包括以下内容:

  1. 文件目录树
    • HDFS 采用类似传统文件系统的层次化目录结构,支持文件和目录的创建、删除和重命名操作。
  2. 元数据存储
    • 元数据存储在 NameNode 的内存中,包括文件与块的映射关系、文件属性(如权限、所有者、大小等)。
    • 元数据通过 FsImage(文件系统快照)和 EditLog(变更日志)持久化到磁盘。
  3. 块管理
    • 文件被分割成固定大小的块(默认 128MB 或 256MB),每个块存储在多个 DataNode 上以实现冗余。
    • NameNode 维护块与 DataNode 的映射关系,确保数据的高可用性和负载均衡。

4.3 通信协议

HDFS 的通信协议主要包括以下部分:

  1. NameNode 与 DataNode 的通信
    • DataNode 定期向 NameNode 发送心跳信号和块报告,以确认其状态和块信息。
    • NameNode 根据块报告和数据块的位置信息进行负载均衡和副本管理。
  2. 客户端与 NameNode 的通信
    • 客户端通过 NameNode 获取文件的元数据(如块的位置信息)。
    • 客户端与 NameNode 的通信通常使用 RPC(远程过程调用)协议。
  3. 客户端与 DataNode 的通信
    • 客户端直接与 DataNode 通信,读取或写入数据块。
    • 数据传输使用基于 TCP 的协议,支持高吞吐量的数据访问。

4.4 客户端

HDFS 客户端是用户与 HDFS 交互的接口,主要功能包括:

  1. 文件操作
    • 支持文件的创建、读取、写入、删除和重命名等操作。
    • 文件操作通过 NameNode 获取元数据,并通过 DataNode 进行实际的数据读写。
  2. 数据访问优化
    • 客户端支持流式读取和写入,适合大规模数据集的批量处理。
    • 通过缓存和预读机制优化数据访问性能。
  3. API 支持
    • 提供多种编程语言的 API(如 Java、Python),方便开发者集成到应用程序中。
    • 支持命令行工具(如 hdfs dfs),便于用户直接操作文件系统。

4.5 HDFS体系结构的局限性

尽管 HDFS 在大规模数据处理中表现出色,但其体系结构也存在一些局限性:

  1. 不适合低延迟应用
    • HDFS 的设计目标是高吞吐量,而非低延迟,因此不适合实时数据处理或交互式查询。
  2. 单点故障问题
    • NameNode 是 HDFS 的单点故障源,如果 NameNode 宕机,整个文件系统将不可用。
    • 虽然可以通过 HA NameNode 或 Secondary NameNode 缓解,但仍需额外配置。
  3. 小文件处理效率低
    • HDFS 适合存储大文件,但对大量小文件的处理效率较低,因为小文件会占用大量 NameNode 的内存。
  4. 不支持多用户写入
    • HDFS 采用“一次写入、多次读取”模型,文件一旦关闭便不可修改,仅支持单用户追加写入。
  5. 跨平台兼容性有限
    • 虽然 HDFS 基于 Java 开发,但在某些非 Java 环境中可能需要额外的配置和支持。

5.HDFS存储原理

5.1 冗余数据保存

HDFS通过多副本机制实现数据冗余存储,核心目标是为容错性和高可用性提供保障。具体策略如下:

  1. 默认三副本机制:每个数据块默认保存3个副本,分布在不同数据节点(DataNode)上。若副本数量不足(如节点故障),HDFS会自动触发副本补充,确保冗余因子(默认3)的满足。
  2. 纠删码(EC)优化:HDFS 3.x引入纠删码技术,通过计算奇偶校验单元减少存储空间占用(例如RS算法),在保持容错能力的同时降低冗余成本。
  3. 冗余优势
    加速数据传输:多个副本支持并行读取,提升访问效率。
    错误检测与恢复:通过校验和(Checksum)验证数据完整性,发现错误后切换至健康副本。
    保证数据的可靠性

5.2数据存储策略

5.2.1数据存储

HDFS通过机架感知(Rack Awareness)副本分布规则优化数据存储位置,平衡性能与容错:

  1. 副本放置规则
    第一个副本:若客户端在集群内,优先存储于发起请求的节点;若为外部客户端,则选择磁盘和CPU负载较低的节点。
    第二个副本:放置在与第一个副本不同机架的节点,避免单机架故障导致数据丢失。
    第三个副本:与第二个副本同一机架的其他节点,减少跨机架通信开销。
    更多副本:随机分配节点,确保负载均衡。
  2. 异构存储支持:根据数据热度选择存储介质(如SSD存储热数据,机械硬盘存储冷数据),优化读写性能。

5.2.2数据读取

HDFS提供了一个API可以确定一个数据节点所属的机架ID,客户端也可以调用API获取自已所属的机架ID。
当客户端读取数据时,从名称节点获得数据块不同副本的存放位置列表,列表中包含了副本所在的数据节点,可以调用API来确定客户端和这些数据节点所属的机架ID,当发现某个数据块副本对应的机架ID和客户端对应的机架ID相同时,就优先选择该副本读取数据,如果没有发现,就随机选择一个副本读取数据。

HDFS具有较高的容错性,可以兼容廉价的硬件,它把硬件出错看作一种常态,而不是异常,并设计了相应的机制检测数据错误和进行自动恢复,主要包括以下几种情形:名称节点出错、数据节点出错和数据出错

5.3 数据错误与恢复

HDFS将硬件错误视为常态,设计了多层检测和恢复机制:

  1. 名称节点(NameNode)故障
    • 依赖FsImage(元数据镜像)EditLog(操作日志)恢复元数据,通过SecondaryNameNode定期合并日志与镜像,减少恢复时间。
    • 高可用(HA)模式下,通过Standby NameNode实现故障自动切换。
  2. 数据节点(DataNode)故障
    心跳检测:DataNode每3秒向NameNode发送心跳,超时(默认10分钟)则标记为宕机,触发副本复制。
    副本重平衡:定期检查节点负载,调整副本分布以均衡集群存储。
  3. 数据块损坏
    客户端校验:读取时验证校验和,若发现错误自动切换至其他副本,并向NameNode报告损坏块以触发修复。
    回收站与快照:误删除文件可暂存回收站(.Trash目录),快照功能支持数据回溯到历史版本。

6.HDFS数据读写过程

6.1读数据的过程

HDFS读数据流程以就近访问并行读取为核心,具体步骤如下:

  1. 客户端发起请求:客户端通过DistributedFileSystem模块向NameNode发送RPC请求,获取文件的元数据(如数据块位置列表)。
  2. NameNode返回元数据:NameNode返回文件的所有数据块信息,并按照网络拓扑距离排序(优先返回与客户端同机架或物理距离近的DataNode地址)。
  3. 建立数据流管道:客户端根据返回的DataNode列表,选择最优节点(如最近的节点)建立连接,并通过FSDataInputStream并行读取数据块。
    短路读取优化:若客户端与DataNode在同一物理节点,直接从本地磁盘读取,跳过网络传输。
  4. 数据校验与错误处理
    • 每读取一个数据块后,客户端会验证校验和(Checksum)。若发现数据损坏,自动切换到其他副本节点重新读取。
    • NameNode会记录损坏的块信息,后续触发副本修复。
  5. 合并数据块:客户端按顺序将多个数据块合并为完整文件。

6.2写数据的过程

HDFS写数据流程通过数据分块流水线传输实现高效写入,步骤如下:

  1. 客户端请求创建文件:客户端调用create()方法向NameNode申请创建文件,NameNode检查权限和文件是否存在后生成元数据。
  2. 数据分块与管道建立
    • 客户端将文件按默认128MB切分为块,并请求NameNode分配可写入的DataNode列表(默认3副本)。
    • NameNode基于机架感知策略选择节点(如第一个副本在客户端本地,第二个在不同机架,第三个在同机架其他节点)。
  3. 流水线传输数据包
    • 客户端与DataNode建立传输管道(例如Client → DN1 → DN2 → DN3),数据以**Packet(默认64KB)**为单位依次传输。
    • 每个DataNode接收数据后立即转发至下一节点,形成流水线并行写入。
  4. 确认机制与容错
    • DataNode每接收一个Packet后向上游返回ACK确认信号。若某个节点写入失败,管道会重新选择可用节点补传数据。
    • 所有副本写入成功后,客户端通知NameNode提交元数据更新。
  5. 租约与一致性保障:NameNode为写入文件的客户端分配租约(Lease),防止多客户端并发写冲突。

7.HDFS编程实践

7.1 命令行操作(CLI)

通过HDFS命令行工具可直接管理文件,常用命令包括:

# 上传本地文件到HDFS  
hdfs dfs -put /local/file /hdfs/path      # 引用  

# 下载HDFS文件到本地  
hdfs dfs -get /hdfs/file /local/path      # 引用  

# 查看文件列表  
hdfs dfs -ls /hdfs/directory  

# 删除文件  
hdfs dfs -rm /hdfs/file  

7.2 Java API编程

HDFS提供Java API支持开发分布式应用,核心类为FileSystemFSDataInputStream/FSDataOutputStream

// 1. 读取文件示例  
Configuration conf = new Configuration();  
FileSystem fs = FileSystem.get(conf);  
FSDataInputStream in = fs.open(new Path("/hdfs/file"));  
byte[] buffer = new byte[1024];  
while (in.read(buffer) > 0) {  
    // 处理数据  
}  
in.close();  

// 2. 写入文件示例  
FSDataOutputStream out = fs.create(new Path("/hdfs/newfile"));  
out.write("Hello HDFS".getBytes());  
out.close();  

关键配置
• 设置副本数:conf.set("dfs.replication", "2");
• 自定义块大小:conf.set("dfs.blocksize", "256M");

7.3 高级功能实践

  1. 数据压缩:使用CompressionCodec类对写入数据压缩,减少存储和传输开销。
  2. 快照管理:通过SnapshotDiff接口创建文件系统快照,支持数据版本回溯。
  3. 权限控制:结合Kerberos实现HDFS文件访问权限管理。

Logo

更多推荐