Hadoop HDFS读写流程
读取:
1) 客户端调用 DistributedFileSystem 的 Open() 方法打开文件。
2) DistributedFileSystem 用 RPC 连接到 NameNode,请求获取文件的数据块的信息;NameNode 返回文件的部分或者全部数据块列表;对于每个数据块,NameNode 都会返回该数据块副本的 DataNode 地址;DistributedFileSystem 返回 FSDataInputStream 给客户端,用来读取数据。
3) 客户端调用 FSDataInputStream 的 Read() 方法开始读取数据。
4) FSInputStream 连接保存此文件第一个数据块的最近的 DataNode,并以数据流的形式读取数据;客户端多次调用 Read(),直到到达数据块结束位置。
5) FSInputStream连接保存此文件下一个数据块的最近的 DataNode,并读取数据。
6) 当客户端读取完所有数据块的数据后,调用 FSDataInputStream 的 Close() 方法。
写入:
1) 客户端调用 DistribuedFileSystem 的 Create() 方法来创建文件。
2) DistributedFileSystem 用 RPC 连接 NameNode,请求在文件系统的命名空间中创建一个新的文件;NameNode 首先确定文件原来不存在,并且客户端有创建文件的权限,然后创建新文件;DistributedFileSystem 返回 FSOutputStream 给客户端用于写数据。
3) 客户端调用 FSOutputStream 的 Write() 函数,向对应的文件写入数据。
4) 当客户端开始写入文件的时候,客户端会将文件切分成多个 packets,并在内部以数据队列“data queue(数据队列)”的形式管理这些 packets,并向 namenode 申请 blocks,获 取用来存储 replicas 的合适的 datanode 列表,列表的大小根据 namenode 中 replication 的设定而定;
队列中的分包被打包成数据包,将第一个块写入第一个Datanode,第一个 Datanode写完传给第二个节点,第二个写完传给第三节点
5) 为了保证所有 DataNode 的数据都是准确的,接收到数据的 DataNode 要向发送者发送确认包(ACK Packet)。确认包沿着数据流管道反向而上,当第三个节点写完返回一个ack packet给 第二个节点,第二个返回一个ack packet给第一个节点,第一个节点返回ack packet给 FSDataOutputStream对象,意思标识第一个块写完,副本数为3;然后剩余的块依次这样写;
6) 不断执行第 (3)~(5)步,直到数据全部写完。
7) 调用 FSOutputStream 的 Close() 方法,将所有的数据块写入数据流管道中的数据结点,并等待确认返回成功。最后通过 NameNode 完成写入。