NFS服务实时备份(inotify、sersync)

时间:2022-09-14 07:31:44

目录
1 inotify
1.1 inotify简介
1.2 inotify实施准备
1.3 开始安装
1.4 inotifywait
1.5 inotify测试
1.6 实时备份测试
1.7 写一个inotify的服务启动脚本
1.8 inotify压力测试结果
1.9 inotify优缺点
2 sersync实时复制工具
2.1 sersync的功能
2.2 配置sersync
2.3 开启sersync
2.4 加入/etc/rc.local
3 高并发数据实时同步方案小结

操作环境:

1、nfs存储服务
参考文章:NFS共享存储服务

2、backup备份服务
参考文章:rsync备份服务搭建
备份原理:

通俗点说,如想实时同步/data目录,则inotify或sersync会实时监控/data下的block数量和inode数量,若发生变化,则会执行rsync去备份。

1 inotify

1.1 inotify简介

Inotify是一种强大的、细粒度的、异步的文件系统时间监控机制,linux内核从2.6.13起,加入了Inotify支持,通过Inotify可以监控文件系统中添加、删除、修改、移动等各时间,利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况,而inotify-tools正是实施这样监控的软件。国人周洋在金山公司开发的sersync。

1.2 inotify实施准备

大前提rsync daemon服务配置成功,可以在rsync客户端推送拉取数据,然后才能配置inotify服务。

1.3 开始安装

在安装inotify-tools前先确定当前系统内核是否达到了2.6.13,并且在编译时开启CONFIG_INOTIFY选项,也可以通过以下命令检测。

1)查看当前系统是否支持inotify

[root@nfs01 ~]# uname -r

2.6.32-696.el6.x86_64

[root@nfs01 ~]# ls -l /proc/sys/fs/inotify/

总用量 0

-rw-r--r-- 1 root root 0 1月 26 12:08 max_queued_events

-rw-r--r-- 1 root root 0 1月 26 12:08 max_user_instances

-rw-r--r-- 1 root root 0 1月 26 12:08 max_user_watches

#显示这三个文件则证明支持

#关键参数说明

在/proc/sys/fs/inotify目录下有三个文件,对inotify机制有一定的限制

max_queued_events:设置inotifywait或inotifywatch命令可以监视的文件数量(单进程)

max_user_instances:设置每个用户可以运行的inotifywait或inotifywatch命令的进程数

max_user_watches:设置inotify实例事件(event)队列可容纳的时间数量

2)下载inotify源码包或yum安装

#yum安装方法

