HDFS原理与应用 这是我参与「第四届青训营 」笔记创作活动的第5天
1. HDFS基本介绍
- windows单机文件系统——NTFS、FAT32、exFAT
- Linux单机文件系统——BTRFS,ZFS,XFS,EXT4
- 分布式文件系统
- 大容量:更多的机器,更多的存储介质
- 高可靠:多个副本提高容错能力
- 低成本:不需要用高端硬件来扩容
- 分布式存储系统:对象存储,文件系统,块存储,数据库:
- 对象存储:例如AWS的S3,阿里云的OSS,开源的Minio。
- 块存储:例如AWS的EBS,开源社区也有Ceph等。
- 文件系统:HDFS、GlusterFS、CubeFS等
- 数据库:KV数据库比如Cassandra,关系型数据库如TiDB、OceanBase等
1.1 HDFS功能特性
- 分布式:受GFS启发,用Java实现的开源系统,没有实现完整的POSIX文件系统语义
- 容错:自动处理、规避多种错误场景,例如常见的网络错误、机器宕机等。
- 高可用:一主多备模式实现元数据高可用,数据多副本实现用户数据的高可用
- 高吞吐:Client直接从DataNode读取用户数据,服务端支持海量client并发读写
- 可扩展:支持联邦集群模式,DataNode数量可达10w级别
- 廉价:只需要通用硬件,不需要定制高端的昂贵硬件设备
2. 架构原理
2.1 分布式存储系统基本概念
- 容错能力:能够处理绝大部分异常场景,例如服务器宕机、网络异常、磁盘故障、网络超时等。
- 一致性模型:为了实现容错,数据必须多副本存放,一致性要解决的问题是如何保障这多个副本的内容都是一致的
- 可扩展性:分布式存储系统需要具备横向扩张scale: -out的能力
- 节点体系模式:常见的有主从模式、对等模式等,不管哪种模式,高可用是必须的功能。
- 数据放置策略:系统是由多个节点组成,数据是多个副本存放时,需要考虑数据存放的策略。
- 单机存储引擎:在绝大部分存储系统中,数据都是需要落盘持久化,单机引擎需要解决的是根据系统特点,如何高效得存取硬盘数据。
2.2 HDFS功能组件
- Client/SDK:读写操作的发起点,HDFS很多读写逻辑都是在SDK中实现的。
- NameNode:元数据节点,是HDFS的中枢节点,也是服务的入口。
- DataNode:数据节点,存放实际用户数据。
3. 关键设计
-
NameNode目录树维护
- 仅在内存中修改:fsimage
- 文件系统目录书,能够完整地存放在内存中,定时存放到硬盘上,修改是只会修改内存中的目录树
- 需要立即保存到硬盘:EditLog
- 目录树的修改日志,client更新目录树需要持久化EditLog后才能表示更新恒公
- EditLog存放位置:本地文件系统/专用系统上
- NameNode HA:如何实现EditLog共享
- 仅在内存中修改:fsimage
-
NameNode数据放置:数据分散在各个节点上,如何定位找到它们?
- 数据块信息维护
- 目录树保存每个文件的块id,NameNode维护了每个数据块所在的节点信息
- NN根据DN汇报的信息动态维护位置信息,不会持久化数据块位置信息
- 数据块的放置分布策略
- 数据块信息维护
-
DataNode设计:数据如何落盘存放?
- 数据块路径
- 文件在NN已经分割成block,DN以block为单位对数据进行存放
- 启动扫盘获得本机文件块列表
- DN需要知道本季存放了哪些数据块
- 启动时把本机硬盘上的数据块列表还在在内存中
- 数据块路径
-
Client读写链路的异常处理
-
写数据异常
- Server端异常
- 文件写入过程中,DN侧出现异常,异常出现的时机
- 创建连接时
- 数据传输时
- complete阶段
- 解决方法:Pipeline Recovery
- 文件写入过程中,DN侧出现异常,异常出现的时机
- Client端异常
- 可能导致的问题:副本不一致;租约(lease)无法释放
- client要修改一个文件,需要通过NN上锁,这个锁就是租约
- 解决方法:Lease Recovery
- 可能导致的问题:副本不一致;租约(lease)无法释放
- Server端异常
-
读数据异常:
- 慢节点:读取文件过程中,DataNode出现异常挂掉了,解决方法:节点 Failover
-
旁路系统:HouseKeeping组件:比如Balancer,Mover等, 这些组件不运行不会马上影响读写操作,但是长时间会积累系统性问题,例如读写不均衡导致IO热点等。
- Balancer:均衡DN的容量
- Mover:确保副本放置符合策略的要求
-
控制面建设:保障系统稳定运行
- 可观测性设施:比如系统指标监控设施等,帮助快速发现定位问题。
- 运维体系建设:从最基本的命令行手工操作,脚本自动化再到完善的运维平台。