文章目录
前言
在HDFS集群运维过程中,我们经常会遇到机器送修的情况,尤其在集群机器数量比较多的情况下,每天因为坏盘或是其它硬件问题导致的机器维修是很常见的。对于集群维护者来说,机器的这种日常损坏我们是无法回避的,我们能做的是如何将这种机器维修所造成的影响降低到最小。在现有的HDFS功能里,社区提供了一种叫做Maintenance state(HDFS-7877)的功能来专门处理这种情况。本文笔者来谈谈这个有用的功能以及我们内部是如何简化此特性来方便于我们的使用的。
Maintenance state
Maintenance state是DataNode里面一种新的状态,它和DataNode正常In Service状态最大的区别是它不会触发大量的replica复制。而且Maintenance state有自己的过期时间阈值设置,一旦超过过期时间,Maintenance state节点会自己重新切换成In Service状态。从这个过程我们可以看到,Maintenance state的引入可以使得机器维护的时段对集群来说是完全透明的,但是这里还需要有一个前提条件:集群内拥有其它足够的副本数据以此保证数据的可用性。如果在维修的机器上保留的是集群仅存的副本数据的话,依然还是会导致数据无法访问的情况。
因此在Maintenance state功能里面,很重要的一部分实现做的是最少副本数的检查,来确保机器进入Maintenance状态后,不会出现部分数据无法访问的情况。
Maintenance state的场景匹配
最近笔者也在调研Maintenance state功能,但是在使用场景上,社区的目前实现并不是十分吻合我们内部的场景,主要差别点如下所示:
最少副本数的检查是否一定是必须的? 这块实现本身在设计出发点上是没有问题的,不过笔者内部集群已经通过改造block replica的placement来做到副本数的冗余分布了。所以对于这块的实现,笔者并不倾向于增加这样的改动在我们内部的版本中。另外这块的改动会引入额外新的enter maintenance状态,这无异于将这块功能的实现复杂化了一些。
使用方式不够灵活,不方便admin使用。社区的Maintenance功能在使用时需要将Maintenance节点信息和其过期时间一同写入host文件的方式来进行Maintenance state的触发刷新。虽然说将Maintenance节点信息写入文件的方式能够持久化这部分信息,但这在另外一个层面来讲,它带来了信息维护的改造成本。比如之前管理员用纯hostname记录的include/exclude的文件来做节点信息的维护,如下所示:
host1
host2
host3
host4
现在就要转变为新的带有过期时间值的json格式的host文件,如下所示:
[
{
"hostName": "host1"
},
{
"hostName": "host2",
"upgradeDomain": "ud0"
},
{
"hostName": "host3",
"adminState": "DECOMMISSIONED"
},
{
"hostName": "host4",
"upgradeDomain": "ud2",
"adminState": "IN_MAINTENANCE"
}
]
笔者公司内部使用的就是传统hostname方式来进行节点的管理的。但是我们想在不改变现有节点管理的方式下,额外再支持Maintenance state节点的管理。
Maintenance state的差别改造
鉴于上面的一些差异点,笔者在社区Maintenance state实现的基础上,进行了二次扩展改造。在这里面主要进行了以下两方面的改造。
第一点,我们摈弃了enter maintenance状态的引入,使得整个功能的实现看起来更为的简洁。而对于enter maintenance期间所做的最小副本数的检查,我们通过别的方式来保证数据的可用性。
第二点,支持dfsadmin命令方式来进行Maintenance节点的管理。这种方式对于Maintenance节点管理员来说将会十分方便。我们也无须去改变原有include/exclude的文件格式了。因为Maintenance节点管理涉及到进入和离开Maintenance state的操作,因此在实现上笔者设计了以下3个新的Maintenance命令。
bin/dfsadmin [-maintenanceState [-enter <host1,host2#time1 in seconds,time2>] [-leave <host1,host2>] -clearAllState]
上面clearAllState的命令指的是一键清除所有Maintenance的节点。
鉴于以上的扩展实现,DataNode的状态机变换将会如下图所示:
在上面的差别化改造后,有个比较重要的不同在于DN的maintenance状态是会发生丢失的。因为maintenance状态是直接通过RPC的方式直接在NN内存里面改的。倘若此时NN发生重启或者意外crash的情况,那些maintenance DN的状态在重启的NN里就会发生丢失。这应该来说是这套简易版Maintenance功能里最大的美中不足。
在UI上,我们进行了相应的调整,能够展示那些在maintenance状态下的DN节点信息,
参考链接
[1].https://issues.apache.org/jira/browse/HDFS-7877
[2].https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsDataNodeAdminGuide.html