[root@nfs01 ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo

[root@nfs01 ~]# yum -y install inotify-tools

[root@nfs01 ~]# rpm -qa inotify-tools

inotify-tools-3.14-1.el6.x86_64

#工具集介绍

一共安装了2个工具(命令)即:inotifywaitinotifywatch

inotifywait:在监控的文件或目录上等待特定文件系统事件(open、close、delete等)发生,执行后处于阻塞状态,适合在shell脚本中使用。

inotifywatch:收集被监视的文件系统使用度统计数据,指文件系统事件发生的次数统计。

1.4 inotifywait

[root@nfs01 ~]# inotifywait --help

Options:

-m|--monitor Keep listening for events forever. Without
this option, inotifywait will exit after one
event is received. #始终保持事件监听状态

-r|--recursive Watch directories recursively. #递归查询目录

-q|--quiet Print less (only print events).
#打印很少的信息,仅仅打印监控事件的信息

--excludei <pattern>
Like --exclude but case insensitive. #排除文件或目录时,不区分大小写

--format <fmt> Print using a specified printf-like format
string; read the man page for more details. #打印使用指定的输出类似格式字符串

--timefmt <fmt> strftime-compatible format string for use with
%T in --format string. #指定时间输出的格式

-e|--event <event1> [ -e|--event <event2> ... ]
Listen for specific event(s). If omitted, all events are
listened for. #通过此参数可以指定需要监控的事件,如下所示

Events:

access file or directory contents were read #文件或目录被读取

modify file or directory contents were written #文件或目录内容被修改

attrib file or directory attributes changed #文件或目录属性被改变

close_write file or directory closed, after being opened in
writeable mode

close_nowrite file or directory closed, after being opened in
read-only mode

close file or directory closed, regardless of read/write mode
#文件或目录封闭,无论(读/写模式)

open file or directory opened #文件或目录被打开

moved_to file or directory moved to watched directory
#文件或目录被移动至另外一个目录

moved_from file or directory moved from watched directory
#文件或目录从另一个目录移动至当前目录

move file or directory moved to or from watched directory

create file or directory created within watched directory
#文件或目录被创建在当前目录

delete file or directory deleted within watched directory #文件或目录被删除

delete_self file or directory was deleted

unmount file system containing file or directory unmounted #文件系统被卸载

1.5 inotify测试:

一个终端开两个页面:

1、测试create:

#第一个终端用来监控(监控/backup目录下文件的创建),此终端会实时显示目录下文件的情况

[root@nfs01 ~]# inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T%w%f' -e create /backup

04/02/18 15:43 /backup/a

04/02/18 15:43 /backup/b

#第二个终端修改监控目录下的事件内容

[root@nfs01 backup]# touch a

[root@nfs01 backup]# echo 111 \>b

[root@nfs01 backup]# ls

a b

2、测试delete:

#第一个终端用来监控(监控/backup目录下文件的创建和删除),此终端会实时显示目录下文件的情况

[root@nfs01 ~]# inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T%w%f' -e create,delete /backup

04/02/18 15:45 /backup/a

#第二个终端修改监控目录下的事件内容

[root@nfs01 backup]# rm -f a

[root@nfs01 backup]# ls

b

3、测试close_write(创建,写)

#第一个终端:

[root@nfs01 ~]# inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T%w%f' -e close_write /backup

04/02/18 15:51 /backup/c

04/02/18 15:51 /backup/k

04/02/18 15:51 /backup/k

04/02/18 15:51 /backup/k

04/02/18 15:51 /backup/k

#第二个终端

[root@nfs01 backup]# touch c

[root@nfs01 backup]# echo 123>>k

[root@nfs01 backup]# echo 123>>k

[root@nfs01 backup]# echo 123>>k

[root@nfs01 backup]# echo 123>>k

[root@nfs01 backup]# rm -f c

#可以简化事件输出

[root@nfs01 backup]# inotifywait -mrq --format '%w%f' -e close_wait /backup

1.6 实时备份测试

1、实现从nfs客户端到rsync服务端的rsync服务部署

#backup服务端准备,在配置文件中新创建一个nfsbackup模块,用于测试

[root@backup ~]# cat /etc/rsyncd.conf

#rsync_config_________________start

#created by rsq

##rsyncd.conf start##

uid = rsync

gid = rsync

use chroot = no

max connections = 200

timeout = 300

pid file = /var/run/rsyncd.pid

lock file = /var/run/rsync.lock

log file = /var/log/rsyncd.log

ignore errors

read only = false

list = false

hosts allow = 192.168.90.0/24

host deny = 0.0.0.0/32

auth users = rsync_backup

secrets file = /etc/rsync.password

[backup] #模块一

path = /backup/

[nffsbackup] #模块二

path = /nfsbackup

#rsync_config_________________end

[root@backup ~]# pkill rsync

[root@backup ~]# lsof -i tcp:873

[root@backup ~]# rsync --daemon

[root@backup ~]# lsof -i tcp:873

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

rsync 14676 root 3u IPv4 74687 0t0 TCP *:rsync (LISTEN)

rsync 14676 root 5u IPv6 74688 0t0 TCP *:rsync (LISTEN)

[root@backup ~]# mkdir /nfsbackup

[root@backup ~]# chown -R rsync. /nfsbackup

2、实现nfs客户端对nfs目录文件系统事件的实时监控

详见1.5 inotify测试

3、当监控到nfs目录文件系统事件变化后,触发rsync推送变化的文件。

#写个脚本,来测试

[root@nfs01 ~]# cat /server/scripts/inotify.sh
#!/bin/bash
PATH=/data
IP=192.168.90.41

/usr/bin/inotifywait -mrq --format '%w%f' -e close_write,delete $PATH \
|while read file
do
#判断读取到的文件是否存在,存在的话就增量备份,否则全量备份
if [ -f $file ];then
/usr/bin/rsync -az $file --delete rsync_backup@$IP::nfsbackup --password-file=/etc/rsync.password
else
cd $PATH && \
/usr/bin/rsync -az ./ --delete rsync_backup@$IP::nfsbackup --password-file=/etc/rsync.password
done

#开两个nfs终端(一个执行脚本,一个修改当前目录下文件状态),一个backup终端(用于检测是否有数据备份)

#nfs终端1

[root@nfs01 ~]# sh -n /server/scripts/inotify.sh

[root@nfs01 ~]# sh -x /server/scripts/inotify.sh
+ PATH=/data
+ IP=192.168.90.41
+ read file
+ /usr/bin/inotifywait -mrq --format %w%f -e close_write,delete /data
+ cd /data
+ /usr/bin/rsync -az ./ --delete rsync_backup@192.168.90.41::nfsbackup
--password-file=/etc/rsync.password
+ read file
+ cd /data
+ /usr/bin/rsync -az ./ --delete rsync_backup@192.168.90.41::nfsbackup
--password-file=/etc/rsync.password
+ read file

#nfs终端2

[root@nfs01 data]# touch 2

[root@nfs01 data]# rm -f 2

#backup终端

[root@backup nfsbackup]# ls

1 2 oldboy.txt

[root@backup nfsbackup]# ls

1 oldboy.txt

#在backup终端/nfsbackup目录下使用watch ls,可以实时监控ls所显示的目录下文件列表,默认每隔两秒显示一下ls的结果

[root@backup nfsbackup]# watch ls

Every 2.0s: ls Tue Feb 6 12:22:59 2018

1

3

4

5

6

oldboy.txt

1.7 写一个inotify的服务启动脚本

[root@nfs01 ~]# cat /etc/init.d/syncd
#!/bin/bash
#chkconfig: 2345 38 46
#############################################################################
#this scripts is inotify start or stop
#############################################################################
. /etc/rc.d/init.d/functions

function usage(){
echo "$0 {start|stop}"
}

if [ $# -ne 1 ];then
usage
exit 1
fi

case "$1" in
start)
/bin/bash /server/scripts/inotify.sh &
echo $$ >/var/run/inotify.pid
if [ `ps -ef|grep inotify|wc -l` -gt 2 ];then
action "inotify service is started" /bin/true
else
action "inotify service is started" /bin/false
fi
;;

stop)
kill -9 `cat /var/run/inotify.pid` >/dev/null 2>&1
pkill inotifywait
sleep 2
if [ `ps -ef|grep inotify|wc -l` -eq 0 ];then
action "inotify service is stoped" /bin/true
else
action "inotify service is stoped" /bin/false
fi
;;

