这是我参与「第四届青训营 」笔记创作活动的的第8天
0x00 HDFS基本介绍
0.1 Hadoop体系
0.2 文件系统
- 单机文件系统:
常见的如Windows NTFS,Linux的Ext4,虽然不同的操作系统和实现,但是本质都是一样的,解决相同的问题。 - 分布式文件系统:
本质上扩展、延伸了单机文件系统,提供了大容量、高可靠、低成本等功能特性;实现上一般也更为复杂。
0.3 分布式存储系统
- 对象存储:例如AWS的S3,阿里云的OSS,开源的Minio。
- 块存储:例如AWS的EBS,开源社区也有Ceph等。
- 文件系统:HDFS、GlusterFS、CubeFS等
- 数据库:KV数据库比如Cassandra,关系型数据库如TiDB、OceanBase等
0.4 HDFS功能特性
- 分布式
- 容错
- 高可用
- 高吞吐
- 可扩展
- 廉价
0x01 HDFS架构原理
1.1 HDFS组件
- Client/SDK:
读写操作的发起点,HDFS很多读写逻辑都是在SDK中实现的。 - NameNode:
元数据节点,是HDFS的中枢节点,也是服务的入口。 - DataNode:
数据节点,存放实际用户数据。
1.2 Client写流程
1.3 Client读流程
1.4 元数据节点NameNode
- 维护目录树
维护目录树的增删改查操作,保证所有修改都能持久化,以便机器掉电不会造成数据丢失或不一致 - 维护文件和数据块的关系
文件被切分成多个块,文件以数据块为单位进行多副本存放 - 维护文件块存放节点信息
通过接收DataNode的心跳汇报信息,维护集群节点的拓扑结构和每个文件块所有副本所在的DataNode类表 - 分配新文件存放节点
Client创健新的文件时候,需要有NameNode来确定分配目标DataNode
1.5 数据节点 DataNode
- 数据块存取
- DataNode需要高效实现对数据块在硬盘上的存取
- 心跳汇报
- 把存放在本机的数据块列表发送给NameNode,以便NameNode能维护数据块的位置信息,同时让NameNode确定该节点处于正常存活状态
- 副本复制
- 数据写入时Pipeline IO操作
- 数据写入时Pipeline IO操作
0x02 HDFS关键设计
2.1 NameNode目录树
- 仅在内存中修改:fsimage
2. 需要立即保存到硬盘:EditLog
2.2 NameNode数据放置
数据分散在各个节点上,如何定位:
- 文件和数据块具备映射关系
- 目录树保存每个文件的块id
- NameNode维护了每个数据块所在的节点信息
- NameNode根据DataNode汇报的信息动态维护位置信息
- NameNode不会持久化数据块位置信息
- 数据块的放置分布策略
2.3 DataNode设计
- 数据块的硬盘存放
- 文件在NameNode已分割成block
- DataNode以block为单位对数据进行存取
- 启动扫盘
- DataNode需要知道本机存放了哪些数据块
- 启动时把本机硬盘上的数据块列表加载在内存中
2.4 Client读写链路的异常处理
- Server端异常
- 可能存在的问题:
- 创建连接时DataNode异常挂掉
- 数据传输时DataNode异常挂掉
- complete时DataNode异常挂掉
- 解决方案: Pipeline Recovery
- 可能存在的问题:
- Client端异常
- 可能存在的问题:
- 副本不一致
- 租约(Lease)无法释放
- 解决方案:
Lease Recovery
- 可能存在的问题:
2.5 旁路系统
-
Balancer:均衡DataNode的容量
-
Mover:确保副本放置符合策略要求
2.6 控制面建设
HouseKeeping组件:比如Balancer,Mover等, 这些组件不运行不会马上影响读写操作,但是长时间会积累系统性问题,例如读写不均衡导致IO热点等,因此需要控制面建设:
- 可观测性设施:比如系统指标监控设施等,帮助快速发现定位问题。
- 运维体系建设:从最基本的命令行手工操作,脚本自动化再到完善的运维平台。