HDFS组成架构
HDFS采用Master/Slave的架构来存储数据,这种架构主要由四个部分组成,分别为HDFS Client、NameNode、DataNode和Secondary NameNode。
- Client:客户端。
(1)文件切分:文件上传HDFS时,Client将文件切分成一个一个的数据块(Block),然后进行上传。
(2)与NameNode交互,获取文件的位置信息。
(3)与DataNode交互,读取或者写入数据。
(4)提供一些命令来管理HDFS,比如NameNode格式化。
(5)通过一些命令访问HDFS,比如对HDFS进行增删查改。 - NameNode:就是Master,是一个主管。
(1)管理HDFS的名称空间
(2)配置副本策略
(3)管理Block映射信息
(4)处理客户端读写请求 - DataNode:就是Slave,NameNode下达命令,DataNode执行实际的操作。
(1)存储实际的Block
(2)执行数据块的读写操作 - Secondary NameNode:并不是NameNode的热备,当NameNode挂掉时,它并不能马上替换NameNode并提供服务。
(1)辅助NameNode,分担其工作量,比如定期合并Fsimage和Edits,并推送给NameNode。
(2)在紧急情况下,可辅助恢复NameNode。
HDFS读写数据流程
HDFS写数据流程:
- Client通过Distributed FileSystem模块向NameNode请求上传文件,NameNode检查目录文件是否已存在。
- NameNode返回是否可以上传。
- Client请求第一个Block上传到哪几个DataNode服务器上。
- NameNode返回3个DataNode节点(replication的默认值为3),假设分别为dn1,dn2,dn3。
- Client通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求后会继续调用dn2,然后dn2调用dn3,将这个通信管道(pipeline)建立完成。
- dn1,dn2,dn3逐级应答客户端。
- Client开始以packet为单位往dn1上传第一个Block,dn1收到一个packet就会传给dn2,dn2再传给dn3;dn1每传一个packet会放入一个应答队列等待应答。(数据先写入client本地缓存,然后写入packet(64k),packet写满之后会放入dataQueue中排队并通知DataStreamer线程去消费数据)
- 当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的DataNode服务器,重复3-7步,直到文件全部上传完毕。(ResponseProcessor线程接收dn返回的packet ack,并更新DataStreamer的stage,最后文件上传完毕后关闭流)
HDFS读数据流程: - Client通过Distributed FileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。
- 挑选一台DataNode服务器(就近原则),请求读取数据。
- DataNode开始传输数据给客户端(从磁盘读取数据输入流,以packet为单位来做校验)。
- Client以packet为单位接收,先在本地缓存,然后写入目标文件。
数据读取流程中,DataNode为每个正在读取数据块的client保留了一个线程和一个TCP套接字,内核中会有相关开销,实际上HDFS还有一个Short-Circuit机制可以来做数据本地读取时的优化:client回想DataNode请求创建一块共享内存,DataNode创建共享内存文件后将共享内存文件描述符返回给client;client申请共享内存中的槽位,并向DataNode请求要读取的副本文件描述符,DataNode打开副本文件并将数据块文件和元数据文件的描述符返回给client;client读取完副本后,异步向DataNode请求释放文件描述符及相应槽位。