Armin
迷茫的话 TRY AGAIN 多少次都能重新再来

在Hadoop 2.0 中HDFS 引入了 append 和 hflush 功能之后,

需要为 数据块增加新的状态 来尽最大可能的保证数据的一致性。

 参阅文档:

https://files.cnblogs.com/inuyasha1027/appendDesign3.pdf

http://stackoverflow.com/questions/10121705/differences-between-hflush-hsync-apis-in-hdfs

 

为了更好地区分 位于DataNode上面的 block 与位于NameNode上面的 block,

我们将位于DataNode上面的 block 称之为 replica,

位于NameNode上面的 block 称之为 block。

 

在 append 和 hflush  功能增加之前, 在DataNode上面的 replica 仅处于

1.finalized 2.temporary 这两种状态。

 

当一个 replica 首次被创建的时候, 它在Datanode上面的状态是 temporary的。

当接收到来自于客户端的 close 命令的时候, 也就是不会向 该 replica 中写入任何数据的时候,

这个 块(replica)的状态将会从 temporary 状态转换 为 finalized状态。

 

对于处于temporary状态的replica (位于Datanode上的数据块)在Datanode重新启动的时候,

将会被从相关的路径中进行移除。 由于HDFS为处于 under-construction 状态的blocks

要尽最大努力提高它们的数据持久性,所以在 append 和 hflush 功能 被添加之前,这个是可以接受的。

("这个":指的是 在datanode restart 之后,将会把处于temporary状态的 replica全部删除,

但是,试想一下,增加 追加 (append) 功能之后,待 datanode重启之后,

就莫名其妙的把 处于temporary 状态的 replicas 给删除,会造成很多数据丢失的)

 

但是,在引入append 和 hflush 功能之后,这么做就行不通了。

因为 HDFS 需要为 处于 under-construction状态下的保存了在append 操作之前的 data 的blocks 

提供高保证的数据持久性 以及尽最大可能为hflush 中的 data提供 持久性。

所以与先前不同,需要改进的地方就是,即便是 Datanode 重新的启动,也要尽量保证 这些处于

temporary状态的 replicas 也是不会被 removed的 而是 被 preserved 的。

 

下面就介绍一下,在Datanode上面,在引入 append /hflush 功能之后,所新增的

replica的各种状态

 

1. Finalized:/完成状态

处于这种状态的 replica 有着固定不变的 bytes。 处于 finalized状态的 replica 是不允许

向其中写入数据的,除非对他执行appen操作 使其重新开启(reopened)。

处于finalized 状态的 block中的 data 和 meta data 数据是相互匹配的。

这个 replica 在不同地方的 冗余备份 和 该 replica 的 replica ID是相同的。

但是, 生成时间戳 并不是保持不变的。

 

2. Rbw(Replica Being Written to):/ 等待写入状态

一旦一个 replica 被创建 或是被追加(appended),

它就会转换为 rbw 状态。

处于 rbw 状态的replica 是允许 数据被写入的。

在文件系统中,一个文件 对应的是一个 INodeFile 实体, 而该INodeFIle实体中有一个LocatedBlock

的数组,该数组中存放的是 位于DataNode上面的所有 存储文件block的分布情况,

如果该文件正处于被追加状态的话,那么一定是向 该文件对应的INodeFile中的 LocatedBlock 中

的最后一个 block进行写入处理, 这样的话, 这个处于 最后一个 位置的block的状态 一定是

rbw状态的。 上面提到的block 实质上指的是 replica, 由于该文件没有被写完,所以文件长度未定,

该块 replica 的长度也是 未定的。

所以对于存放在 物理介质上的 块中的  data 和meta data 中的数据时不匹配的。

位于不同节点 拥有相同 ID 的 冗余 块 多多少少 与 该块中的数据 也是不一致的。

处于 rbw 状态下的replica 中的部分数据duireaders 是可见的。

为了防止任何错误的发生, 在rbw 状态下的 replica 中的数据 会尽量的被保留的。

 

3. Rwr (Replica waiting to be recovered):/ 等待恢复状态

如果一个Datanode 死掉 或是重新启动的话, 处于该datanode上面的所有 rbw 状态的 replicas

都会从 rbw 状态转换 为 rwr 状态。

Rwr 状态下的 replicas 不会出现在 任何 pipeline中, 因此 也不会接受任何新的写入数据。

对于处于Rwr 状态下的replicas 要么成为 过期数据,

要么参与一次 租约恢复操作(如果和datanode 建立 租约(lease)的client 同样挂掉的话) .

 

4. Rur (Replica Under Recovery ): /处于恢复状态

当一个 replica 开始恢复直到 租约到期的时候,该replica 将会转为 state 状态。

 

5. Temporary: 一个处于temporary状态的 replica 同样 也是 当该replica

是 under-construction 状态的时候, 但是有所不同的是:

rbw: 对应的是 client 向 Datanode中写操作而造成的 该replica 是 under-construction

而 temporary: 对应的是 datanode之间的冗余备份 或是 整个集群的负载均衡操作 造成的。

 

处于 temporary 状态的 replica 与 rbw 状态 的replica 中共享着很多的 属性,

但是还是有所不同

不同1.处于 temporary 状态的 replica 中的 数据对任何 reader 都是 不可见的。

不同2.处于temporary 状态的 replica 如果 创建失败 或是 该replica 所在的 datanode 重启的话,

该 replica 会被 删除,而 rbw 会从 rbw 状态转换为 rwr 状态即等待被 恢复状态。

 

上述就是,位于 datanode上面的block : replica 的几种状态。

 

 

在 DataNode的数据目中共有三个子目录:

1. current

在这个目录中 保留着 所有处于finalized状态的replicas

2.tmp

在这个目录中保留着 处于temporary状态的replicas,

3.rbw

在这个目录下 保留着 处于 rbw、rwr和rur 状态的replicas。

 

-----------------------------------------------------------------------

所以,在HDFS接收到来自DFS(client端)创建 replica 的消息, 创建一个replica之后,

该replica首先是被存放在rbw 目录下面的。

 

而当一个replica 首次被创建,是用于 datanodes 之间的冗余 备份 或是 负载均衡的目的的话,

这个replica 将会被 存放到tmp 目录下面。

 

一旦一个 replica 被完成之后,即 finalized ,它就会被移动 到 current 目录的下面了。

 

 ----------------------------after restart--------------------------------------------

当一个DataNode重新启动之后,位于tmp 目录下面的 replicas将会被删除;

而位于 rbw 目录下面的所有 replicas 将会 被转换为rwr状态;

而位于current 目录下面的 replicas 将会 被正常 加载 且 为 finalized 状态。

 

下图为 datanode 上面的 block(replica )的状态转换图:

 

 

posted on 2013-12-03 17:28  Armin  阅读(1616)  评论(0编辑  收藏  举报