找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

330

积分

0

好友

44

主题
发表于 6 天前 | 查看: 12| 回复: 0

一、HDFS简介

HDFS是大数据生态系统中最为核心的组件之一。当数据集规模超过单台物理计算机的存储容量时,就需要将其分区并存储到多台计算机上。管理网络中跨多台计算机存储的文件系统称为分布式文件系统。该系统构建于网络之上,必然引入网络编程的复杂性,因此分布式文件系统比普通磁盘文件系统更为复杂。例如,使文件系统能够容忍节点故障且不丢失任何数据就是极具挑战性的任务。

HDFS在大规模分布式服务器集群上,对数据分片后进行并行读写及冗余存储。由于HDFS可部署在大型服务器集群上,集群中所有服务器的磁盘都供HDFS使用,因此整个HDFS的存储空间可达PB级容量。

HDFS的主要特性包括:

  • 超大文件存储:适用于存储大数据文件
  • 流式数据访问:一次写入多次读取是最佳访问模式
  • 商用硬件支持:庞大集群中部分节点故障时仍能持续运行,用户无感知
  • 低延迟访问限制:不适合低时间延迟数据访问,可考虑HBase替代
  • 小文件存储劣势:大量小文件会占用NameNode过多内存资源
  • 写入限制:仅支持单个写入者,写操作总是追加至文件末尾

1.HDFS原理

(1)数据形式

①数据形式简介
  • Block:HDFS中文件采用分块方式存储,每个block放置在不同DataNode上。每个block标识为三元组(block id, numBytes, generationStamp),其中block id具有唯一性,由NameNode分配
  • Packet:DFSClient与DataNode通信过程中,数据发送和接收都以packet为基础单位
  • Chunk:在数据通信过程中,每个packet包含多个chunk,每个chunk会进行checksum计算生成校验字节

文件被拆分为多个block持久化存储(block大小由配置参数决定),数据通信时一个block被拆分为多个packet,一个packet包含多个chunk。

②Packet结构与定义

Packet分为实际数据包和心跳包两类。一个Packet数据包由Header和Data两部分组成:

HDFS核心原理深度解析:分布式文件系统架构与读写机制详解 - 图片 - 1

Header部分包含Packet的概要属性信息:

HDFS核心原理深度解析:分布式文件系统架构与读写机制详解 - 图片 - 2

  • Data部分包含4字节校验和(Checksum)与Chunk部分,Chunk部分最大为512字节
  • 构建Packet时,字节流数据首先写入缓冲区,从偏移量25位置开始写Chunk的Checksum部分,从偏移量533位置开始写Chunk Data部分
  • 当写入文件的最后一个Block的最后一个Packet时,如果Packet大小未达最大长度,会检查并压缩数据间隙后再发送

(2)HDFS块的概念

①传统分布式文件系统的缺点

考虑四个文件:0.5TB的file1、1.2TB的file2、50GB的file3、100GB的file4;7台服务器,每台服务器10个1TB硬盘:

图片

传统存储方式将文件存储在相同服务器上(大文件需要切分),使用映射关系记录存储位置,存在明显缺点:

  • 负载不均衡:文件大小不一致导致节点磁盘利用率差异
  • 网络瓶颈:大文件存储于单一节点,并行处理时产生网络瓶颈
②HDFS的块——独立存储单元

HDFS引入块(Block)概念,块大小固定且可自定义。块是HDFS系统中的最小存储单位,Hadoop 2.0中默认大小为128MB(1.x版本为64MB)。文件被拆分为多个块,每个块作为独立单元存储在不同DataNode上:

图片

HDFS确保一个块存储在一个数据节点上,如果文件最后一个块未达128M,不会占据整个块空间。

③分布式文件系统块抽象的优势
  • 文件可大于任意磁盘容量,块可分布存储在不同磁盘
  • 简化存储子系统设计,便于存储管理
  • 提供数据容错能力,通过块复制确保数据可靠性
④HDFS块大小设计原理
  • 最小化寻址开销:机械硬盘寻址时间占总I/O开销主要部分,大块设计减少总寻址时间
  • 节省内存使用:块元数据约150字节,大块减少内存占用
  • 平衡原则:块过大降低MapReduce任务效率,过小增加寻址时间
⑤块相关参数设置

块大小在hdfs-default.xml中配置,可在hdfs-site.xml中重置:

<property>
    <name>dfs.blocksize</name>
    <value>134217728</value>
    <description>默认块大小,以字节为单位</description>
</property>
<property>
    <name>dfs.namenode.fs-limits.min-block-size</name>
    <value>1048576</value>
    <description>最小块大小</description>
</property>
<property>
    <name>dfs.namenode.fs-limits.max-blocks-per-file</name>
    <value>1048576</value>
    <description>每个文件最大块数</description>
</property>
⑥HDFS块存储位置

在hdfs-site.xml中配置:

<!-- 确定DFS数据节点块存储位置 -->
<property>
    <name>dfs.datanode.data.dir</name>
    <value>file://${hadoop.tmp.dir}/dfs/data</value>