*)
usage
exit 1

esac

[root@nfs01 ~]# chkconfig --add syncd

[root@nfs01 ~]# chkconfig syncd on

1.8 inotify压力测试结果

经过测试,每秒200个文件并发,数据同步几乎无延迟(小于1s)

1.9 inotify优缺点

inotify优点:

1)监控文件系统时间变化,通过同步工具实现实时数据同步

inotify缺点:

1)并发如果大于200个文件(10-100K),同步就会有延迟。

2)我们前面写的脚本,每次都是全部推送一次,但确实是增量的。也可以只同步变化的文件,不变化的置之不理。

3)监控到事件后,调用rsync同步是单进程的(也可加&并发),sersync是多进程同步。

2 sersync实时复制工具

2.1 sersync的功能

1)支持配置文件管理

2)真正的守护进程socket

3)可以对失败文件定时重传(定时任务功能)

4)第三方HTTP接口(例如更新cdn缓存)

5)默认多线程rsync同步

2.2 配置sersync

先从网上下载sersync的压缩包,解压到本地修改一些参数

有关64位sersync的压缩包我个人也有整理,可去以下链接下载,也可自行上网搜索下载。
由于必须要填资源分,故要使用2C币下载,要免费资源的可以私聊我,我单发。

http://download.csdn.net/download/mr_rsq/10244345

[root@nfs01 ~]# cd /application/

[root@nfs01 application]# ls

28-sersync.tar.gz sersync

[root@nfs01 application]# cd sersync/

[root@nfs01 sersync]# ls

bin conf GNU-Linux-x86 logs sersync2.5.4_64bit_binary_stable_final.tar.gz

[root@nfs01 sersync]# ll bin #执行文件

总用量 1768

-rwxr-xr-x. 1 root root 1810128 10月 26 2011 sersync

#注意要给执行权限(chmod -R +x /application/sersync/bin/)

[root@nfs01 sersync]# ll conf/

总用量 8

-rwxr-xr-x. 1 root root 2234 2月 7 11:41 confxml.xml

-rwxr-xr-x. 1 root root 2214 11月 27 10:27 confxml.xml.ori #配置文件的备份

[root@nfs01 sersync]# ll logs/

总用量 0

#以下贴上配置文件,使用的时候把带#好注释的去掉即可
[root@nfs01 ~]# cat /application/sersync/conf/confxml.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
<host hostip="localhost" port="8008"></host>
<debug start="false"/>
<fileSystem xfs="false"/>
<filter start="false">
<exclude expression="(.*)\.svn"></exclude>
<exclude expression="(.*)\.gz"></exclude>
<exclude expression="^info/*"></exclude>
<exclude expression="^static/*"></exclude>
</filter>
<inotify>
<delete start="true"/>
<createFolder start="true"/>
<createFile start="false"/>
<closeWrite start="true"/>
<moveFrom start="true"/>
<moveTo start="true"/>
<attrib start="false"/>
<modify start="false"/>
</inotify>

