导语
在HDFS集群运维过程中,常会碰到因为实际业务增长低于集群创建时的预估规模;集群数据迁出,数据节点冗余较多;费用控制等原因,需要对集群进行缩容操作。Decommission DataNode是该过程中关键的一步,就是把DataNode从集群中移除掉。那问题来了,HDFS在设计时就把诸如机器故障考虑进去了,能否直接把某台运行Datanode的机器关掉然后拔走呢?理论上可行的,不过在实际的集群中,如果某份数据只有一份副本而且它就在这个机器上,那么直接关掉并拔走机器就会造成数据丢失。本文将介绍如何Decommission DataNode以及可能会遇到Decommission超时案例及其解决方案。
Decommission DataNode步骤
1、在Active Namenode节点,把需要Decommission的DataNode的主机名加入到dfs.hosts.exclude(该配置项在hdfs-site.xml)所指定的文件中,有多个Decommission DataNode以换行分割,建议一次Decommission节点小于hdfs备份数。腾讯云EMR该文件为/usr/local/service/hadoop/etc/hadoop/hdfsexcludedhosts。
PS:如果hdfs-site.xml中未找到dfs.hosts.exclude,需手动将该属性加入配置文件中,如:
代码语言:txt复制 <property>
<name>dfs.hosts.exclude</name>
<value>/usr/local/service/hadoop/etc/hadoop/hdfsexcludedhosts</value>
</property>
2、在Active NameNode节点,执行以下命令:su <HDFS_USER> hdfs dfsadmin -refreshNodes。<HDFS_USER>指的是拥有HDFS服务的用户,腾讯云EMR为hadoop。
3、打开NameNode Web UI,跳转到Datanodes页面,检查要Decommission的DataNode的状态是否已更改为“Decommission In Progress”,如下图。
4、当Decommission DataNode节点所有块均已复制,其状态将变为“Decommissioned”,如下图。
5、在Decommission DataNode节点停止DataNode进程,执行以下命令<HADOOP_HOME>/sbin/hadoop-daemon.sh stop datanode。腾讯云EMR直接在控制台操作。
6、在Active NameNode主机上,清空<步骤1>中文件添加的Decommission节点的主机名,然后执行以下命令:su <HDFS_USER> hdfs dfsadmin -refreshNodes。<HDFS_USER>指的是拥有HDFS服务的用户,腾讯云EMR为hadoop。
案例
问题描述
客户反馈,正常3个节点,一天就可以完成下线,这次执行了5天还没完成,并不是不动,而是动的非常慢
原因分析
查看NameNode Web UI的Datanodes页面如下
- Under replicated blocks:当前block的副本 < 所设置的副本(默认就是小于3) 数量
- Blocks with no live replicas:没有live 的副本,存在的副本可能都在Decommission的节点上
- Under Replicated Blocks In files under construction: 当前正在复制中的block个数
在decommission几个节点中,存在副本只在Decommission的节点上的情况。这意味着,如果“删除”数据节点,则带有这些块的文件将被损坏。以防这种现象出现,Decommission节点会被阻塞。
解决方案
检查0/1/2副本的文件,强制改成三副本
代码语言:javascript复制1、打印所有块信息:
hdfs fsck / -files -blocks > ./blocks.txt
2、检查副本:
sed '$!N;/Live_repl=0/P;D' ./blocks.txt | grep "block" | awk '{print $1}' > ./rep_0.txt # 0副本文件
sed '$!N;/Live_repl=1/P;D' ./blocks.txt | grep "block" | awk '{print $1}' > ./rep_1.txt # 1副本文件
sed '$!N;/Live_repl=2/P;D' ./blocks.txt | grep "block" | awk '{print $1}' > ./rep_2.txt # 2副本文件
3、改副本数:(改之前确认一下文件内容)
for hdfsfile in `cat ./rep_0.txt`; do hdfs dfs -setrep 3 $hdfsfile; done
for hdfsfile in `cat ./rep_1.txt`; do hdfs dfs -setrep 3 $hdfsfile; done
for hdfsfile in `cat ./rep_2.txt`; do hdfs dfs -setrep 3 $hdfsfile; done
延申
1、文件未关闭导致Decommission超时
当待Decommission DataNode节点中存在打开中的文件,表明此文件目前不是一个完整状态,此文件副本就无法复制到其它datanode节点上,由于存在未完全复制完的副本,则待Decommission会被阻塞超时。通过以下步骤检查Decommission 节点是否存在打开的文件。
代码语言:javascript复制检查日志获取正在退服的块
grep "Is current datanode" hadoop-xx-namenode-xxxxxxxxx.log | tail | awk '{print $9}'
根据block id 获取对应的文件,并检查是否处于打开状态
hdfs fsck -blockId block_id
hadoop fsck 文件名 -files -blocks -locations -openforwrite
2、调整参数加速Decommission DataNode
Decommission DataNode相关参数
参数名称 | 默认值 | 参数含义 |
---|---|---|
dfs.namenode.decommission.interval | 30 | 每次启动monitor线程处理退服节点的间隔 |
dfs.namenode.decommission.blocks.per.interval | 500000 | 每个批次最多处理多少个文件块 |
dfs.namenode.decommission.max.concurrent.tracked.nodes | 100 | 同时处理退服的节点个数 |
dfs.namenode.replication.work.multiplier.per.iteration | 32 | 每次复制的块的个数为 dn的个数* 该参数 |
dfs.namenode.replication.max-streams | 64 | 进行复制任务分配时,单个DN 任务的最大值 |
dfs.namenode.replication.max-streams-hard-limit | 128 | 若DN 的复制任务大于改值时,不会将其选为复制的源节点 |
默认参数下,Decommission执行速度较慢,建议检查参数是否为建议值,可适当调大下列参数
代码语言:javascript复制dfs.namenode.replication.work.multiplier.per.iteration 注意:过大会导致块复制操作占用过多的带宽,影响业务
dfs.namenode.replication.max-streams
dfs.namenode.replication.max-streams-hard-limit