了解HDFS恢复过程(第1部分)【Understanding HDFS Recovery Processes】

转载https://clouderatemp.wpengine.com/blog/2015/03/understanding-hdfs-recovery-processes-part-1/

很好的文章,但是要翻墙转载给国内的伙伴,有问题请联系删除

在运行或转向可用于生产环境的Apache Hadoop时,掌握HDFS恢复过程非常重要。

HDFS的一项重要设计要求是确保连续正确的操作以支持生产部署。一个特别复杂的领域是在存在网络和节点故障的情况下确保向HDFS写入的正确性,其中租赁恢复,块恢复和管道恢复过程将发挥作用。了解何时以及为何调用这些恢复过程以及它们的操作,可以帮助用户以及开发人员了解其HDFS群集的结构。

在此博客文章中,您将深入了解这些恢复过程。我们将从快速介绍HDFS写入管道和这些恢复过程开始,解释块/副本状态和生成标记的重要概念,然后逐步完成每个恢复过程。最后,我们将列出一些相关问题,以解决并解决未解决问题。

这篇文章分为两个部分:第1部分将检查租约恢复和大块恢复的详细信息,第2部分将检查管道恢复的详细信息。有兴趣了解更多信息的读者应参考设计规范:Append,Hflush和Read,以获取实现细节。

背景

在HDFS中,文件分为多个块,并且文件访问遵循多读取器,单写入器的语义。为了满足容错要求,一个块的多个副本存储在不同的DataNode上。副本数称为复制因子。创建新文件块或打开现有文件进行追加时,HDFS写入操作将创建一个DataNodes管道来接收和存储副本。(复制因子通常确定管道中的DataNodes数量。)随后对该块的写入将通过管道(图1)。

图1. HDFS写管道

对于读取操作,客户端选择保存该块副本的DataNode之一,并请求从中进行数据传输。

以下是两个应用场景,重点介绍了对容错设计要求的需求:

  • HBase的区域服务器(RS)写入其WAL(预写日志),WAL是有助于防止数据丢失的HDFS文件。如果RS出现故障,将启动一个新的RS,它将通过读取WAL文件来重建前身RS的状态。如果在RS终止时写管道还没有完成,则管道中的不同DataNode可能不同步。HDFS必须确保从WAL文件中读取所有必要的数据,以重建正确的RS状态。
  • 当Flume客户端将数据流传输到HDFS文件时,即使管道中的某些DataNode发生故障或停止响应,它也必须能够连续写入。

租用恢复,块恢复和管道恢复在这种情况下起作用:

  • 在客户端可以写入HDFS文件之前,它必须获得租约,该租约本质上是一个锁。这样可以确保单写者的语义。如果客户希望继续写书,则必须在预定的时间内续签租约。如果未明确续订租约或持有租约的客户去世,则该租约将到期。发生这种情况时,HDFS将代表客户端关闭文件并释放租约,以便其他客户端可以写入该文件。此过程称为租约回收
  • 如果正在写入的文件的最后一块没有传播到管道中的所有DataNode,那么在发生租约恢复时,写入不同节点的数据量可能会有所不同。在租约恢复导致文件关闭之前,必须确保最后一个块的所有副本都具有相同的长度。此过程称为块恢复。块恢复仅在租用恢复过程中触发,而租用恢复仅在文件的最后一个块不处于COMPLETE状态(在后面的部分中定义)时才触发该块的块恢复。
  • 在写管道操作期间,管道中的某些DataNode可能会失败。发生这种情况时,基础的写操作就不会失败。而是,HDFS将尝试从错误中恢复,以允许管道继续运行,并使客户端继续写入文件。从管道错误中恢复的机制称为管道恢复

以下各节将更详细地说明这些过程。

块,副本及其状态

为了区分NameNode上下文中的块和DataNode上下文中的块,我们将前者称为,将后者称为副本

