一次Hadoop脑裂的修复(Cloudera hadoop split-brain repair)

from:  http://www.linuxboy.net/?p=854


突然发现hadoop集群的second namenode日志显示IPC错:

Active

于是重启辅namenode

好几次的从 1% — 100%

注意,看时间戳,加载fsimage的时间可能会很长,花费20多分钟,注意观察:50070端口的页面,要有耐心:

居然在13:09分,second namenode正在加载fsimage和transaction中崩溃了,幸亏当时有人及时发现,
当即重启,13:15分重启:
显然这时候已经发生脑裂了,因为主辅的状态都不对,所以zkfc服务不停的试图扶正辅namenode(变成主)

这时候判断辅namenode由于报错已久,好几天了,metadata估计都是不太正常的,主辅的meta所占磁盘空间也相差比较大。所以杀掉了辅namenode,备份了好的主namenode的metadata,然后单独启动了主namenode

悲剧就从这时开始了,主namenode启动后处于standby模式,safe mode is on。
sudo -u hdfs hdfs haadmin的命令都不可用,总是连接辅namenode的8020,得不到回应而失败。

注意以下这条命令,他是直接把nn1 变成主,而不执行autofailover
sudo -u hdfs hdfs haadmin haadmin –transitionToActive nn1
没办法:按一下方法处理,才解决:

①先停掉主辅namenode,备份好meata数据文件

②杀掉所有的Datanode上面的Datanode进程,避免读写文件,产生干扰。

③停掉主辅namenode上面的zkfc进程,同时修改hdfs-site.xml文件:


⑤重启主、辅namonode,观察:50070的页面,看是否都进入standby safe mode.

⑥在主namenode上,切换状态,从standby safe mode切到Active safe mode.
sudo -u hdfs hdfs haadmin -failover –forceactive nn2 nn1
注意:这条命令指定了failove,会调用failover函数,最后指定的是nn1是活状态,nn2是备用。

⑦主namenode处于active状态后,启动所有Datanode上面的Datanode的进程,看:50070页面lost block的变化,等到就绪。

⑧如果有问题,可以hadoop fsck / -blocks,进行检查。直到就绪

⑨主namenode执行命令,离开safe mode,开始提供服务:
sudo -u hdfs hdfs dfsadmin -safemode leave

⑩看看辅namenode的状态,看是否能追上来,并修复,如果不能修复的话可以重做:
sudo -u hdfs hdfs namenode -bootstrapStandby
⑪注意haadmin的几条命令:
transition要慎用,它根本不通知其他的namenode,是单台执行的。
而failover会通知其他的namenode。

由于Hadoop脑裂,且ganglia无报警,灭有办法,只能手工加上一层报警了。

Fuse-hdfs 文件系统不支持 O_RDWR and O_EXCL, 所以用rsync同步文件到fuse_hdfs中的时候会得到 EIO 错误.

必须修正rsync源代码:

diff -r rsync-3.0.8.no_excl/syscall.c rsync-3.0.8/syscall.c
234a235,252
> #if defined HAVE_SECURE_MKSTEMP && defined HAVE_FCHMOD && (!defined HAVE_OPEN64 || defined HAVE_MKSTEMP64)
>   {
>       int fd = mkstemp(template);
>       if (fd == -1)
>           return -1;
>       if (fchmod(fd, perms) != 0 && preserve_perms) {
>           int errno_save = errno;
>           close(fd);
>           unlink(template);
>           errno = errno_save;
>           return -1;
>       }
> #if defined HAVE_SETMODE && O_BINARY
>       setmode(fd, O_BINARY);
> #endif
>       return fd;
>   }
> #else
237c255,256
<   return do_open(template, O_WRONLY|O_CREAT, perms);
---
>   return do_open(template, O_RDWR|O_EXCL|O_CREAT, perms);
> #endif

 

Logo

更多推荐