HDFS读流程,写流程,放置策略

本文详细解析了HDFS的写入和读取流程,包括客户端如何与NameNode通信创建文件,数据块的副本写入过程,以及读取时如何选择DataNode节点。同时介绍了副本放置策略,确保数据的高可用性和一致性。

1.HDFS写流程

[hadoop@hadoop002 hadoop-2.6.0-cdh5.7.0]$ hdfs dfs -put LICENSE.txt /
19/02/20 21:30:22 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
[hadoop@hadoop002 hadoop-2.6.0-cdh5.7.0]$ 

对于我们操作者而言,是无感知的
1.Client调用FileSystem.create(filePath)方法,
去与NN进行【RPC】通信,check该路径的文件是否存在
以及有没有权限创建该文件。 假如OK,就创建一个新文件,
但是不关联任何的block,nn根据上传的文件大小且块大小且副本数,
计算多少块,以及块存放的dn,最终将这些信息返回给客户端
则为【FSDataOutputStream】。

2.Client调用FSDataOutputStream.write方法,将第一个块的
第一个副本写到第一个DN,写完写第二个副本,写完写第三个副本;
当第三个副本写完,返回给ack packet给第二个副本的DN,然后第二个DN返回ack packet给第一个DN;
第一个DN返回ack packet给FSDataOutputStream对象,标识第一个块,3副本写完!
然后依次写剩余的块!
(对操作者来说是透明的)

3.当向文件写入数据完成后,Client调用FSDataOutputStream.close()方法。关闭输出流,flush换成区的数据包。
4.再调用FileSystem.complete(),通知NN节点写入成功。
在这里插入图片描述

3DN
3副本
副本数据=DN

1DN
1副本
测试:DN挂了 能不能写
同比: 3DN 3副本 1DN挂了 肯定写不成功

10DN
3副本
副本数据<DN
测试:DN挂了 写

总结: 存活的DN满足我们的副本数 就能写

2.读流程

FSDataIutputStream
1.Client通过FileSystem.open(filePath),
去与NN进行【RPC】通信,返回该文件的部分
或全部的block列表,也就是返回FSDataInputStream对象。

2.Client调用【FSDataInputStream】对象的read()方法,
a. 去与第一个块的最近的DN进行read,读取完后,会check,
假如success,会关闭与当前DN通信。假如fail 会记录失败的DN+block信息,下次就不会读取。
那么会去该块的第二个DN的地址读取。
b.然后去第二个块的最近的DN上读取,会check,success,会关闭与当前DN通信。
c.假如当前block列表全部读取完成,文件还没结束,那么FileSystem会从NN获取下一批的block列表。
(对于操作者,是透明的,感觉就是连续的数据流)

3.Client调用FSDataInputStream.close() 关闭输入流

在这里插入图片描述

3.副本放置策略

生产上 尽量将读写的动作 选取DN节点
在这里插入图片描述

### HDFS 流程详解 #### HDFS 数据流程 HDFS数据流程是一个复杂的过程,涉及客户端、NameNode (NN) 和 DataNode (DN),具体如下: 1. **客户端发起请求** 客户端通过 API 向 NameNode 发起入文件的请求。NameNode 验证客户端是否有权限,并检查目标文件是否存在。如果验证失败,则返回错误;否则继续处理。 2. **文件切片** 文件被分割成固定大小的块(默认为 128MB),这些块将作为基本单位存储在分布式环境中[^5]。 3. **获取存储位置** 对于每一个块,客户端再次向 NameNode 请求可用的 DataNode 列表。NameNode 基于副本机制、负载均衡原则以及机架感知策略决定存储位置[^5]。 4. **创建传输管道** 客户端根据获得的 DataNode 列表顺序连接第一个 DataNode 并建立传输通道。随后依次与其他节点建立链路,最终形成一条完整的传输管道[^5]。 5. **数据流与确认机制** 数据按照 `客户端 -> DN1 -> DN2 -> DN3` 的方式逐级传递至各副本所在的 DataNode 上。与此同时,每一步都伴随着反向应答机制 (`ACK`) 来确保数据完整性。只有当所有接收方均反馈成功后,当前阶段才算完成。 6. **重复以上步骤直到结束** 当前块完成后,回到第三步重新申请下一个块的目标地址,直至整个文件全部上传完毕为止。 --- #### HDFS 数据流程 相比操作而言,HDFS过程相对简单一些,但仍需经历若干重要环节: 1. **定位 Block 地址** 客户端先联系 NameNode 获取所需文件对应的 block 元数据信息及其分布情况。此时,NameNode 按照一定的优先级排序提供候选副本列表给客户端选择最合适的源进行取[^4]。 2. **直连 DataNode 下载数据** 得知确切的位置之后,客户端直接跳过中间代理而同选定的那个或者那些具体的 DataNodes 展开通信以取得实际的内容片段。 3. **校验数据一致性** 在从某个特定 DataNode 收到一部分资料的同时也会对其进行哈希值匹配之类的检验动作来保障所得到的东西确实无误。 4. **拼接重组原始文件** 将零散下来的各个部分依照原先设定好的次序组装起来还原成为最初的完整文档形式呈现出来供使用者查阅利用[^4]。 --- ```python # Python 示例:模拟简单的 HDFS 入逻辑 def hdfs_write(file_data, chunk_size=128 * 1024 * 1024): blocks = [] # Step 1: Split file into chunks for i in range(0, len(file_data), chunk_size): blocks.append(file_data[i:i + chunk_size]) # Simulate interaction with Namenode and Datanodes namenode_response = get_namenode_storage_locations(len(blocks)) for idx, block in enumerate(blocks): datanode_list = namenode_response[idx] pipeline = establish_pipeline(datanode_list) send_block_via_pipeline(block, pipeline) def get_namenode_storage_locations(num_blocks): """Simulates querying the Namenode.""" import random nodes = ['node1', 'node2', 'node3'] return [[random.choice(nodes)]*replica_factor for _ in range(num_blocks)] def establish_pipeline(node_list): """Establishes a data transfer pipeline between client and datanodes.""" pass def send_block_via_pipeline(block, pipeline): """Sends one block through established pipeline.""" pass ``` --- #### 关键特性说明 - **机架感知** HDFS 使用机架感知算法优化副本放置策略,在减少跨机架流量的同时提高系统的可靠性和性能[^1]。 - **低延迟限制** HDFS 设计初衷并非针对实时场景下的快速响应需求,因此它并不擅长处理毫秒级别内的查询任务[^2]。 - **小文件问题** 大量的小型文件会对 NameNode 构成沉重负担,因为每个文件都需要单独占据其内存资源的一部分[^2]。 - **单模型** 单一时间窗口内仅允许一位用户对某份材料实施追加编辑行为,而不支持任意位置上的自由更改活动。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值