HDFS读写流程详解
写流程
-
大致流程
- 客户端先向NameNode进行通信,确认文件路径以及父路径是否正确,并获取负责接受块的DataNode位置。然后客户端按照文件顺序逐个将block传递给一个DataNode,这个DataNode接收到文件后会负责向另一个DataNode复制副本,以此连续直到副本数到达要求
-
详细流程
- DistributeFileSystem(FileSystem的子类)调用
create()
方法,DistributeFileSystem与NameNode创建一个PRC调用,并在NameNode的命名空间中创建一个文件 - NameNode会对这个文件是否存在以及父路径是否存在进行判断,如果检查通过则则NameNode为日志文件新键一条记录,如果检查失败则抛出异常
- 客户端会按照块大小先对文件进行切分,然后向NameNode请求可以存储数据块的DataNode
- 客户端向DataNode请求RPC调用,建立pipeline。第一个收到请求的DataNode会向下一个DataNode发送请求,依次循环直到pipeline建立完成,逐级返回客户端
- 客户端将数据库从磁盘读取到本地缓存,以packet(64kb)为单位,向DataNode逐级发送。
- 写入数据时,DataNode会以chunk(512byte)为单位进行数据校验
- 当一个block传输完成后,客户端再次请求NameNode上传第二个数据库的服务器
- DistributeFileSystem(FileSystem的子类)调用
-
DataNode发生故障
- 关闭管线
- 重新将数据包添加回队列前端
- 为正常的DataNode添加新标识,并将标识上报给NameNode
- 将故障的DataNode节点从管线中删除
- 重新选择DataNode创建管线
读流程
- 大致流程
- 客户端将要读取文件的路径发送给NameNode,NameNode将文件的信息(数据库的位置信息)返回给客户端,客户端跟进信息找到DataNode逐个获取文件的数据块,并在客户端本地进行合并,从而获取整个文件
- 详细流程
- 客户端与NameNode进行通信查询元数据信息,即block所在的DataNode节点
- 根据就近原则挑选DataNode(没有就近的节点就随机选择),并建立socket流
- DataNode开始发送数据(以packet为单位进行校验)
- 客户端以packet为单位接受,先在本地进行缓存,然后写入目标文件中,进行合并
- DataNode通信遇到错误时
- 会尝试从这个块的另外一个临近的DataNode读取数据。
- 会记住故障的DataNode节点,保证以后不会反复读取该节点上后续的块。
- DFSInputStream也会校验数据是否完整,如果发现有损坏的块。会试图从其他的DataNode进行赋值,并将损坏的块通知NameNode