身边有一套没什么人用的系统,后端采用了 Hadoop 一式三份存储数据文件。
某日,Ambari 报其中一台 Datanode 的 Heartbeat lost,且不论通过任何方式远程连接均报 Connect refused,多次尝试无果后前往机房,发现硬盘 0 闪红灯,经核对厂商说明,并重新启动服务器看阵列卡报告,确认该硬盘已故障掉盘。
由于集群尚有另外两台 Datanode 在线,且重要文件亦有本地备份,决定采取重装系统并重新同步所有文件的形式进行维护。
本文是给自己的笔记,不是教程,由于本文记述的是摸索过程,如果您有相似的情况需要处理,请不要直接按照本文步骤进行操作。
1、替换损毁的硬盘
关机后撤换有问题的硬盘,然后比照其它 Datanode 的阵列配置重新组装阵列即可,很简单不再赘述。
2、重装操作系统
节点上之前安装的是 CentOS 6.7,尽管是现在已经过时的操作系统,为了保持与原有环境一致,仍然安装了该版本。
安装过程基本一路回车,但由于对于 Linux 的 LVM 机制不熟悉,采用了默认的在磁盘 0 上 root 和 home 分区分离的分区方式(当时还准备保留磁盘 1 和 2 上的分区),该配置在之后的配置过程中引发了问题,后述。
安装过程中需要将主机名配置为节点的内网域名(本例为 dn3.hadoopcluster.com),否则在后面的配置过程中安装 Hadoop 组件时会造成自动配置不正确,本次因缺乏经验就造成了这个问题,后述。
3、配置网络
修改 /etc/sysconfig/network-scripts/ 下对应网卡的配置文件,如:第一块网卡通常被识别为 eth0,则修改该目录下的 ifcfg-eth0 文件。
追加内容如下:
- 修改 ONBOOT= 为 yes
- 修改 BOOTPROTO= 为 static(本机为静态 IP 的情况)
- 新增 IPADDR=IP地址、NETMASK=为子网掩码、GATEWAY=为网关、DNS1=、DNS2=为主、辅DNS
- 可选:新增 IPV6INIT=no 关闭 IPv6,在仅有 IPv4 的环境下减少没有必要的的 IPv6 地址产生的信息
如果在上面选择了关闭 IPv6,还需要修改以下位置:
- 修改 /etc/sysctl.conf 增加 net.ipv6.conf.all.disable_ipv6 = 1
- 修改 /etc/sysconfig/network 增加 NETWORKING_IPV6=no
修改完成后可以重启生效,也可以分别使用以下两条指令立刻生效:
- 重启网络服务使 IP 配置生效:service network restart
- 使 IPv6 的相关修改生效:sysctl -p
4、设置国内源
安装完成后建议将 yum 源设置为国内的地址,以加快软件包的安装与更新的速度。
此处以清华大学 TUNA 源为例,截至本文成文为止,CentOS 6.7 已属于归档的 vault 源,依照 TUNA 提供的帮助信息,修改方法如下:
(1)备份原有文件:cp -r /etc/yum.repos.d/ /etc/yum.repos.d.bak/
(2)修改 CentOS-Base.repo(其它 repo 文件默认没有启用,可不修改):
- 在所有的 mirrorlist= 前面加上 # 注释掉
- 将所有的 baseurl= 前面的 # 去掉注释
- (6.7 为本例的系统版本号,参考时请按自己的实际情况修改)修改所有 baseurl 行中的 mirror.centos.org/centos/$releasever 为 mirrors.tuna.tsinghua.edu.cn/centos-vault/6.7
(3)更新 yum 缓存:yum makecache
5、安装 JDK,及其它准备工作
将从其它 Datanode 上复制来的 JDK 压缩包放在 /usr/soft 目录下,进行解压缩,并增加执行权限:
cd /usr/soft
tar -zxvf jdk-7u79-linux-x64.tar.gz
chmod -R 755 jdk1.7.0_79/
然后配置 JDK 的环境变量,在 /etc/profile 中新增以下内容:
export JAVA_HOME=/usr/soft/jdk1.7.0_79
export PATH=$PATH:$JAVA_HOME/bin
export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
并执行以下命令使环境变量生效:
source /etc/profile
完成后执行以下指令,确认是否安装成功:
java -version
输出 Java 版本表示安装成功。
执行以下命令禁用透明大页(Hadoop 集群要求):
echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled
如有需要,在做好安全防护的前提下,关闭防火墙:
/etc/init.d/iptables stop #此命令关闭防火墙
chkconfig iptables off #关闭防火墙的开机启动
6、恢复损毁的 Datanode 节点与其它节点之间的互访
修改 /etc/hosts 添加到其它机器的访问:
192.168.0.100 nn1.hadoopcluster.com
192.168.0.101 nn2.hadoopcluster.com
192.168.0.103 dn1.hadoopcluster.com
192.168.0.104 dn2.hadoopcluster.com
192.168.0.105 dn3.hadoopcluster.com #本机 IP,也是本次要修复的 Datanode 节点
安装 OpenSSH-Server:
yum install openssh-server -y
生成密钥对:
mkdir /root/.ssh
cd /root/.ssh
ssh-keygen -t rsa //一路回车即可
此时下一步原本应该是将各个节点的公钥(/root/.ssh/id_rsa.pub)发送到主 Namenode 节点(nn1.hadoopcluster.com),但由于除了 dn3 上的机器上还保留着 dn3 崩溃之前的 SSH 公钥信息,且 sshd 默认情况下开启了 strict 模式(/etc/ssh/sshd_config 中设置了 StrictHostKeyChecking yes),会造成其它节点访问 dn2 时因 host key 验证失败而无法连接,例如,在做出下面修改的之前,尝试在其余节点上使用 ssh dn3.hadoopcluster.com 会出现以下提示:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is SHA256:HDjXJvu0VYXWF+SKMZjSGn4FQmg/+w6eV9ljJvIXpx0.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /root/.ssh/known_hosts:5
ECDSA host key for dn3.hadoopcluster.com has changed and you have requested strict checking.
Host key verification failed.
所以需要先去各个机器上删掉已知主机公钥库中的 dn3 公钥:
- 首先备份 /root/.ssh/known_hosts
- 然后删除中文件原来 dn3.hadoopcluster.com 的一整行,保存即可(也可使用 ssh-keygen -R dn3.hadoopcluster.com)
- 以上操作需要在 nn1、nn2、dn1、dn2 上分别执行
接下来在 nn1 上拉取 dn3 的公钥到 ~/.ssh/(可能需要输入 dn3 的 root 账户和密码):
cd ~/.ssh/
scp [email protected]:~/.ssh/id_rsa.pub id_rsa_dn3.pub
将所有公钥集合为已认证公钥库 authorized_keys,并备份原来的文件以防万一:
# 注意此时已保存的公钥文件名均为 id_rsa_*.pub 的格式,包括 nn1 本身的)
cp authorized_keys authorized_keys.bak
cat id_rsa_*.pub >> ~/.ssh/authorized_keys
然后将认证库发送到其它机器上:
scp ~/.ssh/authorized_keys [email protected]
scp ~/.ssh/authorized_keys [email protected]
scp ~/.ssh/authorized_keys [email protected]
最后,重建其它节点到 DN3 的连通性:
ssh dn3.hadoopcluster.com #需要在所有机器上依次执行一遍,包括 dn3 自己
# 虽然也可以在 nn1 上连接一次然后将 known_hosts 发布到其它各主机上,但为求稳妥,最好是实际去各台机器上连接一遍
出现以下提示时输入 yes 将 dn3 的新 host key 加入本地的 known_hosts:
The authencity of host ‘dn3.hadoopcluster.com (192.168.0.105)’ can’t be established.
ECDSA key fingerprint is SHA256:HDjXJvu0VYXWF+SKMZjSGn4FQmg/+w6eV9ljJvIXpx0.
Are you sure you want to continue connecting (yes/no): # 输入yes
7、使用 Ambari 为新的 Datanode 安装 Hadoop 软件
本例中 Ambari 安装于 nn1,由于没有保留截图,简述一下步骤:
(1)在 Hosts 中点击 Actions – Add hosts
(2)向导第一步中,Target hosts 填写要安装软件的 FQDN(不能填写 IP,该域名不需要在公网能解析,本例为 dn3.hadoopcluster.com),并在 Host Registration Information 上传要安装软件的主机 SSH 私钥(~/.ssh/id_rsa,多个主机将多个私钥文件拼接起来即可)。SSH User account 和 SSH Port number 无特殊情况可以保留原样。
(3)向导第二步会检查环境,有问题会进行提示,进行对应修复即可。
(4)向导第三步中,勾选安装 Datanode、Zookeeper 和 Ambari Metrics
(5)等待完成安装即可。
8、小插曲:停下就再也醒不过来的 Datanode
完成上述步骤后,发现 Datanode 迟迟不开始同步(实际原因后述),尝试重启 Datanode 服务但是不成功,通过查看日志(/var/log/hadoop/hdfs/hadoop-hdfs-datanode-dn3.hadoopcluster.com.log)发现如下信息:
java.net.BindException: Problem binding to [0.0.0.0:50010] java.net.BindException: Address already in use; For more details see: http://wiki.apache.org/hadoop/BindException
但如果按照网上搜出来的方法,使用 netstat -tunlp|grep 50010 尝试找出占用 TCP 50010 端口的进程的话,会发现没有任何输出,而使用 netstat -n|grep 50010 查看的话,会发现一个处于 TIME_WAIT 状态的在 50010 端口上的连接。
通过查找资料,在 /etc/sysctl.conf 中增加以下参数可以缓解此问题:
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
其中第一行用于启用 TCP 连接重用,允许内核重用处于 TIME_WAIT 状态的连接;第二行用于启用 TIME_WAIT 连接的尽快回收(注:本案例处于比较简单的网络布局下,请不要在 NAT 复杂环境下启用该参数)。
修改完成后重启(sysctl -p 可以立刻生效但之前的 TIME_WAIT 连接仍在),现在 Datanode 重启基本不会遇到 Address already in use 的情况了。
9、扩充 / 分区
完成上述安装步骤后,按说只需要等待 Hadoop 自动同步所有文件即可,但过了一天 Under replicated blocks 仍然有好几万。
经过对多处参数的查看,最后终于在 dn3 的 Datanode web 界面(dn3.hadoopcluster.com:50070)上发现一处端倪:Capacity Left 一直是 0 B。
经查看配置文件,得知默认的 Hadoop 数据目录 /hadoop/hdfs/data 存在于 / 下(df -h /hadoop 查看所在分区),但由于安装系统时将 / 和 /home 进行了划分(实际应该采取全盘 / 的分区形式),导致 / 目录只有几百 MB 的容量,在 Hadoop 开始节点同步后很快被填满,导致同步无法继续进行。
由于具体修改的过程没有留下截图或日志,故以下简单记录所进行的操作:
(1)由于第2、3块磁盘在阵列卡中被配置为一块虚拟磁盘,在当前系统中被识别为 /dev/sdb1,遂尝试挂载(mkdir /mnt/sdb1 && mount /dev/sdb1 /mnt/sdb1)查看内容,出现类似如下提示:
mount: unknown filesystem type ‘LVM2_member’
经搜索,为 CentOS 6.7 中默认选项未安装 lvm2 所致,使用以下指令安装:
yum install lvm2
(2)安装后使用 pvs 查看物理卷情况,发现 /dev/sdb1 从属于丢失的VG:
Couldn’t find device with uuid ’56ogEk-OzLS-cKBc-z9vJ-kP65-DUBI-hwZPSu’.
(3)尝试使用 pvcreate –uuid 丢失的设备UUID /dev/sdc –restorefile /etc/lvm/backup/原来的vg名称 无效,因为 restorefile 参数需要指向vg元数据备份文件,而这个文件已经随着系统盘损毁一并丢失了。
(4)最后放弃抢救旧的 vg,删除失效的 vg,并将现有的 vg 扩展到 sdb1 上(此时由于参考某些教程,还没有注意到 /hadoop 不在 /home 下而在 / 下):
vgremove 旧的vg名称 –removemissing #删除旧的vg
vgextend 当前系统所在vg名称 /dev/sdb1 #将现有vg扩展到sdb1上
lvextend -l +100%FREE /dev/当前系统所在vg名称/lv_home #将扩展后的vg可用空间全部分配给lv_home
resize2fs -p -F /dev/当前系统所在vg名称/lv_home #分区扩展后,在线扩展文件系统
(5)后来终于意识到 /hadoop 在 / 下,执行了以下操作删除 /home 并将可用空间分配给 /:
首先去 Ambari 中停止所有在 DN3 上的服务
tar cvf /tmp/home.tar /home #备份 /home 中的内容,完成后将 home.tar 下载到本地备用
umount /home #卸载 /home
编辑 /etc/fstab 文件,将其中原有挂载 home 分区的行加上 # 注释掉,避免下次重启后查找不存在的 home 分区
lvremove /dev/mapper/当前系统所在vg名称下的lv_home分区(如vg_hadoopdn3-lv_home)#删除旧的home逻辑卷
lvextend -l +100%FREE /dev/mapper/当前系统所在vg名称下的lv_root分区(如vg_hadoopdn3-lv_root)#将可用空间全部扩展给/
resize2fs /dev/mapper/当前系统所在vg名称下的lv_root分区(如vg_hadoopdn3-lv_root)#扩充文件系统
如有必要,使用刚刚备份的文件恢复 /home 目录下的文件
去 Ambari 中重启服务
10、总结
经过以上一通折腾,损毁的 DN3 节点终于重新上线,经过大约一周的重新同步,Under replicated blocks 清零,系统恢复到部分损毁之前的情况。
以上是本人在乙方提供的说明书只提及了如何通过 Ambari 进行 Hadoop 软件安装的情况下对 Hadoop datanode 损毁尝试恢复的笔记,中间绕了不少弯子,幸而最后成功解决了,可喜可贺。
再次提醒:本文是笔记,不是教程,请勿逐步照做。同时由于本人并非专业运维,且本文成文间隔时间较长,部分步骤肯定不是最优解,仅供参考。
注:所有评论将在审核通过后显示,请不要在评论内容的任何位置出现链接,否则您的评论将被自动移入回收站,且永远不会被复审。
All comments will be available after being manually reviewed, please do not include any links anywhere in your comment, otherwise your comment will be automatically deleted and are not eligible for review.