</property>
⑦块大小设置规则
  • 寻址时间约10ms,最佳传输时间1s(寻址时间占1%)
  • 磁盘传输速度100MB/s时,最佳块大小:100MB/s * 1s = 100MB
  • 实际设置:128MB(100MB/s)、256MB(200MB/s)、512MB(400MB/s)

2.HDFS的优缺点

(1)HDFS优点

  • 高容错性:数据自动多副本存储,副本丢失自动恢复
  • 大数据集支持:GB/TB/PB级数据,千万级文件数量
  • 数据一致性:一次写入多次读取,保证数据安全
  • 低成本构建:可部署在廉价机器上
  • 高可移植性:跨平台兼容
  • 高效处理:节点间数据动态平衡,处理速度快
  • 高可靠性:位级数据存储处理

(2)HDFS缺点

  • 低延迟访问不足:适合高吞吐而非毫秒级延迟应用
  • 小文件存储劣势:大量小文件消耗大量寻址时间和NameNode内存
  • 写入限制:不支持并发写入和随机修改

3.HDFS架构

图片

(1)架构组成

HDFS采用master/slaves主从结构,包含四个核心组件:

  • HDFS Client:系统使用者,通过API操作文件;与NameNode交互获取元数据;与DataNode交互进行数据读写
  • NameNode:主节点,系统唯一管理者,负责命名空间管理、数据块映射、副本策略和客户端请求处理
  • DataNode:数据存储节点,存储实际数据,执行数据块读写,向NameNode汇报存储信息
  • Secondary NameNode:辅助NameNode工作,定期合并fsimage和edits

(2)架构原则

  • 元数据与数据分离
  • 主从架构设计
  • 一次写入多次读取
  • 移动计算优于移动数据

(3)Hadoop 2.x HA高可用

①高可用需求

NameNode单点故障会导致整个HDFS系统不可用,传统恢复需要30分钟以上冷启动时间。

②NameNode高可用架构

图片

高可用集群使用两台独立机器作为NameNode,一台Active一台Standby:

  • ZKFailoverController:独立进程,控制主备切换
  • 共享存储系统(Quorum Journal Node):保持Active和Standby节点同步
  • DataNode:同时向主备NameNode上报数据块位置信息
③主备切换原理

图片

主备切换由三个组件协同实现:

  • HealthMonitor:检测NameNode健康状态
  • ActiveStandbyElector:完成自动主备选举
  • ZKFailoverController:管理NameNode状态切换

(4)Hadoop 2.x Federation联邦机制

联邦机制解决单NameNode扩展性和性能瓶颈:

  • 多个NameNode共享集群存储资源
  • 每个DataNode为所有存储池提供存储
  • 客户端挂载表实现透明访问
  • 设计优势:向前兼容、命名空间与块存储分离

二、HDFS读写原理

1.数据读取

(1)原理解析

图片

  • Client向NameNode发送RPC请求获取文件block位置
  • NameNode检查权限后返回部分或全部block列表及对应DataNode地址
  • DataNode地址按集群拓扑排序:网络距离近的优先,心跳超时的靠后
  • Client选择排序靠前的DataNode读取block,本地DataNode优先(短路读取)
  • 通过Socket Stream并行读取block数据
  • 读取完成后继续获取下一批block列表
  • 所有block合并为完整文件
(2)设计重点

客户端直接连接DataNode检索数据,数据流分散在集群中,支持大量并发客户端,NameNode仅负责元数据响应。

(3)块损坏处理

客户端读取后进行checksum验证,发现不一致时通知NameNode,从备用DataNode重新读取,确保数据完整性。

2.数据写入

(1)原理解析

图片

  • Client发起上传请求,NameNode检查文件是否存在
  • Client将文件分块(如64MB分为block1和block2)
  • NameNode返回可用DataNode列表
  • Client与DataNode建立pipeline,流式写入数据
  • 数据按64k packet划分,管道式传输
  • 写入完成后DataNode向NameNode和Client发送确认

图片

(2)DataNode故障处理
  • 关闭管道,将确认队列数据包回滚至数据队列前端
  • 为新数据块制定新标识并通知NameNode
  • 从管道移除故障节点,基于正常节点重建管道
  • NameNode在新节点创建副本确保数据冗余

3.一致模型

HDFS一致模型描述文件读写的数据可见性:

  • 新建文件立即可见,但写入内容不保证立即可见
  • 写入数据超过一个块后,已完成块对新reader可见
  • 调用hflush()方法强制刷新缓存,确保数据到达所有DataNode
  • hsync()方法确保数据写入磁盘,提供更强一致性保证



上一篇:Python事件驱动架构实战:消息代理与观察者模式详解
下一篇:Jenkins与Kubernetes微服务CI/CD实战:Maven打包到滚动发布完整脚本
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区(YunPan.Plus) ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-7 04:51 , Processed in 0.133508 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 CloudStack.

快速回复 返回顶部 返回列表