深入理解HDFS 错误恢复

news/2024/10/9 14:02:37/文章来源:https://www.cnblogs.com/hdpdriver/p/18454086

我们从动态的角度来看 hdfs

先从场景出发,我们知道 hdfs 的写文件的流程是这样的:

数据以 pipeline 的方式写入 hdfs ,然后对于读取操作,客户端选择其中一个保存块副本的 DataNode 来读数据.考虑这样两个场景:

  • hbase rs 在写 wal log 的时候.如果一个 rs 挂了.那么这个 rs 会转移并且通过读取 wal log 来恢复之前的状态.如果这个rs 挂的时候 ,写 wal log 的 pipeline 没有完成,那么必然这份 wal log 数据在不同的dn 上是存在差异的. 那么 hdfs 是如何保证 rs 转移后能够恢复到正确的状态?
  • 流计算写入hdfs ,如果中间 datanode 挂了.hdfs 是如何保证这个流计算程序不抛出错误,并持续运行下去的?

这里就引出了 hdfs 一个非常重要的特性就是 hdfs 写的错误恢复.对于 hdfs 的写的错误恢复.进而就需要了解三个重要概念: lease recovery, block recovery, and pipeline recovery . hdfs 的写的容错性就是由这三个概念保证的. 这三个概念也是相互关联,相互包含的.一切跟写文件有关:

  • 租约恢复 在客户端可以写入 HDFS 文件之前,它必须获得租约,这本质上是一个锁。如果客户端希望继续写,则必须在约定的时间段内续租。如果租约没有明确更新或持有它的客户端死亡了,那么它就会过期。发生这种情况时,HDFS 将代表客户端关闭文件并释放租约,以便其他客户端可以写入该文件。这个过程称为租约恢复。
  • 块恢复 如果正在写入的文件的最后一个块没有传递到管道中的所有 DataNode,那么当发生租约恢复时,写入不同节点的数据量可能会不同。在租约恢复导致文件关闭之前,需要一个过程来确保最后一个块的所有副本具有相同的长度.此过程称为块恢复。块恢复仅在租约恢复过程中触发,并且在租约恢复中仅在文件的最后一个块不处于 COMPLETE 状态时才触发块恢复。
  • 管道恢复 在写入管道操作期间,管道中的某些 DataNode 可能会失败。发生这种情况时,底层的写操作不能只是失败。相反,HDFS 将尝试从错误中恢复,以允许管道继续运行并且客户端继续写入文件。从管道错误中恢复的机制称为管道恢复。

我们知道写文件,就是写 block . 上面这些错误恢复,最终的目的无非是要保证所有客户端的文件的所有 block 都能够完整的写入所有的 datanode . 所以,还得从更细致的角度去看 block,了解 block 的一些概念及语义

首先,把 datanode 中的 block 称之为 replica(副本) .用以区分 namenode 中的 block(块). 对于 replica ,它有如下几种状态,也对应了 replica 写入到 datanode 的一个动态过程:

  • FINALIZED 当副本处于此状态时,对副本的写入完成并且副本中的数据被“冻结”(长度已确定),除非重新打开副本以进行追加。具有相同 generation stamp 的块的所有最终副本(称为 GS)应该具有相同的数据。最终副本的 GS 可能会因恢复发生而增加。
  • RBW (Replica Being Written) 这是正在写入的任何副本的状态,无论文件是为写入而创建的,还是为追加而重新打开的。 RBW 副本始终打开文件的一个块。数据仍在往副本里面写,尚未最终确定。 RBW 副本的数据(不一定是所有)对读取客户端可见。如果发生任何故障,将尝试将数据保存在 RBW 副本中。
  • RWR (Replica Waiting to be Recovered) 如果一个 DataNode 死掉并重新启动,它的所有 RBW 副本都将更改为 RWR 状态。 RWR 副本要么过时并因此被丢弃,要么将参与租约恢复中的块恢复。
  • RUR (Replica Under Recovery) 非 TEMPORARY 副本在参与租约恢复时将更改为 RUR 状态。
  • TEMPORARY 临时副本,用于块复制,由 replication monitor 或cluster balancer 来发起。它类似于 RBW 副本,只是它的数据对所有读取器客户端都是不可见的。如果块复制失败,将删除一个 TEMPORARY 副本。

