HDFS存储架构主要由三部分组成:NameNode,DataNode,Client
NameNode
- Namenode 是一个中心服务器,单一节点(简化系统的设计和实现),负责管理文件系统的名字空间(namespace)以及客户端对文件的访问。
- 文件操作,NameNode 负责文件元数据的操作,DataNode负责处理文件内容的读写请求,跟文件内容相关的数据流不经过NameNode,只会询问它跟那个DataNode联系,否则NameNode会成为系统的瓶颈。
- 副本存放在哪些DataNode上由 NameNode来控制,根据全局情况做出块放置决定,读取文件时NameNode尽量让用户先读取最近的副本,降低带宽消耗和读取时延
- Namenode 全权管理数据块的复制,它周期性地从集群中的每个Datanode接收心跳信号和块状态报告(Blockreport)。接收到心跳信号意味着该Datanode节点工作正常。块状态报告包含了一个该Datanode上所有数据块的列表。
DataNode:
- 一个数据块在DataNode以文件存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳
- DataNode启动后向NameNode注册,通过后,周期性(1小时)的向NameNode上报所有的块信息。
- 心跳是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个DataNode 的心跳,则认为该节点不可用。
- 集群运行中可以安全加入和退出一些机器
Client
- 客户端,系统使用者,调用HDFS API操作文件;与NameNode交互获取文件元数据;与DataNode交互进行数据读写。
读文件流程
(1)打开分布式文件
调用 分布式文件 DistributedFileSystem.open()方法
(2)从 NameNode 获得 DataNode 地址
DistributedFileSystem 使用 RPC 调用 NameNode,NameNode 返回存有该副本的 DataNode 地址,DistributedFileSystem 返 回一个输入流 FSDataInputStream对象,该对象封存了输入流 DFSInputStream
(3)连接到DataNode
调用 输入流 FSDataInputStream 的 read() 方法,从而 输入流 DFSInputStream 连接 DataNodes
(4)读取DataNode
反复调用 read()方法,从而将数据从 DataNode 传输到客户端
(5)读取另外的DataNode直到完成
到达块的末端时候,输入流 DFSInputStream 关闭与DataNode 连接, 寻找下一个 DataNode
(6)完成读取,关闭连接
即调用输入流 FSDataInputStream.close()
写文件流程
(1)发送创建文件请求:调用分布式文件系统DistributedFileSystem.create()方法
(2)NameNode中创建文件记录:分布式文件系统DistributedFileSystem 发送 RPC 请求给namenode,namenode 检查权限后创建一条记录,返回输出流 FSDataOutputStream,封装了输出流 DFSOutputDtream
(3)客户端写入数据:输出流 DFSOutputDtream 将数据分成一个个的数据包,并写入内部队列。DataStreamer 根据 DataNode 列表来要求 namenode 分配适合的新块来存储数据备份。一组DataNode 构成管线(管线的 DataNode 之间使用 Socket 流式通信)
(4)使用管线传输数据:DataStreamer 将数据包流式传输到管线第一个DataNode,第一个DataNode 再传到第二个DataNode ,直到完成。
(5)确认队列:DataNode 收到数据后发送确认,管线的DataNode所有的确认组成一个确认队列。所有DataNode 都确认,管线数据包删除。
(6)关闭:客户端对数据量调用close()方法。将剩余所有数据写入DataNode管线,并联系NameNode且发送文件写入完成信息之前等待确认。
(7)NameNode确认
(8)故障处理:若过程中发生故障,则先关闭管线, 把队列中所有数据包添加回去队列,确保数据包不漏。为另一个正常DataNode的当前数据块指定一个新的标识,并将该标识传送给NameNode, 一遍故障DataNode在恢复后删除上面的不完整数据块. 从管线中删除故障DataNode 并把余下的数据块写入余下正常的DataNode。NameNode发现复本量不足时,会在另一个节点创建一个新的复本