hdfs写入数据的流程

1、客户端通过调用distributedFileSystem调用ceate()方法创建文件

2、distributedFileSystem对namenode创建一个PPC调用,去检查是否有这个文件,以及这个文件的权限,如果有这个文件,会返回IOException,如果没有就去创建这个文件。之后distributedFileSystem会返回给客户端DFSOutputStream对象,这个对象负责处理DataNode和namenode之间的通信。

3、客户端写入数据时,DFSOutputStream将这个数据分解成一个个的数据包,并写入内存数据队列中,称为“数据队列”

4、datastreamer来处理数据,是根据DataNode的大小来要求namenode分配DataNode适合的新内存来存储这些数据副本。首先将数据队列存储在第一DataNode中,之后一次存储在第二个DataNode中,然后再存储在第三个DataNode中。

5、等到DataNode存储完成之后,fileoutputstream等待DataNode去返回回执结果。等到DataNode将所有的结果都返回之后,该数据包才会从这个数据队列中删除。

6、客户端完成数据的写入后,调用close方法,该操作将所有的包写入DataNode管线。

7、distributedFileSystem等待确认信号,namenode已经知道文件由哪些块组成,所以他在返回前只需要等待数据块进行最小量的复制。

hdfs写入数据的流程_第1张图片

  1. 客户端通过在DistributedFileSystem中调用create()来创建文件。
  2. DistributedFileSystem 使用RPC去调用namenode,在文件系统的命名空间创一个新的文件,没有块与之相联系。namenode执行各种不同的检查以确保这个文件不会已经存在,并且在client有可以创建文件的适当的许可。如果检查通过,namenode就会生成一个新的文件记录;否则,文件创建失败并向client抛出一个IOException异常。分布式文件系统返回一个文件系统数据输出流,让client开始写入数据。就像读取事件一样,文件系统数据输出流控制一个DFSOutputStream,负责处理datanode和namenode之间的通信。
  3. 在client写入数据时,DFSOutputStream将它分成一个个的包,写入内部队列,称为数据队列。数据流处理数据队列,数据流的责任是根据适合的datanode的列表要求namenode分配适合的新块来存储数据副本。这一组datanode列表形成一个管线————假设副本数是3,所以有3个节点在管线中。
  4. 数据流将包分流给管线中第一个的datanode,这个节点会存储包并且发送给管线中的第二个datanode。同样地,第二个datanode存储包并且传给管线中的第三个数据节点。
  5. DFSOutputStream也有一个内部的数据包队列来等待datanode收到确认,称为确认队列。一个包只有在被管线中所有的节点确认后才会被移除出确认队列。如果在有数据写入期间,datanode发生故障, 则会执行下面的操作,当然这对写入数据的client而言是透明的。首先管线被关闭,确认队列中的任何包都会被添加回数据队列的前面,以确保故障节点下游的datanode不会漏掉任意一个包。为存储在另一正常datanode的当前数据块制定一个新的标识,并将该标识传给namenode,以便故障节点datanode在恢复后可以删除存储的部分数据块。从管线中删除故障数据节点并且把余下的数据块写入管线中的两个正常的datanode。namenode注意到块复本量不足时,会在另一个节点上创建一个新的复本。后续的数据块继续正常接收处理。只要dfs.replication.min的副本(默认是1)被写入,写操作就是成功的,并且这个块会在集群中被异步复制,直到其满足目标副本数(dfs.replication 默认值为3)。
  6. client完成数据的写入后,就会在流中调用close()。
  7. 在向namenode节点发送完消息之前,此方法会将余下的所有包放入datanode管线并等待确认。namenode节点已经知道文件由哪些块组成(通过Data streamer 询问块分配),所以它只需在返回成功前等待块进行最小量的复制。
  • 复本的布局:需要对可靠性、写入带宽和读取带宽进行权衡。Hadoop的默认布局策略是在运行客户端的节点上放第1个复本(如果客户端运行在集群之外,就随机选择一个节点,不过系统会避免挑选那些存储太满或太忙的节点。)第2个复本放在与第1个复本不同且随机另外选择的机架的节点上(离架)。第3个复本与第2个复本放在相同的机架,且随机选择另一个节点。其他复本放在集群中随机的节点上,不过系统会尽量避免相同的机架放太多复本。
  • 总的来说,这一方法不仅提供了很好的稳定性(数据块存储在两个机架中)并实现很好的负载均衡,包括写入带宽(写入操作只需要遍历一个交换机)、读取性能(可以从两个机架中选择读取)和集群中块的均匀分布(客户端只在本地机架上写入一个块)。

你可能感兴趣的:(HDFS)