这是我参与「第四届青训营 」笔记创作活动的第3天
HDFS原理与应用
HDFS基本介绍
hadoop技术体系
文件系统
1.Window单机文件系统
2.Linux单机文件系统
3.分布式文件系统
特点:
- 大容量:更多的机器,更多的存储介质
- 高可靠:多个副本提高容错能力
- 低成本:不需要高端硬件来扩容
4.分布式存储系统
HDFS功能特性
- 分布式:受GFS启发,用Java实现的开源系统,没有实现完整的POSIX文件系统语义
- 容错:自动处理,规避多种错误场景,例如常见的网络错误、机器宕机等
- 高可用:一主多备模式实现元数据高可用,数据多副本实现用户数据的高可用
- 高吞吐:Client直接从DataNode读取用户数据,服务端支持海量client并发读写
- 可扩展:支持联邦集群模式,DataNode数量可达10w级别
- 廉价:只需要通用硬件,不需要定制昂贵的硬件设备
架构原理
HDFS组件
HDFS存储概述:
- HDFS中的文件在物理上是分块存储(block),块的大小通过配置参数决定
- HDFS文件系统会给客户端提供一个统一的抽象目录树,客户端通过路径来访问文件
HDFS组件:
- Client:客户端,用户通过客户端访问HDFS,通过命令行进行交互
- NameNode:NameNode是HDFS集群主节点,负责维护整个hdfs文件系统的目录树,以及每一个路径(文件)所对应的block块信息,用于管理分布式系统的文件。
- DateNode:DateNode是HDFS集群从节点,每一个block都可以在多个DateNode上存储多个副本。
Client写流程
客户端要向HDFS写数据,首先要跟namenode通信以确认可以写文件并获得接收文件block的datanode,然后,客户端与DataNode建立连接,按顺序将文件逐个block传递给相应datanode,并由接收到block的datanode负责向其他datanode复制block的副本,叫做pipeline写。
Client读流程
客户端将要读取的文件路径发送给namenode,namenode获取文件的元信息(主要是block的存放位置信息)返回给客户端,客户端根据返回的信息与相应datanode建立连接并逐个获取文件的block并在客户端本地进行数据追加合并从而获得整个文件。
源数据节点NameNode
- 维护目录树:维护目录树的增删改查操作,保证所有修改都能持久化,以便机器掉电不会造成数据丢失或不一致
- 维护文件和数据块的关系:文件被切分成多个块,文件以数据块为单位进行多副本存放,这些块存放在DataNode上,由NameNode来维护
- 维护文件快存放节点信息:通过接受DataNode的心跳汇报信息,维护集群节点的拓扑结构和每个文件块所有副本所在的DataNode等
- 分配新文件存放节点:Client创建新的文件时候,需要有NameNode来确定分配目标DataNode
数据节点DataNode
- 数据块存取:DataNode需要高效实现对数据块在硬盘上的存取
- 心跳汇报:把存放在本机的数据块列表发送给NameNode,以便NameNode能维护数据块的位置信息,同时让NameNode确定该节点处于正常存活状态
- 副本复制:1.数据写入时Pipeline IO操作 2.机器故障时补全副本
HDFS关键设计
分布式存储系统基本概念
- 容错能力:能够处理绝大部分异常场景,例如服务器宕机、网络异常、磁盘故障、网络超时等
- 一致性模型:为了实现容错,数据必须多副本存放,一致性要解决的问题时如何保障这不同机器多个副本的内容都是一致的
- 可扩展性:分布式存储系统需要具备横向扩张scale-out的能力,容量不够,可以通过加节点做一些扩展等
- 节点体系:常见的有主从模式、对等模式等,不管哪种模式,高可用是必须的功能
- 数据防止:系统是由多个节点组成,数据是多个副本存放时,需要考虑数据存放的策略
- 单机存储引擎:在绝大部分存储系统中,数据都是需要落盘持久化,单机引擎需要解决的时根据兄特点,如何高效的存取硬盘数据
NameNode目录树维护
fsimage
- 文件系统目录树
- 完整的存放在内存中
- 定时存放在硬盘上
- 修改时只会修改内存中的目录树
Editlog
- 目录树的修改日志,修改时实时的刷到硬盘上,掉电时可以通过Editlog构建出完整一致的目录树
- client更新目录树需要持久化Editlog后才能表示更新成功
- Editlog可循放在本地文件系统,也可存放在专用系统上
- NameNode HA方案一个关键点就是如何实现EditLog共享
NameNode数据放置
数据块信息维护
- 目录树保存每个文件的块id
- NameNode维护了每个数据块所在的节点信息
- NameNode根据DataNode回报的信息动态维护位置信息
- NameNode不会持久化数据块位置信息,启动时DataNode告诉NameNode我这里有这些块,NameNoede再去在内存中构建map信息
注意:数据副本应该分别储存在多个节点上,这样及时一个节点失效,其他节点依然有可读副本。
数据放置策略
- 新数据存放到哪写节点
- 数据均衡需要怎么合理搬迁数据
- 3个副本怎么合理放置
DataNode
数据块的硬盘存放
- 文件在NameNode已分割成block
- DataNode以block为单位对数据进行存取
第一个绿框是硬盘盘符,第二三个绿色框是它的blockid 既它存储在硬盘上的哈希值,第一个红框是存储内容,第二个是元数据,描述块的校验码之类的。
启动扫盘
- DataNode需要知道本机存放了哪些数据块
- 启动时把本机硬盘上的数据块列表加载在内存中
HDFS写异常处理
Lease Recovery
租约:Client要修改一个文件时,需要通过NameNode上锁,这个锁就是租约(Lease)
情景:文件写了一半,client自己挂掉了。
可能产生的问题:
- 没有ACK,副本不一致
- Lease无法释放
解决方法:Lease Recovery
Lease Recovery流程
- 获取包含文件最后一个 block 的所有 DataNodes。
- 指定其中一个 DataNode 作为主导恢复的节点。
- 主导节点向其他节点请求获得它们上面存储的 replica 信息。
- 主导节点收集了所有节点上的 replica 信息后,就可以比较计算出各节点上不同 replica 的最小长度。
- 主导节点向其他节点发起更新,将各自 replica 更新为最小长度值,保持各节点 replica 长度一致。
- 所有 DataNode 都同步后,主导节点向 NameNode 报告更新一致后的最终结果。
- NameNode 更新文件 block 元数据信息,收回该文件租约,并关闭文件。
Pipeline Recovery
情景:文件写入过程中,DataNode侧出现异常挂掉了,服务端出错了
异常出现的时机:
- 创建连接时
- 数据传输时
- complete阶段
解决方法: Pipeline Recovery
1.数据准备阶段发生错误:
- 新写文件:Client 重新请求 NameNode 分配 block 和 DataNodes,重新设置 pipeline。
- 追加文件:Client 从 pipeline 中移除出错的 DataNode,然后重新准备。
2.data streaming 错误(数据传输阶段) :
- 当 pipeline 中的某个 DataNode 检测到写入磁盘出错(可能是磁盘故障),它自动退出 pipeline,关闭相关的 TCP 连接。
- 当 Client 检测到 pipeline 有 DataNode 出错,先停止发送数据,并基于剩下正常的 DataNode 重新构建 pipeline 再继续发送数据。
- Client 恢复发送数据后,从没有收到确认的 packet 开始重发,其中有些 packet 前面的 DataNode 可能已经收过了,则忽略存储过程直接传递到下游节点。
3.close 错误:
- Client继续让剩下的 DataNode 重建 pipeline,并完成close操作。
Client读异常处理
情景:读取文件的过程,DataNode侧出现异常挂掉了
解决方法:节点Failover,和第二个节点连接读取副本
增强情景:节点半死不过,读取很慢
旁路系统
Balancer:均衡DataNode的容量
Mover:确保副本放置符合策略要求
控制面建设
可观测性设施
- 指标埋点
- 数据采集
- 访问日志
- 数据分析
运维体系建设
- 运维操作需要平台化
- NameNode操作复杂
- DataNode机器规模庞大
- 组件控制面API
\