我有关于hadoop数据写入的小查询
来自Apache文档
对于常见情况,当复制因子为3时,HDFS的放置策略是将一个副本放在本地机架中的一个节点上,另一个放置在不同(远程)机架中的节点上,而将最后一个放在不同节点上在同一个远程机架中。此策略可以减少机架间写入流量,从而提高写入性能。机架故障的可能性远小于节点故障的可能性;
在下图中,写入确认被视为成功?
1)将数据写入第一个数据节点?
2)将数据写入第一个数据节点+2个其他数据节点?
我问这个问题因为,我在YouTube视频中听到了两个相互矛盾的陈述。一个视频引用一旦数据写入一个数据节点并且写入成功。其他视频引用了只有在将数据写入所有三个节点后才会发送确认。
答案 0 :(得分:6)
步骤1:客户端通过在DistributedFileSystem上调用create()方法来创建文件。
第2步: DistributedFileSystem对namenode进行RPC调用,在文件系统的命名空间中创建一个新文件,没有与之关联的块。
namenode执行各种检查以确保文件尚不存在,并且客户端具有创建文件的正确权限。如果这些检查通过,则namenode会记录新文件;否则,文件创建失败,客户端抛出IOException。 TheDistributedFileSystem返回一个FSDataOutputStream,供客户端开始写入数据。
步骤3:当客户端写入数据时,DFSOutputStream会将其拆分为数据包,并将其写入内部队列,称为数据队列。数据队列由DataStreamer使用,DataStreamer负责通过选择合适的数据节点列表来请求namenode分配新块以存储副本。数据节点列表形成一个管道,这里我们假设复制级别为3,因此管道中有三个节点。 TheDataStreamer将数据包流式传输到管道中的第一个数据节点,存储数据包并将其转发到管道中的第二个数据节点。
步骤4:同样,第二个数据节点存储数据包并将其转发到管道中的第三个(也是最后一个)数据节点。
步骤5: DFSOutputStream还维护一个等待数据节点确认的数据包内部队列,称为ack队列。只有当管道中的所有数据节点都已确认时,才会从ack队列中删除数据包。
第6步:当客户端完成数据写入后,它会调用流上的close()。
步骤7:此操作将所有剩余的数据包刷新到datanode管道并在联系namenode之前等待确认,以表明文件已完成namenode已知道文件是由哪些块组成的因此,在成功返回之前,只需要等待块进行最低限度的复制。
答案 1 :(得分:2)
如果成功写入一个副本,则认为数据写入操作成功。它由hdfs-default.xml文件中的属性dfs.namenode.replication.min管理。 如果在编写副本时数据节点出现任何故障,则写入的数据不会被视为不成功,但是不足以复制,而在平衡群集时会创建缺少的副本。 Ack数据包与写入数据节点的数据状态无关。即使没有写入数据包,也会传送确认包。