在数据管理部上下文中的副本可以是以下状态之一(见枚举ReplicaState在):org.apache.hadoop.hdfs.server.common.HdfsServerConstants.java

  • FINALIZED:当副本处于此状态时,对副本的写入完成,并且副本中的数据被“冻结”(长度已确定),除非重新打开副本以进行追加。具有相同世代标记(以下定义为GS)的块的所有最终副本应具有相同的数据。由于恢复,最终副本的GS可能会增加。
  • RBW(正在复制的副本):这是正在写入的任何副本的状态,无论文件是为写入而创建的,还是为附加而重新打开的。RBW副本始终是打开文件的最后一块。数据仍在写入副本中,并且尚未完成。读取器客户端可以看到RBW副本的数据(不一定是全部数据)。如果发生任何故障,将尝试将数据保留在RBW副本中。
  • RWR(正在等待恢复的副本):如果DataNode死亡并重新启动,则其所有RBW副本将更改为RWR状态。RWR复制副本将变得过时并因此被丢弃,或者将参与租约恢复。
  • RUR(正在恢复的副本):非临时副本在参与租约恢复时将变为RUR状态。
  • TEMPORARY:创建临时副本以进行块复制(通过复制监视器或群集平衡器)。它类似于RBW副本,不同之处在于其数据对于所有读取器客户端都是不可见的。如果块复制失败,则将删除TEMPORARY副本。

在名称节点上下文中的块可以是在一个以下状态(见枚举BlockUCState在):org.apache.hadoop.hdfs.server.common.HdfsServerConstants.java

  • UNDER_CONSTRUCTION:这是写入状态。UNDER_CONSTRUCTION块是打开文件的最后一块;它的长度和标记仍然可变,并且读者可以看到其数据(不一定是全部)。NameNode中的UNDER_CONSTRUCTION块跟踪写入管道(有效RBW副本的位置)及其RWR副本的位置。
  • UNDER_RECOVERY:如果相应客户端的租约到期时,文件的最后一个块处于UNDER_CONSTRUCTION状态,则在块恢复开始时它将变为UNDER_RECOVERY状态。
  • COMMITTED:COMMITTED意味着块的数据和生成标记不再可变(除非重新打开以追加),并且报告了GS / length相同的FINALIZED副本的DataNode的最小复制数量少于该数量。为了满足读取请求,COMMITTED块必须跟踪RBW复制副本的位置,GS及其最终复制副本的长度。客户端要求NameNode向文件添加新块或关闭文件时,UNDER_CONSTRUCTION块将更改为COMMITTED。如果最后一个或倒数第二个块处于COMMITTED状态,则无法关闭文件,客户端必须重试。
  • COMPLETE:当NameNode看到匹配GS / length的FINALIZED副本的最小复制数量时,COMMITTED块将更改为COMPLETE 。仅当文件的所有块都变为COMPLETE时,才能关闭文件。即使一个块没有最小的复制副本数,也可能将其强制为COMPLETE状态,例如,当客户端请求一个新块,而先前的块尚未完成时。

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

复制品和模块的简化状态转换图如图​​2和3所示。有关详细信息,请参见设计文档

图2:简化的副本状态转换

图3.简化的块状态转换

世代邮票

GS是由NameNode永久维护的每个块的单调递增8字节数。出于以下目的,引入了块和副本的GS(设计规范:HDFS追加和截断):

  • 检测块的陈旧副本:即,当副本GS早于块GS时,例如,在某种程度上跳过副本的追加操作时,可能会发生这种情况。
  • 在已失效很长时间的DataNode上检测过时的副本,然后重新加入群集。

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

  • 创建一个新文件
  • 客户端打开现有文件进行追加或截断
  • 客户端在将数据写入DataNode时遇到错误,并请求新的GS
  • NameNode启动文件的租约恢复

租赁恢复和块恢复

租赁经理

租约由NameNode的租约管理器管理。NameNode跟踪每个客户端已打开以供写入的文件。续订租约时,客户端不必枚举已打开的每个文件以进行写入。取而代之的是,它会定期向NameNode发送一个请求,以立即续订所有请求。(请求是一条消息,它是HDFS客户端和NameNode之间的RPC协议。)org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtos.RenewLeaseResponseProto

