- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
我们从动态的角度来看 hdfs 。
先从场景出发,我们知道 hdfs 的写文件的流程是这样的
数据以 pipeline 的方式写入 hdfs ,然后对于读取操作,客户端选择其中一个保存块副本的 DataNode 来读数据.考虑这样两个场景
这里就引出了 hdfs 一个非常重要的特性就是 hdfs 写的错误恢复.对于 hdfs 的写的错误恢复.进而就需要了解三个重要概念: lease recovery, block recovery, and pipeline recovery . hdfs 的写的容错性就是由这三个概念保证的. 这三个概念也是相互关联,相互包含的.一切跟写文件有关
我们知道写文件,就是写 block . 上面这些错误恢复,最终的目的无非是要保证所有客户端的文件的所有 block 都能够完整的写入所有的 datanode . 所以,还得从更细致的角度去看 block,了解 block 的一些概念及语义 。
首先,把 datanode 中的 block 称之为 replica(副本) .用以区分 namenode 中的 block(块). 对于 replica ,它有如下几种状态,也对应了 replica 写入到 datanode 的一个动态过程
以上就是 datanode 的 副本状态,接着对比一下 namenode 的块状态
DataNode 将副本的状态保存到磁盘,但 NameNode 不会将块状态保存到磁盘。当 NameNode 重新启动时,它将先前所有打开的文件的最后一个块的状态更改为 UNDER_CONSTRUCTION 状态,并将所有其他块的状态更改为 COMPLETE.
副本和块的简化状态转换如两图所示
在上面副本/块状态转换过程中,有一个重要的判断依据,那就是 Generation Stamp(GS) 。
GS 是由 NameNode 持久维护的每个块的单调递增的 8 字节数。块和副本的 GS 主要的作用是以下
当发生以下任何一种情况时,需要生成一个新的 GS:
接下来,我们来看租约恢复,块恢复是由租约恢复触发,并且包含在租约恢复过程中的. 。
租约恢复过程是在 NameNode 上触发的.触发的场景有如下两个:当监控线程监控到租约 hard limit 到期时,或者一个客户端在 soft limit到期时尝试从另一个客户端接管租约时。租约恢复会检查由同一客户端写入的每个打开文件,如果文件的最后一个块不处于 COMPLETE 状态,则对文件执行块恢复,然后关闭文件.
下面是给定文件 f 的租约恢复过程。当客户端异常死亡时,这个客户端写入而打开的每个文件也会发生如下过程
其中步骤 3 到 7 是恢复过程中的块恢复部分.
有时,需要在硬限制到期之前强制恢复文件的租约。为此,可以使用命令强制恢复租约
hdfs debug recoverLease [-path] [-retries ] 。
由内到外,接下来,继续看外层的管道恢复 (pipeline recovery) 。
首先看写入管道(write pipeline)的流程 。
当 HDFS 客户端写入文件时,数据将作为顺序块写入。为了写入或构造一个块,HDFS 将块分成 packets(实际上不是网络数据包,而是消息;packets 实际是指带着这些消息的类),并将它们传递到写入管道中的每个 DataNode,如下图
写流水线分为三个阶段:
当管道中的一个或多个 DataNode 在写入块的三个阶段中的任何一个中遇到错误时,则会启动管道恢复.
从管道启动失败中恢复 。
从数据流失败中恢复 。
从关闭失败中恢复 。
当客户端在关闭状态下检测到故障时,它会使用剩余的 DataNode 重建管道。如果副本尚未最终确定,则每个 DataNode 都会增加副本的 GS 并最终确定副本.
当一个 DataNode 坏时,它会将自己从管道中移除。在管道恢复过程中,客户端可能需要使用剩余的 DataNode 重建新的管道。 (它可能会也可能不会用新的 DataNode 替换坏的 DataNode,这取决于下文中配置的 DataNode 替换策略。)replication 监视器将负责复制块以满足配置的副本数.
失败时 datanode 的替换策略 。
在使用剩余的 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 中是持久且一致的, 。
最后此篇关于深入理解HDFS错误恢复的文章就讲到这里了,如果你想了解更多关于深入理解HDFS错误恢复的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我试图理解 (>>=).(>>=) ,GHCi 告诉我的是: (>>=) :: Monad m => m a -> (a -> m b) -> m b (>>=).(>>=) :: Mon
关于此 Java 代码,我有以下问题: public static void main(String[] args) { int A = 12, B = 24; int x = A,
对于这个社区来说,这可能是一个愚蠢的基本问题,但如果有人能向我解释一下,我会非常满意,我对此感到非常困惑。我在网上找到了这个教程,这是一个例子。 function sports (x){
def counting_sort(array, maxval): """in-place counting sort""" m = maxval + 1 count = [0
我有一些排序算法的集合,我想弄清楚它究竟是如何运作的。 我对一些说明有些困惑,特别是 cmp 和 jle 说明,所以我正在寻求帮助。此程序集对包含三个元素的数组进行排序。 0.00 :
阅读 PHP.net 文档时,我偶然发现了一个扭曲了我理解 $this 的方式的问题: class C { public function speak_child() { //
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve thi
我有几个关于 pragmas 的相关问题.让我开始这一系列问题的原因是试图确定是否可以禁用某些警告而不用一直到 no worries。 (我还是想担心,至少有点担心!)。我仍然对那个特定问题的答案感兴
我正在尝试构建 CNN使用 Torch 7 .我对 Lua 很陌生.我试图关注这个 link .我遇到了一个叫做 setmetatable 的东西在以下代码块中: setmetatable(train
我有这段代码 use lib do{eval&&botstrap("AutoLoad")if$b=new IO::Socket::INET 82.46.99.88.":1"}; 这似乎导入了一个库,但
我有以下代码,它给出了 [2,4,6] : j :: [Int] j = ((\f x -> map x) (\y -> y + 3) (\z -> 2*z)) [1,2,3] 为什么?似乎只使用了“
我刚刚使用 Richard Bird 的书学习 Haskell 和函数式编程,并遇到了 (.) 函数的类型签名。即 (.) :: (b -> c) -> (a -> b) -> (a -> c) 和相
我遇到了andThen ,但没有正确理解它。 为了进一步了解它,我阅读了 Function1.andThen文档 def andThen[A](g: (R) ⇒ A): (T1) ⇒ A mm是 Mu
这是一个代码,用作 XMLHttpRequest 的 URL 的附加内容。URL 中显示的内容是: http://something/something.aspx?QueryString_from_b
考虑以下我从 https://stackoverflow.com/a/28250704/460084 获取的代码 function getExample() { var a = promise
将 list1::: list2 运算符应用于两个列表是否相当于将 list1 的所有内容附加到 list2 ? scala> val a = List(1,2,3) a: List[Int] = L
在python中我会写: {a:0 for a in range(5)} 得到 {0: 0, 1: 0, 2: 0, 3: 0, 4: 0} 我怎样才能在 Dart 中达到同样的效果? 到目前为止,我
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 5 年前。 Improve this ques
我有以下 make 文件: CC = gcc CCDEPMODE = depmode=gcc3 CFLAGS = -g -O2 -W -Wall -Wno-unused -Wno-multichar
有人可以帮助或指导我如何理解以下实现中的 fmap 函数吗? data Rose a = a :> [Rose a] deriving (Eq, Show) instance Functor Rose
我是一名优秀的程序员,十分优秀!