这是我参与「第四届青训营 」笔记创作活动的第7天
HDFS
架构原理
HDFS的三大件分别是: Client/SDK、NameNode、DataNode
一般集群中的DataNode要多于NameNode。
Client
这里只讲述大致流程,内部具体的实现细节可以看我之前写的一篇笔记
写流程:
- Client向NameNode请求写入新的数据块
- NameNode检查数据是否合法,若合法记录元数据,返回副本目标DataNode列表
- Client切分文件符合块的大小并,向DN写入数据块,DN之间传递复制数据块
- 节点之间传递ACK信息告知写入成功
读流程:
- Clinet发送getBlockLocations请求
- NameNode返回目标副本DN列表
- Client从DataNode读取数据
NameNode
NameNode的主要功能有:
-
维护目录树: 主要是维护目录树的增删改查操作,保证所有修改的持久化。
-
维护文件和数据块的关系: 将文件切分为许多块,以块为单位存储数据。
-
维护文件块存放节点信息: 接受DataNode的心跳,维护集群节点的拓扑结构,保证每个文件所有副本所在的DataNode类表。
-
分配新文件存放节点: Client想要写入或创建新文件是需要NameNode对其进行分配存放目标DataNode。
DataNode
DataNode的主要功能有:
- 数据块存取: DataNode要求存取数据的高效性。
- 心跳汇报: 每一段时间将自己的数据块列表发送给NameNode,方便NameNode对这些数据块进行管理,并证明自己还活着。
- 副本复制: 数据写入时有Pipeline IO操作,以及在机器故障时可以补全副本。
关键设计
NameNode目录树维护
fsimage:
文件系统的目录树,存放在内存中,定时会存放在硬盘上,修改目录树只会修改内存中的目录树。
EditLog:
目录树的修改日志,Client需要持久化EditLog后才能更新目录树,EditLog的存放位置灵活,可以是本地文件系统,也可以是专门的系统上,NameNode HA的一个关键点就是实现EditLog的共享。
NameNode数据放置
数据块信息维护:
每个块id中都保存着目录树,而NameNode通过DataNode汇报的心跳动态维护位置信息,维护每个数据块所在节点的信息。但是NameNode并不会持久化存储位置信息。
数据放置策略:
数据一般存放在多个节点,在某个节点宕机时,数据在其他节点有备份,不至于丢失。
DataNode
数据块硬盘存放:
NameNode将数据划分为一个个的块,而DataNode存放数据的单位就是块。
启动扫描盘:
DataNode需要知道本机器存放了哪些数据块,所以启动时会把本机硬盘上的数据块列表加载到内存中。
异常处理
- Lease Recovery 解决Client在写过程中挂掉导致NameNode的Lease无法释放的问题。
- Pipeline Recovery 解决文件写入时DataNode侧挂掉出现文件写入失败的问题。
- 节点 Failover 解决读数据时DataNode侧挂掉问题。