每个NameNode管理一个HDFS命名空间,每个命名空间都有一个租约管理器来管理与该命名空间关联的所有客户端租约。联合HDFS群集可能具有多个名称空间,每个名称空间都有自己的租约管理器。

租约管理者在到期时间上维持软限制(1分钟)和硬限制(1小时)(这些限制当前不可配置),并且由租约管理者维护的所有租约都遵守相同的软限制和硬限制。在软限制到期之前,持有文件租约的客户端具有对该文件的独占写访问权限。如果软限制到期并且客户端尚未续订租约或关闭文件(关闭文件时将释放文件的租约),则另一个客户端可以强制接管租约。如果硬性限制到期并且客户端尚未续订租约,则HDFS会假定客户端已退出,并将代表客户端自动关闭文件,从而恢复租约。

一个客户端持有文件租赁的事实并不能阻止其他客户端读取该文件,即使一个客户端正在写入文件,文件也可能具有许多并发读取器。

租赁管理器支持的操作包括:

  • 为客户端和路径添加租约(如果客户端已经具有租约,则将路径添加到租约,否则,将创建新的租约并将路径添加到租约)
  • 删除客户端和路径的租约(如果这是租约中的最后一条路径,则会删除租约)
  • 检查软限制和/或硬限制是否已过期,以及
  • 为给定客户续订租约。

租约管理器具有一个监视线程,该线程定期(当前每2秒一次)检查任何租约是否具有过期的硬限制,如果是,它将触发这些租约中文件的租约恢复过程。

HDFS客户端通过维护用户列表并在每个NameNode上为每个用户运行一个线程的类来更新其租约。该线程定期使用NameNode进行检入,并在租约期结束一半时续订所有客户端的租约。org.apache.hadoop.hdfs.LeaseRenewer.LeaseRenewer

(注意:HDFS客户端仅与一个NameNode关联;请参阅的构造函数)。如果同一应用程序要访问联合集群中不同NameNodes管理的不同文件,则需要为每个NameNode创建一个客户端。)org.apache.hadoop.hdfs.DFSClient

租赁回收流程

租约恢复过程在NameNode上触发,以通过硬限制到期后的监视线程,或当软限制到期时客户端尝试从另一客户端接管租约时,为给定客户端恢复租约。它检查由同一客户端打开的每个文件以供写入,如果文件的最后一个块不处于COMPLETE状态,则对该文件执行块恢复,然后关闭该文件。仅在恢复文件的租约时才触发文件的块恢复

以下是给定文件f的租约恢复算法。客户端死亡时,将相同的算法应用于客户端打开以进行写入的每个文件。

  1. 获取包含f的最后一块的DataNode。
  2. 将其中一个DataNode分配为主要DataNode p。
  3. p从NameNode获得新一代的邮票。
  4. p从每个DataNode获取块信息。
  5. p计算最小块长度。
  6. p 使用新生成的标记和最小的块长度更新具有有效生成标记的DataNodes
  7. p确认NameNode更新结果。
  8. NameNode更新BlockInfo。
  9. NameNode删除f的租约(其他编写者现在可以获取写给f的租约)。
  10. NameNode提交更改以编辑日志。

步骤3至7是算法的块恢复部分。如果文件需要块恢复,则NameNode会选择一个具有该文件最后一个块的副本的主DataNode,并告诉该DataNode与其他DataNode协调该块恢复工作。完成后,该DataNode将报告回NameNode。然后,NameNode更新此块的内部状态,删除租约,并将更改提交给编辑日志。

有时,管理员需要在硬限制到期之前强行恢复文件的租约。有一个CLI调试命令(从Hadoop版本2.7和CDH 5.3开始)可用于此目的:

hdfs debug recoverLease [-path] [-retries ]

结论

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

现在,您应该更好地了解何时以及为何调用租约恢复和块恢复以及它们的作用。在第2部分中,我们将探讨管道恢复。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章