<sersync>
<localpath watch="/data">
#这里的ip地址需要修改成备份服务器ip,而不是本机ip地址
<remote ip="192.168.90.41" name="nfsbackup"/>
<!--<remote ip="192.168.8.39" name="tongbu"/>-->
<!--<remote ip="192.168.8.40" name="tongbu"/>-->
</localpath>
<rsync>
#下面的是rsync使用的参数,可自定义,也可以根扩展--delete等,来实现想要的备份方式
<commonParams params="-avz"/>
#下面是是否要启动,改成true即可,users为模块名,
<auth start="true" users="rsync_backup" passwordfile="/etc/rsync.password"/>
<userDefinedPort start="false" port="874"/><!-- port=874 -->
#下面这个可以设置超时时间
<timeout start="true" time="100"/><!-- timeout=100 -->
<ssh start="false"/>
</rsync>
#下面这个也需要注意,根据实际情况去修改
<failLog path="/application/logs/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
<crontab start="false" schedule="600"><!--600mins-->
<crontabfilter start="false">
<exclude expression="*.php"></exclude>
<exclude expression="info/*"></exclude>
</crontabfilter>
</crontab>
#这里是定时任务备份,自定义使用
<plugin start="false" name="command"/>
</sersync>

<plugin name="command">
<param prefix="/bin/sh" suffix="" ignoreError="true"/> <!--prefix /opt/tongbu/mmm.sh suffix-->
<filter start="false">
<include expression="(.*)\.php"/>
<include expression="(.*)\.sh"/>
</filter>
</plugin>

<plugin name="socket">
<localpath watch="/opt/tongbu">
<deshost ip="192.168.138.20" port="8009"/>
</localpath>
</plugin>
<plugin name="refreshCDN">
<localpath watch="/data0/htdocs/cms.xoyo.com/site/">
<cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
<sendurl base="http://pic.xoyo.com/cms"/>
<regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/>
</localpath>
</plugin>
</head>

2.3 开启sersync

[root@nfs01 ~]# /application/sersync/bin/sersync -h

set the system param

execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches

execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events

parse the command param

_______________________________________________________

参数-d:启用守护进程模式

参数-r:在监控前,将监控目录与远程主机用rsync命令推送一遍

c参数-n: 指定开启守护线程的数量,默认为10个

参数-o:指定配置文件,默认使用confxml.xml文件

参数-m:单独启用其他模块,使用 -m refreshCDN 开启刷新CDN模块

参数-m:单独启用其他模块,使用 -m socket 开启socket模块

参数-m:单独启用其他模块,使用 -m http 开启http模块

不加-m参数,则默认执行同步程序

________________________________________________________________

# 执行sersync及加载配置文件

[root@nfs01 ~]# /application/sersync/bin/sersync -d -r -n 8 -o /application/sersync/conf/confxml.xml

set the system param

execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches

execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events

parse the command param

option: -d run as a daemon

option: -r rsync all the local files to the remote servers before the sersync
work

option: -n thread num is: 8

option: -o config xml name: /application/sersync/conf/confxml.xml

parse xml config file

host ip : localhost host port: 8008

daemon start,sersync run behind the console

use rsync password-file :

user is rsync_backup

passwordfile is /etc/rsync.password

config xml parse success

please set /etc/rsyncd.conf max connections=0 Manually

sersync working thread 10 = 1(primary thread) + 1(fail retry thread) + 8(daemon
sub threads)

Max threads numbers is: 18 = 10(Thread pool nums) + 8(Sub threads)

please according your cpu ,use -n param to adjust the cpu rate

chmod: 无法访问"/application/logs/rsync_fail_log.sh": 没有那个文件或目录

------------------------------------------

rsync the directory recursivly to the remote servers once

working please wait...

execute command: cd /data && rsync -avz -R --delete ./ --timeout=100
rsync_backup\@192.168.90.41::nfsbackup --password-file=/etc/rsync.password
>/dev/null 2>&1

run the sersync:

watch path is: /data

#测试,和inotify测试一样,往/data目录中创建、删除或修改文件,然后去backup服务器中查看结果,这里不再演示

2.4 加入/etc/rc.local

[root@nfs01 ~]# vim /etc/rc.local

#sersync start

application/sersync/bin/sersync -d -r -n 8 -o application/sersync/conf/confxml.xml

3 高并发数据实时同步方案小结

1)inotify(sersync)+rsync,是文件级别的。

2)drbd文件系统级别,文件系统级别,基于block块同步,缺点:备节点数据不可用。

3)第三方软件的同步功能:mysql同步,oracle,mongodb。

4)程序双写,直接写两台服务器。

5)利用产品业务逻辑解决(读写分离,备读不到,读主)

6)NFS集群(1,4,5方案整合)(双写主存储,备存储用inotify(sersync)+rsync,备没有找主解决延迟问题)