HDFS 写入数据流程

宏观流程

No 步骤 详情
1 客户端向HDFS发送写数据请求 hdfs dfs -put tomcat.tar.gz /bdg/
2 filesystem通过rpc调用namenode的create方法 nn首先检查是否有足够的空间权限等条件创建这个文件,或者这个路径是否已经存在
有:NN会针对这个文件创建一个空的Entry对象,并返回成功状态给DFS
没有:直接抛出对应的异常,给予客户端错误提示信息
3 DFS如果接收到成功状态,会创建一个对象FSDataOutputStream的对象给客户端使用 返回流
4 客户端需要向NN询问第一个Block存放的位置 NN通过机架感知策略 (node1 node 2 node8)
5 需要将客户端和DN节点创建连接 pipeline(管道)
客户端和node1创建连接 socket
node1和node2创建连接 socket
node2 和node8创建连接 socket
6 客户端将文件按照块block切分数据,但是按照packet发送数据 block = 128M
packet = 64K
block = 2048 * packet
7 客户端通过pipeline管道开始使用FSDataOutputStream对象将数据输出 客户端首先将一个packet发送给node1,同时给予node1一个ack状态
node1接受数据后会将数据继续传递给node2,同时给予node2一个ack状态
node2接受数据后会将数据继续传递给node8,同时给予node8一个ack状态
node8将这个packet接受完成后,会响应这个ack给node2为true
node2会响应给node1 ,同理node1响应给客户端
8 客户端接收到成功的状态,就认为某个packet发送成功了,直到当前块所有的packet都发送完成
9 如果客户端接收到最后一个pakcet的成功状态,说明当前block传输完成
10 客户端会将这个消息传递给NN,NN确认传输完成 NN会将block的信息记录到Entry,客户端会继续向NN询问第二个块的存储位置,依次类推
block1 (node1 node2 node8)
block2 (node1 node8 node9)
....
blockn(node1 node7 node9)
11 当最后一个Block传输完成,管道就会被撤销 每次传完一个Block都会撤销管道,根据下一个Block对应的DN,重新新建管道
12 当所有的block传输完成后,NN在Entry中存储所有的File与Block与DN的映射关系
13 关闭FsDataOutPutStream

微观流程

  1. 首先客户端从自己的硬盘以流的方式读取数据文件到自己的缓存中

  2. 然后将缓存中的数据以chunk (512B)和checksum(4B)的方式放入到packet (64K)

    1. chunk:checksum=128:1
    2. checksum:在数据处理和数据通信领域中,用于校验目的的一组数据项的和
    3. Packet分为两类,一类是实际数据包,另一类是heater包。
  3. 一个Packet数据包的组成结构

  4. 当packet满的时候加入到添加到dataqueue

  5. datastreamer开始从dataqueue队列上取出一个packet,通过FSDataOPS发送到Pipleline

    1. 在取出的时候,也会将packet加入到ackQueue,典型的生产者消费者模式
  6. 客户端发送一个Packet数据包以后开始接收ack,会有一个用来接收ack的ResponseProcessor进 程,如果收到成功的ack

    1. 如果某一个packet的ack为true,那么就从ackqueue删除掉这个packet
    2. 如果某一个packet的ack为false,将ackqueue中所有的packet重新挂载到 发送队列,重新发送
  7. 最终DFS保存的数据格式为

HDFS 读取数据流程

  1. 首先客户端发送请求到DFS,申请读取某一个文件
    1. hdfs dfs -get /bdp/tomcat.tar.gz /home/hadoop
  2. DFS去NN查找这个文件的信息(权限,文件是否存在)
    1. 如果文件不存在,抛出指定的错误
    2. 如果文件存在,返回成功状态
  3. DFS创建FSDataInputStream对象,客户端通过这个对象读取数据
  4. 客户端获取文件第一个Block信息,返回DN1 DN2 DN8
  5. 客户端直接就近原则选择DN1对应的数据即可
  6. 依次类推读取其他块的信息,直到最后一个块,将Block合并成一个文件
  7. 关闭FSDataInputStream