HDFS写入过程中DataNode故障处理

在 HDFS 写数据的过程中,如果有一个 DataNode 挂掉,HDFS 的容错机制会被触发,确保数据写入最终成功且满足副本数要求。整个过程对客户端是透明的(客户端会感知到延迟或重试,但最终结果是一致的)。

以下是详细流程:

  1. 正常写入流程 (回忆):

    • 客户端向 NameNode 请求上传文件。
    • NameNode 验证权限和文件是否存在,然后为文件分配数据块(Block)和一组(默认3个)目标 DataNode(DN1, DN2, DN3),并将这些 DN 信息返回给客户端。
    • 客户端与这些 DN 建立流水线(Pipeline):通常客户端将数据先发给 DN1,DN1 接收一部分数据后立即转发给 DN2,DN2 同样接收一部分后转发给 DN3。数据是以数据包(Packet)为单位传输的。
    • 数据在 Pipeline 中传输的同时,每个 DN 会将接收到的数据包先写入本地磁盘的临时文件.blk_<id>_<genstamp>.tmp)中。
    • 当一个 Block 的所有数据包都传输完毕,每个 DN 会向 NameNode 汇报块信息,并确认给上游节点(DN3 确认给 DN2, DN2 确认给 DN1, DN1 确认给客户端)。
    • 客户端收到所有 DN 的最终确认(通过 DN1)后,通知 NameNode 文件写入完成(或关闭文件)。
    • NameNode 收到关闭请求后,将文件元数据(包含块及其副本位置)持久化到 EditLog 和 FsImage 中。此时,DN 上的临时文件会被重命名为最终的数据块文件。
  2. 写入过程中 DataNode 挂掉:

    • 故障检测:
      • Pipeline 内部: 上游 DN(例如 DN1 发给 DN2)或客户端(发给 DN1)在发送数据包后会等待下游的 ACK 确认。如果在超时时间内没有收到 ACK,或者网络连接直接断开,就会检测到故障。
      • NameNode 心跳: 所有活跃的 DataNode 会定期(默认 3 秒)向 NameNode 发送心跳。如果 NameNode 在预设的时间(默认 10 分钟 + 30 秒)内没有收到某个 DataNode 的心跳,就会将其标记为宕机(Dead)
    • Pipeline 关闭与恢复:
      • 检测到故障的节点(客户端或上游 DN)会关闭当前的 Pipeline
      • 客户端会收到一个 IOException 或其子类异常(如 IOException: Failed to replace a bad datanode...)。
      • 关键步骤: 客户端会联系 NameNode,报告发生故障的 Block ID 和故障的 DataNode (DN_failed)。
      • NameNode 会:
        • 将 DN_failed 标记为宕机(如果还没标记)。
        • 为这个 Block 重新分配一个新的、健康的 DataNode (DN_new) 来替代 DN_failed。NameNode 会从集群中选择一个负载较低、与已有副本(如 DN1 或 DN2)机架感知策略匹配良好的节点。
        • 将新的 DN 列表 (DN1, DN2, DN_new) 返回给客户端。
      • 建立新 Pipeline: 客户端使用新的 DN 列表 (DN1, DN2, DN_new) 建立一个新的 Pipeline。
      • 数据恢复:
        • 已有副本: DN1 和 DN2 上已经有该 Block 的部分数据(写入到了临时文件)。
        • 最小副本: HDFS 会计算当前 Block 在健康节点(DN1, DN2)上已确认的数据包的最小长度(Generation Stamp 和长度)。
        • 同步: 新的 Pipeline 建立后,客户端不会从头开始发送整个 Block。DN1(通常是 Pipeline 中的第一个健康节点)会将其临时文件中已确认的、达到最小长度的数据直接传输给 DN_new。这确保了 DN_new 能快速获得与其他健康副本一致的数据起点。
      • 继续写入: 客户端接着从上次成功写入的位置(即最小长度之后)开始,将剩余的数据包通过新的 Pipeline (DN1 -> DN2 -> DN_new) 发送出去。
      • 最终确认: 当 Block 的所有数据成功写入 DN1, DN2, DN_new 的临时文件并收到最终 ACK 后,客户端确认该 Block 写入成功。
    • 临时文件的处理:
      • 挂掉的 DN_failed 上的临时文件会一直保留(直到其磁盘被清理或该 DN 重启后自己清理)。
      • 当挂掉的 DN_failed 重新启动并加入集群后:
        • 它会向 NameNode 发送心跳和块报告。
        • NameNode 发现 DN_failed 上报告的 Block ID (比如 BlockX) 的副本信息。
        • NameNode 检查自己的元数据,发现 BlockX 在集群中已经存在足够(3个)的健康副本(在 DN1, DN2, DN_new 上),并且 DN_failed 上的副本(可能不完整)不是最新的(因为写入过程在它挂掉后继续了,Generation Stamp 可能不同)。
        • NameNode 会指令 DN_failed 删除这个过时的、不完整的 BlockX 副本(包括临时文件)。
        • 这样保证了集群中最终只有最新、完整的那 3 个副本。
  3. 关键点总结:

    • 容错透明性: HDFS 自动处理写入过程中的 DataNode 故障,客户端只需处理重试逻辑(通常 HDFS 客户端 SDK 内部已实现)。
    • 流水线恢复: 故障导致当前 Pipeline 关闭,客户端通过 NameNode 获取新的 DN 列表重建 Pipeline。
    • 最小副本同步: 新加入的 DN 会从现有健康副本同步已达成一致的最小长度数据,避免整个 Block 重传。
    • 断点续传: 客户端从故障点之后继续发送剩余数据。
    • 副本数保证: 最终写入成功的副本数一定满足配置要求(默认3)。
    • 过时副本清理: 宕机节点恢复后,其上未完成的写入(临时文件)会被识别为过时并被删除。
    • 性能影响: 故障处理和 Pipeline 重建会带来额外的延迟,但对最终一致性没有影响。

简单来说: 当写入 Pipeline 中的某个 DataNode 挂掉,HDFS 会踢掉坏节点,找一个新节点加入,让新节点从现有好节点那里“赶上”已经写好的部分数据,然后客户端接着从断掉的地方继续写剩下的数据。最终保证数据有足够的、完整的副本。坏节点上的“半成品”数据会在它恢复后被自动清理掉。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

走过冬季

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值