文章目录
- 前言
- HDFS NameNode端针对Rolling Upgrade的调整
- HDFS DataNode端针对Rolling Upgrade的调整
- 引用
前言
我们知道HDFS Rolling Upgrade功能在几年前比较早的时间早已实现,但是我们往往只注意怎么去做HDFS Rolling Upgrade这个事情本身,但是对于HDFS如何实现Rolling Upgrade这个功能可能了解的会比较少。本文笔者来聊聊其中部分要点的设计实现,为了做到Rolling Upgrade的快速和安全性,社区在这块实现上还是花了一些功夫的。本文主要基于HDFS Rolling Upgrade社区JIRA HDFS-5535:Umbrella jira for improved HDFS rolling upgrades来展开内容进行阐述。
HDFS NameNode端针对Rolling Upgrade的调整
HDFS针对Rolling Upgrade的实现,在NameNode和DataNode两边都进行了相关的调整实现。首先我们来看NameNode做了哪些模块的调整。
第一个,NameNode在pre-upgrade, upgrade in-progress, finalized, downgrade/rollback这些期间
元数据文件的一个状态处理,包括FsImage文件以及editlog文件。当我们执行Rolling Upgrade的rollback操作时,NN是可以支持撤销rolling upgrade时的那个transaction后发生的所有transaction。简单来说,它会忽略掉升级过程中执行过的那些事务transaction。
第二点,Layout的拆分,原有Layout一拆为二,分别有NameNode和DataNode各自对应的NamenodeLayoutVersion和DatanodeLayoutVersion。Layout内会分别记有NameNode,DataNode这边的当前版本所支持的各种feature或者标明目录结构版本的信息。
例如以下是NameNode NamenodeLayoutVersion和DataNode DatanodeLayoutVersion的内部信息:
public class NameNodeLayoutVersion {
...
public enum Feature implements LayoutFeature {
ROLLING_UPGRADE(-55, -53, -55, "Support rolling upgrade", false),
EDITLOG_LENGTH(-56, -56, "Add length field to every edit log op"),
XATTRS(-57, -57, "Extended attributes"),
CREATE_OVERWRITE(-58, -58, "Use single editlog record for " +
"creating file with overwrite"),
XATTRS_NAMESPACE_EXT(-59, -59, "Increase number of xattr namespaces"),
BLOCK_STORAGE_POLICY(-60, -60, "Block Storage policy"),
TRUNCATE(-61, -61, "Truncate"),
APPEND_NEW_BLOCK(-62, -61, "Support appending to new block"),
QUOTA_BY_STORAGE_TYPE(-63, -61, "Support quota for specific storage types"),
ERASURE_CODING(-64, -61, "Support erasure coding"),
EXPANDED_STRING_TABLE(-65, -61, "Support expanded string table in fsimage");
private final FeatureInfo info;
...
}
public class DataNodeLayoutVersion {
...
public enum Feature implements LayoutFeature {
FIRST_LAYOUT(-55, -53, "First datanode layout", false),
BLOCKID_BASED_LAYOUT(-56,
"The block ID of a finalized block uniquely determines its position " +
"in the directory structure"),
BLOCKID_BASED_LAYOUT_32_by_32(-57,
"Identical to the block id based layout (-56) except it uses a smaller"
+ " directory structure (32x32)");
private final FeatureInfo info;
...
}
Layout信息的定义在系统做Rolling Upgrade时还是比较常见的,Layout可以明确标明当期服务启动版本所在的当前版本号以及它现有所支持的新特性(这里指的是一些具有不兼容改动的特性或者涉及数据结构目录layout的改动)。当服务在Upgrade启动后,发现当前运行版本的layout值大于当前存储于本地的layout version值时,就表明此时服务是换了一个新的version版本在跑。
第三点,Rolling Upgrade admin操作命令的支持。这个很好理解,这是为了Rolling Upgrade过程能更加安全,可以人工操作操作模式进行而不是完全的自动化升级,对于存储有海量数据规模的存储系统,完全自动化的Rolling Upgrade危险系数难免太高。
HDFS DataNode端针对Rolling Upgrade的调整
说完HDFS NameNode这边的调整,下面我们再来说说HDFS在DataNode对于Rolling Upgrade的支持做了哪些调整。
一般对于一个系统做升级,master节点的升级要更为重要,slave之类的节点所需要进行的操作要轻量级很多。如果在新升级版本内没有不兼容特性引入的话,那么升级的步骤就很简单了,只需要一个简单的替换安装包重启服务的过程。
不过HDFS社区在做这块实现时围绕以下几点目标做了额外的优化:
- DataNode的快速启动优化
- DataNode的OOB信息实现(HDFS-5583: Make DN send an OOB Ack on shutdown before restarting)
上述两点都是为了尽可能减少Rolling Upgrade过程DataNode节点重启服务所带来的影响。DataNode节点的重启Rolling,中间会涉及到的时间可能比较长,这个由实际集群所包含的DataNode数量规模而定。
这里简单谈谈上述第二点DataNode OOB信息实现。OOB在这里的全称是out of band,意为额外的传送信息。DataNode定义和利用这个OOB信息做什么呢?答案是用来向其它正在读写此DataNode数据的client表明它将要马上做restart操作了,然后告诉这些client它们应该在一定超时时间内等待并忽略与此重启操作引发的异常错误。这可以避免client遇到这类异常马上执行错误recovery这类cost更高的操作。笔者认为这个设计点还是比较巧妙的。
关于HDFS Rolling Upgrade更详细实现的内容可参阅社区JIRA HDFS-5535(Umbrella jira for improved HDFS rolling upgrades)。