以上就是 datanode 的 副本状态,接着对比一下 namenode 的块状态:

  • UNDER_CONSTRUCTION 这是写入时的状态。 UNDER_CONSTRUCTION 块是打开文件的最后一个块;它的长度和 GS 仍然是可变的,并且它的数据(不一定是全部)对读者是可见的。 NameNode 中的 UNDER_CONSTRUCTION 块会跟踪管道中的合法 RBW 及 RWR 副本的位置。
  • UNDER_RECOVERY 如果一个文件的最后一个块在相应客户端的租约到期时处于 UNDER_CONSTRUCTION 状态,那么就会开始块恢复,同时它将变为 UNDER_RECOVERY 状态。
  • COMMITTED COMMITTED 意味着一个块的数据和 GS 不再可变(除非它被重新打开用以追加, 并且此时上报上来的有相同 GS/长度的 FINALIZED 副本的 DataNode 数要少于设定的最小副本数。为了服务读取请求,COMMITTED 块必须跟踪 RBW 副本的位置、GS 及其 FINALIZED 副本的长度。当客户端要求 NameNode 向文件添加新的块或关闭文件时,UNDER_CONSTRUCTION 块将更改为 COMMITTED。如果最后一个或倒数第二个块处于 COMMITTED 状态,则无法关闭文件,客户端必须进行重试。
  • COMPLETE 当 NameNode 检测到 匹配 GS/长度要求的 FINALIZED 副本数达到最小副本数的要求时,COMMITTED 块更改为 COMPLETE。只有当文件的所有块都变为 COMPLETE 时才能关闭文件。一个块可能会被强制进入 COMPLETE 状态,即使它没有最小的复制副本数 . 例如,当客户端请求一个新块时,前一个块尚未完成这种情况.

DataNode 将副本的状态保存到磁盘,但 NameNode 不会将块状态保存到磁盘。当 NameNode 重新启动时,它将先前所有打开的文件的最后一个块的状态更改为 UNDER_CONSTRUCTION 状态,并将所有其他块的状态更改为 COMPLETE。

副本和块的简化状态转换如两图所示:

image

image

在上面副本/块状态转换过程中,有一个重要的判断依据,那就是 Generation Stamp(GS)

GS 是由 NameNode 持久维护的每个块的单调递增的 8 字节数。块和副本的 GS 主要的作用是以下:

  • 检测块的陈旧副本:即,当副本 GS 比块 GS 旧时,例如,在副本中以某种方式跳过 append 操作时,可能会发生这种情况。
  • 检测 DataNode 上的过期副本,比如 datanode 死了很长时间后重新加入集群。

当发生以下任何一种情况时,需要生成一个新的 GS:

  • 创建了一个新文件
  • 客户端打开现有文件以进行 append 或 truncate
  • 客户端在向 DataNode(s) 写入数据时遇到错误并请求新的 GS
  • NameNode 启动文件的租约恢复

接下来,我们来看租约恢复,块恢复是由租约恢复触发,并且包含在租约恢复过程中的.

租约恢复过程是在 NameNode 上触发的.触发的场景有如下两个:当监控线程监控到租约 hard limit 到期时,或者一个客户端在 soft limit到期时尝试从另一个客户端接管租约时。租约恢复会检查由同一客户端写入的每个打开文件,如果文件的最后一个块不处于 COMPLETE 状态,则对文件执行块恢复,然后关闭文件。

下面是给定文件 f 的租约恢复过程。当客户端异常死亡时,这个客户端写入而打开的每个文件也会发生如下过程:

  1. 得到 包含 f 的最后一个块的 DataNode。
  2. 将其中一个 DataNode 指定为主 DataNode p。
  3. p 从 NameNode 获取新的 GS 标记。
  4. p 从每个 DataNode 获取这个块的信息。
  5. p 计算得到这个块的最小长度。
  6. p 更新具有合法 GS 标记的 DataNode 的块, 让其更新为新的 GS 标记和最小块的长度。
  7. p 通知 NameNode 更新的结果。
  8. NameNode 更新 BlockInfo。
  9. NameNode 删除 f 的租约(其他写入者现在可以获得写入 f 的租约)。
  10. NameNode 向 edit log 提交更改。

其中步骤 3 到 7 是恢复过程中的块恢复部分。

有时,需要在硬限制到期之前强制恢复文件的租约。为此,可以使用命令强制恢复租约:

hdfs debug recoverLease [-path] [-retries ]

由内到外,接下来,继续看外层的管道恢复 (pipeline recovery)

首先看写入管道(write pipeline)的流程

当 HDFS 客户端写入文件时,数据将作为顺序块写入。为了写入或构造一个块,HDFS 将块分成 packets(实际上不是网络数据包,而是消息;packets 实际是指带着这些消息的类),并将它们传递到写入管道中的每个 DataNode,如下图:

image

写流水线分为三个阶段:

  1. 管道启动。客户端沿管道发送 Write_Block 请求,最后一个 DataNode 发送回确认。收到确认后,管道准备好写入。
  2. 数据流。数据通过管道以数据包的形式发送。客户端缓存数据,直到一个packet 数据包被填满,然后将数据包发送到管道。如果客户端调用 hflush(),那么即使一个数据包没有满,它仍然会被发送到管道并且必须得收到前一个数据包 hflush() 的确认。
  3. 关闭(finalize 副本并关闭管道)。客户端等待直到所有数据包都被确认,然后发送关闭请求。管道中的所有 DataNode 将相应的副本更改为 FINALIZED 状态并报告回 NameNode。如果配置的最小副本数量的 DataNode 报告了其相应副本的 FINALIZED 状态,则 NameNode 然后将块的状态更改为 COMPLETE。

当管道中的一个或多个 DataNode 在写入块的三个阶段中的任何一个中遇到错误时,则会启动管道恢复。

从管道启动失败中恢复

  1. 如果管道是为一个新块创建的,客户端会放弃该块并向 NameNode 请求一个新块和一个新的 DataNode 列表。管道为新块重新初始化。
  2. 如果创建管道 append 块操作,则客户端使用剩余的 DataNode 重建管道并增加块的 GS 标记。

从数据流失败中恢复

  1. 当管道中的 DataNode 检测到错误(例如,checksum 错误或写入磁盘失败)时,该 DataNode 通过关闭所有 TCP/IP 连接将自己从管道中取出。
  2. 接着客户端检测到故障,它会停止向管道发送数据,并使用剩余的 DataNode 重建新的管道。接着,该块的所有副本都被更新到一个新的 GS。
  3. 客户端使用这个新的 GS 继续发送数据包。如果发送的数据已经被某些 DataNode 接收了,他们会忽略该数据包并往管道下游传递.

从关闭失败中恢复

当客户端在关闭状态下检测到故障时,它会使用剩余的 DataNode 重建管道。如果副本尚未最终确定,则每个 DataNode 都会增加副本的 GS 并最终确定副本。

当一个 DataNode 坏时,它会将自己从管道中移除。在管道恢复过程中,客户端可能需要使用剩余的 DataNode 重建新的管道。 (它可能会也可能不会用新的 DataNode 替换坏的 DataNode,这取决于下文中配置的 DataNode 替换策略。)replication 监视器将负责复制块以满足配置的副本数。

失败时 datanode 的替换策略

在使用剩余的 DataNode 设置恢复管道时,关于是否添加额外的 DataNode 以替换坏的 DataNode 有四种可配置策略:

  1. DISABLE:禁用 DataNode 替换并在dn 上抛出错误。
  2. NEVER:当管道发生故障时,永远不替换 DataNode(通常不建议)。
  3. DEFAULT:根据以下条件替换:
    a. 假设 r 为配置的副本数。
    b. 设 n 为现已有副本数据的节点的数量。
    c. 仅当 r >= 3 且满足下面任一条件才添加新的 DataNode
    • flour(r/2) >= n
    • r > n 并且块是被 hflushed/appended
  4. ALWAYS:当现有的 DataNode 失败时,总是添加一个新的 DataNode。如果无法替换 DataNode,则会失败。

替换策略的开关为 dfs.client.block.write.replace-datanode-on-failure.enable ,值为 false 时,禁用所有策略.

值为 true,打开替换策略,此时通过配置 dfs.client.block.write.replace-datanode-on-failure.policy 来指定策略,默认策略为 default

使用 default 或 always 时,如果管道中只有一个 DataNode 成功,则错误恢复永远不会成功,客户端将无法执行写入直到超时。这种情况可以配置如下属性来解决此问题:dfs.client.block.write.replace-datanode-on-failure.best-effort
默认为false。使用默认设置,客户端将继续尝试,直到满足指定的策略。当该属性设置为 true 时,即使不能满足指定的策略(例如管道中只有一个成功的 DataNode,小于策略要求),仍然允许客户端继续来写。

租约恢复、块恢复和管道恢复对于 HDFS 容错至关重要。它们共同保证了即使存在网络和节点故障的情况下,写入到 HDFS 中是持久且一致的,

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/810519.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过MySQL Workbench 将 SQL Server 迁移到GreatSQL

通过MySQL Workbench 将 SQL Server 迁移到GreatSQL 一、概述 MySQL Workbench 提供了可以将Microsoft SQL Server的表结构和数据迁移到 GreatSQL 的功能,此次将通过MySQL Workbench将SQL Server的数据迁移到GreatSQL。 本文章只是简单演示一下单张表的迁移,如果在项目中使用…

我的第一个博客

我的第一个博客我的第一个博客 CBV添加装饰器的三种方式 # CBV添加装饰器 from django.views import View # 需要先导入method_decorator from django.utils.decorators import method_decorator # CBV中django不建议直接给类的方法加装饰器# @method_decorator(login_auth, na…

我店生活模式功能分析

一、平台概述 “我店”由上海我店科技网络有限公司创立于2021年8月,作为一个本地生活服务平台,它致力于响应国家的环保政策,并运用绿色积分来促进经济活动,帮助实体店铺吸引客流。面对实体商业的挑战,“我店”平台凭借其独特的商业模式,为商户与顾客提供了新的合作与发展…

AI即服务平台的优势

AI即服务平台以其降低成本、加速创新、提升效率、增强安全性及促进普惠化等多方面的优势,正在深刻改变企业运营模式和市场竞争格局。当今,企业为了提升竞争力、优化运营流程、增强用户体验,纷纷探索AI技术的应用。然而,AI技术的复杂性和高昂的研发成本往往成为中小企业和初…

易基因: Nat Commun:中南大学曾朝阳/熊炜/龚朝建团队利用ChIP-seq等揭示头颈鳞癌免疫逃逸机制|项目文章

大家好,这里是专注表观组学十余年,领跑多组学科研服务的易基因。 免疫逃逸是癌症进展的关键里程碑,是肿瘤免疫治疗的理论基础。头颈部鳞状细胞癌((head and neck squamous cell carcinoma, HNSCC))是全球最常见的恶性肿瘤之一,传统治疗选择包括手术切除、放疗和化疗。最近…

20222407 2024-2025-1《网络与系统攻防技术》实验一实验报告

1.实验内容 1.1本周学习内容 1.1.1缓冲区溢出的定义和原因 定义:写入缓冲区的数据量超过该缓冲区能容纳的最大限度,造成溢出的数据改写了与该缓冲区相邻的原始数据的情形。 原因:(直接)由于代码语言的设计问题、程序员的安全意识问题,程序没有严格的内存越界检查;(根本…

揭秘!尤雨溪成立的VoidZero如何改变前端世界

Vue和Vite之父尤雨溪宣布成立公司 VoidZero,目前已经融资3200万。这篇文章欧阳将带你了解VoidZero是如何改变javascript的世界!前言 Vue和Vite之父尤雨溪宣布成立公司 VoidZero,目前已经融资3200万。这篇文章欧阳将带你了解VoidZero是如何改变javascript的世界! 关注公众号…

20222314 2024-2025-1 《网络与系统攻防技术》实验一实验报告

网络攻防实验报告姓名:陈振烨学号:20222314实验日期:2024/09/29 — 2024/10/09实验名称:缓冲区溢出和shellcode 指导教师:王志强实验要求:1.掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(0.5分)2.掌握反汇编与十六进制编程器 (0.5分)3.能正确修改机器指令改变程序执行流…

最基本必会的增删改查

本文详细介绍了SQL中的四大基本操作:INSERT用于数据插入,DELETE用于数据删除,UPDATE用于更新数据,SELECT用于查询数据。文中还涵盖了WHERE条件查询,LIKE用于模糊查询,ORDERBY进行排序,LIMIT用于分页查询,以及聚合函数如COUNT(),SUM(),AVG()和MAX()。这些是数据库管理的…

macos安装gemini

macos运行步骤 1.下载gemini 2.给gemini权限sh-3.2# chmod +x gemini-darwin-amd64sh-3.2# ./gemini-darwin-amd64 这个时候需要在mac的隐私设置出进行允许 启动台--》系统偏好--》 再次sudo执行少侠,我看你气度不凡天赋异禀,骨骼精奇,这么帅,来了就帮推荐一把吧 我的最近更…

销售团队管理全面指南:从结构到流程

“除非卖出东西,否则就不能叫生意。” ——Thomas Watson的这段话表明,无论您经营哪个行业,销售都应该成为企业最重要的部分。您可能拥有出色的产品,但真正重要的是如何销售它。为此,您需要一支出色的销售团队,并让他们在一个良好的管理体系(流程体系)下发挥作用。 一、…

SonarQube的安装与使用

SonarQube的安装与使用一、说明: SonarQube 7.8以上只支持jdk 11版本并且不支持mysql数据库 本次安装为Windows环境 版本信息如下: 1、sonarqube — 7.7 2、Sonar-scanner-cli —4.5.0 3、Postgre —10.1二、解压附件中的sonarqube-7.7.zip,sonar-sca…