master:131 log:132 vip:15
目前还没有弄大清楚mfsmetarestore这里命令参数到底是什么意思,总体的思路是: 1、安装一个mfsmaster 2、利用同样的配置来配置这台mfsmaster(利用备份来找回mfsmaster.cfg),可见配置文件也是需要备份的。 3、找回metadata.mfs.back文件,可以从备份中找,也可以中metalogger主机中找(如果启动了metalogger服务),然后把metadata.mfs.back放入data目录,一般为${prefix}/var/mfs。 4、从在master宕掉之前的任何运行metalogger服务的服务器上拷贝最后metadata文件,然后放入mfsmaster的数据目录。 5、利用mfsmetarestore命令合并元数据changelogs,可以用自动恢复模式mfsmetarestore –a,也可以利用非自动化恢复模式,语法如下: mfsmetarestore -m metadata.mfs.back -o metadata.mfs changelog_ml.*.mfs
方案是这样的: 131是Master,log为132,要是131倒掉,就从132上再起一个master,在132上master和log server是共存的,在log上恢复master的好处是不用scp master上的Metadata.mfs.bak文件,因为master和Log是互为热备的,我们要充分利用这一优势。
131和132之间用Keepalived做到心跳: master keepalived配置:
! Configuration File for keepalived
global_defs {
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id mfs_master
}
vrrp_script check_run {
script "/usr/local/mfs/script/keepalived_check_mfsmaster.sh"
interval 2
}
vrrp_sync_group VG1 {
group {
VI_MFS
}
}
vrrp_instance VI_MFS {
state MASTER
interface eth1
virtual_router_id 30
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
check_run
}
virtual_ipaddress {
192.168.40.15/24 broadcast 192.168.40.255
}
}
keepalived每隔一段时间就运行一次keepalived_check_mfsmaster.sh脚本, keepalived_check_mfsmaster.sh如下:
#!/bin/sh
KEEPALIVED_CMD=/usr/local/keepalived/etc/rc.d/init.d/keepalived
CHECK_TIME=2
function check_mfsmaster() {
ps -ef|grep mfsmaster|grep -v grep|grep -v vim|grep -v cat|grep -v vi|grep -v less|grep -v 'keepalived_check_mfsmaster'
if [ $? = 0 ];then
MFS_OK=1
else
MFS_OK=0
fi
return $MFS_OK
}
while [ $CHECK_TIME -ne 0 ]
do
CHECK_TIME=`expr $CHECK_TIME - 1`
check_mfsmaster
if [ $MFS_OK = 1 ];then
CHECK_TIME=0
exit 0
fi
if [ $MFS_OK -eq 0 ] && [ $CHECK_TIME -eq 0 ]; then
/usr/local/mfs/sbin/mfsmaster -s
$KEEPALIVED_CMD stop
exit 1
fi
done
脚本如果发现mfs进程不存在,就把keepalived卡掉,为了防止裂脑,再把Master卡一次。 这样Keepalived的master点就算倒掉了,
backup: backup 132 的keepalived配置:
! Configuration File for keepalived
global_defs {
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id mfs_backup
}
vrrp_sync_group VG1 {
group {
VI_MFS
}
notify_master "/usr/local/mfs/script/keepalived_notify.sh master"
notify_backup "/usr/local/mfs/script/keepalived_notify.sh backup"
}
vrrp_instance VI_MFS {
state BACKUP
interface eth1
virtual_router_id 30
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.40.15/24 broadcast 192.168.40.255
}
}
Backup上检测到master倒了之后就运行/usr/local/mfs/script/keepalived_notify.sh master脚本 脚本如下:
MFS_HOME=/usr/local/mfs
MFSMASTER=${MFS_HOME}/sbin/mfsmaster
MFSMETARESTORE=${MFS_HOME}/sbin/mfsmetarestore
MFSMETALOGGER=${MFS_HOME}/sbin/mfsmetalogger
MFS_DATA_PATH=/data/mfs
MFS_MASTER_DATA_PATH=/data/mfs_master_backup
function backup2master() {
rm -fr $MFS_MASTER_DATA_PATH/*
cp -f ${MFS_DATA_PATH}/* ${MFS_MASTER_DATA_PATH}/
$MFSMETARESTORE -a -d $MFS_MASTER_DATA_PATH
mv ${MFS_MASTER_DATA_PATH}/sessions_ml.mfs ${MFS_MASTER_DATA_PATH}/sessions.mfs
$MFSMASTER start
#${MFS_HOME}/sbin/mfscgiserv restart
}
function master2backup() {
$MFSMASTER stop
${MFS_HOME}/sbin/mfscgiserv -s
$MFSMETALOGGER start
}
function ERROR() {
echo 'USAGE: keepalived_notify.sh master|backup';
}
case $1 in
master)
backup2master
;;
backup)
master2backup
;;
*)
ERROR
;;
esac
注意看backup2master函数,这里我把mfsmetalogger的元数据全部cp过去了,并切同步了sessions,防止客户端需要重新挂载。
backup132上的目录结构:
[admin@ /usr/local/mfs/script]# cd /data/
[admin@ /data]# ls -al
total 44
drwxr-xr-x 8 admin root 4096 May 6 16:32 .
drwxr-xr-x 24 admin root 4096 May 6 16:32 ..
drwxrwxr-x 2 potadm app 4096 Mar 21 15:36 logs
drwx------ 2 admin root 16384 Mar 20 18:01 lost+found
drwxr-xr-x 2 mfs mfs 4096 May 6 16:42 mfs
drwxr-xr-x 2 mfs mfs 4096 May 6 16:12 mfs_master_backup
drwxr-xr-x 2 admin root 4096 Mar 21 10:20 tsysdata
我做了两个目录,mfs目录专门给metalogger用,mfs_master_backup目录是给mfs的Master备用工作目录。这样master和metalogger是不相同的,互不干涉!
如果131回复,我们要重新把master从132切到131上,切的脚本为:
#!/bin/sh
scp admin@192.168.40.132:/data/mfs_master_backup/* /data/mfs/
mv /data/mfs/metadata.mfs.back metadata.mfs
/usr/local/mfs/sbin/mfsmaster start
/usr/local/keepalived/etc/rc.d/init.d/keepalived start
把132上的所有Log和会话文件和metadata全拷贝过去,重名名元数据文件,把master启动起来,再把keepalived的master启动即可!
不可否认,中间确实存在隐含的问题,比如文件正在读写什么的,每次发生故障切换一次肯定有文件要损坏,但是就在几秒内。
参考:http://hi.baidu.com/zhengkungong/item/68f85e37a86103ae134b1450 http://www.cnblogs.com/oubo/archive/2012/05/04/2482893.html http://hi.baidu.com/zhengkungong/item/e28f0acac27b643c46d5c050
接上面,经过这几天的测试,发现很多有意思的东西,网上的资料和官网的英文翻译对master和metalogger之间的容灾备份含糊其词,不准确,于是我测试了一下。
总的来说metalogger对Master的热备相当靠谱,基本在秒级,如果master切换在3--5s内完成,也就对数据造成的影响在这3--5s中之间,不会对其他的文件造成影响,也就是说master发生故障最坏的情况是丢失切换的的这2--3s的数据。
恢复的原理不变,就是上面开头提到的。 但是我们来看看具体mater的元数据文件夹和metalogger的元数据文件夹的区别在哪里?
master
metalogger
master文件metadata大小为1029874, metaLogger的metadata_ml.mfs.back文件大小相等,另外metaLogger的chongelog_ml.0.mfs和Master的changelog.0.mfs也是秒级同步的, 来自:http://www.moosefs.org/reference-guide.html#using-moosefs 按照官网上的介绍,只要获取metadata.mfs.back 在加上changelog就可以恢复文件系统了。
测试过程:
测试脚本:
#!/bin/sh
FILE_SUM=1000000
TARGET_FILE=/mnt/mfs/test
START=0
while [ $START -le $FILE_SUM ]
do
dd if=/dev/zero of=$TARGET_FILE/$START bs=1KB count=1
date
date > $TARGET_FILE/$START
START=`expr $START + 1`
sleep 1
done
搞好多文件,一秒钟搞一个,把当前时间写进去。
kill掉mater 脚本运行停止一段时间,然后继续跑起来 客户端日志如下: ay 8 14:03:25 mfsmount[16012]: master: connection lost (1) May 8 14:03:25 mfsmount[16019]: master: connection lost (1) May 8 14:03:25 mfsmount[16012]: can't connect to master ("192.168.40.15":"10072") May 8 14:03:25 mfsmount[16019]: can't connect to master ("192.168.40.15":"10072") May 8 14:03:36 mfsmount[16019]: master: register error (read header: Connection refused) May 8 14:03:36 mfsmount[16012]: master: register error (read header: Connection refused) May 8 14:03:38 mfsmount[16012]: master: register error (read header: Connection refused) May 8 14:03:38 mfsmount[16019]: master: register error (read header: Connection refused) May 8 14:03:40 mfsmount[16012]: registered to master May 8 14:03:40 mfsmount[16019]: registered to master May 8 14:03:41 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:03:41 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:03:41 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:03:42 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:03:43 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:03:44 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:03:46 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:03:48 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:03:50 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:03:53 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:03:56 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:03:59 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:04:03 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:04:07 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:04:11 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:04:16 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12 May 8 14:04:21 mfsmount[16019]: file: 9014, index: 0 - fs_writechunk returns status 12
03:25开始切,03:40连接master成功,发现文件9014有错误, [root@/mnt/mfs/test]# cat 9010 cat: 9010: No such file or directory [root@/mnt/mfs/test]# cat 9009 cat: 9009: No such file or directory [root@/mnt/mfs/test]# cat 9008 cat: 9008: No such file or directory [root@/mnt/mfs/test]# cat 9007 cat: 9007: No such file or directory [root@/mnt/mfs/test]# cat 9006 cat: 9006: No such file or directory [root@/mnt/mfs/test]# cat 9005 Wed May 8 14:03:24 CST 2013
查看文件我们发现1--9005号文件全正常也就是说,这次切换 03:24之前的文件没有问题 [root@/mnt/mfs/test]# cat 8000 Wed May 8 13:46:24 CST 2013 [root@/mnt/mfs/test]# cat 6999 Wed May 8 13:29:28 CST 2013 [root@/mnt/mfs/test]# cat 5003 Wed May 8 12:55:42 CST 2013 [root@/mnt/mfs/test]# cat 4102 Wed May 8 12:40:28 CST 2013 [root@/mnt/mfs/test]# cat 1102 Wed May 8 11:49:43 CST 2013 [root@/mnt/mfs/test]# cat 1 Wed May 8 11:31:06 CST 2013
测试程序的中断: 1+0 records in 1+0 records out 1000 bytes (1.0 kB) copied, 0.00183204 s, 546 kB/s Wed May 8 16:36:54 CST 2013 1+0 records in 1+0 records out 1000 bytes (1.0 kB) copied, 0.0022054 s, 453 kB/s Wed May 8 16:36:55 CST 2013
中断了.....
1+0 records in 1+0 records out 1000 bytes (1.0 kB) copied, 0.00216818 s, 461 kB/s Wed May 8 16:37:14 CST 2013 1+0 records in 1+0 records out 1000 bytes (1.0 kB) copied, 0.0022239 s, 450 kB/s Wed May 8 16:37:15 CST 2013 1+0 records in 1+0 records out 1000 bytes (1.0 kB) copied, 0.00202958 s,
通过这个我们可以看到,就中断了大约9s。
也就是说程序在卡了大约9s钟之后继续运行起来了。 我也测试过,在client重新连接上Msater这个时间之后对挂载目录进行读写操作没有问题。 也就是说,只要客户端重新连接上Master,读写就可以恢复。
综上,我又从备机把mater切回到主机上,客户端Log为: May 8 14:07:58 mfsmount[16012]: master: connection lost (1) May 8 14:07:58 mfsmount[16019]: master: connection lost (1) May 8 14:08:01 mfsmount[16012]: master: register error (read header: Connection refused) May 8 14:08:01 mfsmount[16019]: master: register error (read header: Connection refused) May 8 14:08:03 mfsmount[16012]: master: register error (read header: Connection refused) May 8 14:08:03 mfsmount[16019]: master: register error (read header: Connection refused) May 8 14:08:05 mfsmount[16012]: master: register error (read header: Connection refused) May 8 14:08:05 mfsmount[16019]: master: register error (read header: Connection refused) May 8 14:08:07 mfsmount[16012]: master: register error (read header: Connection refused) May 8 14:08:07 mfsmount[16019]: master: register error (read header: Connection refused) May 8 14:08:09 mfsmount[16019]: master: register error (read header: Connection refused) May 8 14:08:09 mfsmount[16012]: master: register error (read header: Connection refused) May 8 14:08:11 mfsmount[16012]: registered to master May 8 14:08:11 mfsmount[16019]: registered to master
通过上面的测试我们可以看出,基本切一次数据丢失不多,在承受范围内(哪个文件系统出了故障还不得丢点数据)
测热备方案的缺陷: 1.master判断是否正常太过粗糙,哪个不懂的上机器给乱整一下,本来好好的,keepalived不知道怎么倒了给切一次,就损失几秒数据 2.master切到和metalogger同一台机器之后,我们还是要把master再还原回去啊,这还原又是一个问题,上面我的方案是一种非常暴力的做法,会把在备机切换时间段内的文件全部丢失, 我也想了一下,遇到这样的情况有两种办法来恢复, 1.还是利用metaLogger的元数据,scp过来之后做一次restore,然后同时起mater和Keepalived 2.将本机上的master元数据scp过来之后,建议也做一个restore,建议这样做的时候停机维护一下,将备机Master也stop了,手放快点,我担心如果不停机的话,这个这么活生生的cp过来的changelog有问题, 有待继续测试。