[译]HDFS 滚动升级和降级
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[译]HDFS 滚动升级和降级相关的知识,希望对你有一定的参考价值。
参考技术A 原文HDFS滚动升级可以升级单独的HDFS守护进程. 例如, datanode们可以独立于namenode来升级. 一个namenode也可以独立于其他的namenode们来升级. namenode们也可以独立于datanode们和journal node们升级.
在Hadoop版本2中, HDFS支持高可用(HA)namenode服务并结合兼容性. 这两项能力使其可以在避免停机时间的情况升级HDFS. 要无停机地升级一个HDFS集群, 这个集群就必须是配置为高可用的.
如果升级后, 在新版中有任何在旧版本中不能使用的新特性, 那么这次升级就必须按以下步骤进行:
在一个高可用集群中, 有至少2个namenodes(NNS), 多个datanodes(DNs), 少数JournalNodes(JNs)和少数Zookeeper节点(ZKNs). JNs相当稳定,在多数情况下, 升级HDFS时不需要升级. 在本文描述的滚动升级中, 只考虑升级NNs(namenodes)和DNs(datanodes), 但是JNs和ZKNs不考虑. 升级JNs和ZKNs可能会导致集群停机.(按: Zookeeper其实也可以进行滚动升级)
假设集群有两个namenodes: NN1和NN2, 各种处于活动和待机状态. 按以下步骤进行高可用集群升级:
在一个联盟集群中, 有多个命名空间, 每个命名空间都有各自的活动和待机NNs. 升级一个联盟集群的过程类似于升级非联盟集群, 区别在于第一步和第四步在每一个命名空间上都执行, 而第二步在每一对活动和待机namenodes上执行. 例如:
对于非高可用的集群, 是不可能升级HDFS且避免停机, 因为要重启namenodes. 不过, datanodes还是可以滚动升级的.
在一个非高可用集群中, 有一个Namenode(NN),一个SecondaryNameNode(SNN)和多个datanodes(DNs). 升级一个非高可用集群的过程类似于升级一个高可用集群, 除了第二步"升级活动和待机节点"要改成以下步骤:
当升级的版本不是需要的版本,或者在某些不太可能的情况下, 升级失败了(因为新版本中的某些bug), 管理员可以选择降级HDFS到升级之前的版本, 或者回滚到升级前的版本和状态.
请注意, 降级可以用滚动方式进行, 但是回滚不行. 回滚时就要停机.
请注意, 降级和回滚只能在一个滚动升级开始后, 和升级终止之间进行. 一个升级过程可以被"结束", 降级或者回滚 其中之一操作终止. 所以, 结束升级,或者降级之后,或无法回滚, 或者结束后无法降级.
降级把系统恢复到升级前版本,且保持用户数据. 假设在时间点T, 滚动升级开始, 这个升级被降级所终止的话, 在时间点T之前或者之后创建的文件都保持在HDFS上, 在时间点T之前或之后删除的文件也是在HDFS里被删除的.
在新版本和旧版本之间, 只有当两边的namenode版本和datanode版本还没在这两个版本之间改变时, 新版本才能降级到旧版本.(不清楚, 请赐教,谢谢. A newer release is downgradable to the pre-upgrade release only if both the namenode layout version and the datanode layout version are not changed between these two releases.)
在一个高可用集群, 当滚动升级从旧版本到新版本在进行中时, 是可以滚动方式降级的, 升级的机器回到旧版本. 同前例, 假设NN1和NN2各自在活动和待机状态. 以下是无停机滚动降级的步骤:
请注意, datanodes必须在namenode降级之前降级, 因为通讯协议是向下兼容的而不是向上兼容的. 例如老版本的datanode可以和新版本的namenode通讯,但是新版本的datanode未必能和老版本的namenode通讯.
回滚把系统恢复到升级前版本, 还把用户的数据恢复到升级前状态. 假设在时间点T, 滚动升级开始, 这个升级被回滚所终止的话, 在时间点T之前创建的文件都保持在HDFS上, 时间点T之后创建的文件就不存在了. 在时间点T之前的文件在HDFS里被删除的, 在时间点T之后删除的文件就被恢复了.
从新版本回滚到旧版本是一直支持的. 但是, 回滚操作不能滚动执行. 这需要停机时间. 设NN1和NN2分别处于活动和待机状态. 以下是回滚步骤:
执行一个滚动升级操作
提交一个关闭请求到指定的datanode. 如果upgrade选项指定了, 访问这个datanode的客户端都会被指示要等这个datanode重启, 同时快速启动模式也要被激活. 当重启不够及时, 客户端就超市,并忽略这个datanode. 在这种情况下, 快速启动模式就被关闭.
请注意, 这个命令并不会等到datanode完全关闭. "hdfs dfsadmin -getDatanodeInfo"命令可以检查datanode是否被完成了关闭.
当一个滚动升级在进行中, -rollingUpgrade 启动选项可以指定不同滚动升级行为
HDFS实践|HDFS3.2升级在滴滴的实践
桔妹导读:Hadoop 3的第一个稳定版本在2017年底就已经发布了,有了很多重大的改进。在HDFS方面,支持了Erasure Coding、More than 2 NameNodes、Router-Based Federation、Intra-datanode balancer 等功能,大家可能对这些功能很感兴趣,打算将集群升级到HDFS 3.x 版本。本篇文章会介绍我们是如何将 HDFS 从2.7滚动升级到3.2版本的,在升级中会遇到哪些问题以及我们是如何解决掉的。HDFS 升级过程漫长,但是收益是非常多的。在此基础上,我们可以继续做非常有意义的工作,持续在稳定性、性能、成本等多个方面深入探索,使用技术为公司创造可见的价值。
1.
为什么要升级
2.
调研升级方案
3.
解决滚动升级中遇到的问题
滚动升级的操作流程在 Hadoop 官方升级文档中有介绍,概括起来大致步骤如下:
1.JournalNode 升级,使用新版本依次重启 JournalNode
2. NameNode 升级
2.1升级准备,生成 fallback fsimage 文件
2. 2使用新版本 Hadoop 重启 Standby NameNode,重启 ZKFC
2.3做 failover,使升级后的 NameNode 变成 Active 节点
2.4使用新版本 Hadoop 重启另一个 NameNode,重启 ZKFC
3.升级 DataNode,使用新版本 Hadoop 重启所有 DataNode 节点
4.做 Finalize,确认集群变更到3.2
在测试环境验证 HDFS 滚动升级方案时,升级和降级过程中都遇到了一些问题。
在滚动升级中,当 Active NameNode 为3.2版本,Standby NameNode 为2.7版本时,会出现 EditLog 不兼容问题。此时,Active NameNode 写 EditLog 时会将 EC 相关的结构写入到 EditLog 当中,当 Standby NameNode 读取 EditLog 时,会出现识别不了的情况,导致 Standby NameNode 直接 Shutdown。我们的解决方案是,考虑当前有效版本是否支持 EC,如果支持 EC 则会写入 EC 信息到 EditLog,否则不会写入。而在升级过程中,有效版本实际上还是2.7,是不支持 EC 的,这个时候忽略 EC 即可,这样 Standby NameNode 读取 EditLog 做合并时,不会出现 EC 相关信息,可正常工作。解决问题的 ISSUE 为 HDFS-13596。
在滚动降级中,当3.2版本的 NameNode 使用3.2版本 Hadoop 重启时,如果当前最新的 Fsimage 是3.2版本 NameNode 产生的,则2.7版本 Hadoop 重启 NameNode 会直接 Shutdown,原因是,3.2版本 Haodop 产生的 Fsimage 文件,2.7版本的 Hadoop 无法进行加载,这将导致如果升级中遇到问题想回滚的话,无法完成回滚操作。经过深入分析,我们发现有两个问题会导致这种情况出现。
第一个问题,Fsimage 的不兼容是由于3.2版本的 NameNode 将 EC 信息写入到了 Fsimage 当中,2.7版本的 Hadoop 无法识别 EC 信息,导致失败。解决方案与上面类似,在保存 Fsimage 时考虑当前的有效版本,如果不支持 EC 则不会将 EC 信息写入到 Fsimage 文件中。解决问题的 ISSUE 为 HDFS-14396。
第二个问题,由于 NameNode 对 StringTable 的修改导致了 Fsimage 的不兼容,目前该问题可以通过回滚 commit 进行解决,社区反馈修复也不是很必要,可以通过先升级到无该 commit 的版本,滚动升级稳定后,直接进行小版本升级,跨过这个不兼容特性。记录 ISSUE 为 HDFS-14831。
由于滴滴使用的是内部的用户名密码认证机制,社区出现的一个问题我们没有遇到, ISSUE 为 HDFS-14509 ,升级过程中 NameNode 和 DataNode 由于数据结构的变化,生成了不同的 password,导致无法认证,读写数据会失败。该 ISSUE 记录了这个问题,需要先升级到 2.x 的最新版本进行过度,之后才能滚动升级到 3.x 版本。
总结起来,需要做 HDFS2.x 到 3.x 的滚动升级,需要关注这些 ISSUE,HDFS-13596,HDFS-14396,HDFS-14831,HDFS-14509。
4.
测试与上线
从19年初开始关注 HDFS 滚动升级,在解决遇到的已知问题之后,开发与测试不断讨论升级方案,将可能遇到的风险进行总结。
在这个过程中,我们详细阅读分析了滚动升级的源码,确定升级中 NameNode,DataNode 会做哪些动作,以明确风险点。同时我们还分析了从2.7到3.2版本引入的关于 HDFS 的4000左右的 Patch ,找出可能存在兼容性问题的点,进行深入地分析。同时我们对3.2中新引入的 Feature 也进行了分析,以确保新功能对升级没有影响。种种总结、分析、测试相关的工作,我们写了四五十篇的 WIKI 文档进行记录。在测试环境中升级步骤进行了数次演练,确认没问题之后,我们开始了升级之路。相关的具体里程碑上线过程如下:
1.19年5月左右,升级演练多次,准备全量 Hadoop、Hive、Spark Case 进行测试,确定方案没有问题
2.19年7月左右,离线小集群1(百台)升级到3.2版本,用户未受到影响。
3.19年10月左右,离线小集群2(数百台)升级到3.2版本,用户未受到影响。
4.19年11月底,离线大集群(数千台)升级到3.2版本,用户未受到影响.
升级过程中,DataNode 在删除 Block 时,是不会真的将 Block 删除的,而是先将Block 文件放到一个 Trash 目录中,为了能够使用原来的 FallBack Fsimage 恢复以前的数据。当升级周期比较长时,Trash 中的数据就会很多,例如我们这边大集群升级周期就有3周之长。升级操作在短时间之内,是可以确定是否有问题的,并且三周之后也不可能真的回滚到以前的数据,倘若真的遇到问题,是需要及时修复的。我们开发了额外的工具,对 Trash 中的 Block 文件进行按天归档,设置好保留时间,例如设置1天。我们会每天例行将1天之前的数据进行删除,这样可以大大减少 DataNode 上磁盘的存储压力。
升级之后,我们对各个集群进行都进行自己观察,目前服务一切正常。
5.
总结
非常高兴在如此大规模的集群上完成从2.7到3.2的滚动升级,走在了行业的前列。HDFS 升级过程漫长,但是收益是非常多的。在此基础上,我们可以继续做非常有意义的工作,持续在稳定性、性能、成本等多个方面深入探索,使用技术为公司创造可见的价值。
本文作者
▬
推荐阅读 ▬
更多推荐 ▬
滴滴开源 / Open Source | | | | | | | | | | | | |获取更多项目
技术干货 / Recommended article | | |阅读更多内容
以上是关于[译]HDFS 滚动升级和降级的主要内容,如果未能解决你的问题,请参考以下文章
[译] 现代 JavaScript 与 CSS 滚动实现指南