博客中介绍了 HDFS 读取文件的流程,这篇文章趁热打铁,介绍一下 HDFS 文件写入的流程,整个流程如下:
- 通过 FileSystem.get 方法获取文件系统 FileSystem,HDFS 文件系统实例为 DistributedFileSystem。
- 通过 DistributedFileSystem.create 调用 namenode 的服务,请求在 namenode 的命名空间中创建一个新的文件条目。namenode 会先检查该文件是否存在,客户端是否有权限创建,通过这些检查之后 namenode 才会生成文件条目,并返回 DFSoutputStream,负责处理数据节点和名称节点之间的通信。如果失败则返回一个 IOException。
- DFSoutputStream 在将文件写入到 datanode 前,会先将文件分为一个个 packet,排成队列 data queue。
- DFSoutputStream 在处理 data queue 时,会先请求 namenode,询问这个文件存储在哪几个 datanode 比较合适(为了保证数据的安全性,需要将文件备份到不同的 datanode 上,默认为 3 个)。然后将这几个 datanode 排成一个 pipeline,DFSoutputStream 把 packet 按 data queue 队列顺序发送到第一个 datanode 中,第一个 datanode 又把这个 packet 发送到第二个 datanode 中,以此类推。
- 当 pipeline 中所有节点将这个 packet 传输完成之后,会发送一个确认码给客户端,这时 DFSoutputStream 才会将这个 packet 从 data queue 中去掉。
- 文件传输完成之后,SDFoutputStream 调用 close 方法结束文件的传输
- DistributedFileSystem 调用 complete 通知 namenode 把这个文件标示为已完成。
用一张图片概括就是这个样子:
这里在补充说明一个问题,namenode 如何选择哪个数据节点来保存副本呢?Hadoop 的策略是在与客户端相同的节点上放置第一个副本(若客户端运行在集群之外,就可以随机选择节点,不过系统会避免挑选那些太满或太忙的节点)。
第二个副本被放置在与第一个节点不同的随机选择的机架上。第三个副本被放置在与第二个副本相同的机架,但放在不同的节点。整个数据中心如下图:
以上就是我对 HDFS 写入文件的总结,如果有错欢迎指出!