5)NFS存储实时复制原理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5)NFS存储实时复制原理相关的知识,希望对你有一定的参考价值。

项目案例:

1、sudo集权分治的权限管理及命令行日志审计

2、全网数据备份解决方案

3、共享存储实时备份(共享存储的单点解决方案)

第一个里程碑: 1)实现从NFS客户端到rsync服务端的rsync服务部署。

第二个里程碑: 1)实现从NFS客户端对NFS目录文件系统事件的实时监控。

第三个里程碑: 1)当监控到NFS目录文件系统事件变化后,触发rsync推送变化文件。

#!/bin/bash
/usr/bin/inotifywait -mrq --format ‘%w%f‘ -e close_write,delete /backip | while read file
 do
 cd /backup
    rsync -az "$file"  --delete [email protected]172.16.1.41::nfsbackup --password-file=/etc/rsync.password
 done

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

inotify实际是一种事件驱动机制,它为应用程序监控文件系统事件提供了实时响应事件的机制,而无需通过诸如cron等的轮询机制来获取事件。cron等机制不仅无法所做到实时性,而且消耗大量系统资源,相比之下,inotify基于事件驱动,可以做到对事件处理的实时响应,也没有轮询造成的系统资源消耗,是非常自然的事件通知接口,也与自然世界的事件机制相符合。

inotify的实现有几款软件

inotify-tools,SErsync(金山周洋),lsyncd.

特别说明:下面inotify配置是建立在rsync服务基础上的配置过程。

实施环境:

配置rsync服务,并且能在客户端推送和拉取。

[[email protected] ~]# rsync -avzP /data/ [email protected]172.16.1.41::nfsbackup --password-file=/etc/rsync.password
sending incremental file list

inotify实施准备

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

开始安装

在安装inotify-tools前请先确认你的Linux内核是否达到了2.6.13、并且在编译时开启CONFIG_INOTIFY选项,也可以通过以下命令检测

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

[[email protected] ~]# uname -r
2.6.32-642.6.2.el6.x86_64

[[email protected] ~]# ls -l /proc/sys/fs/inotify/
总用量 0
-rw-r--r-- 1 root root 0 1月  23 11:09 max_queued_events
-rw-r--r-- 1 root root 0 1月  23 11:09 max_user_instances
-rw-r--r-- 1 root root 0 1月  23 11:09 max_user_watches
(显示这三个文件则证明支持)
关键参数说明:

1)

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

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

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

max_queued_events:设置inotify实例事件(event)队列可容纳的事件数量。

2)下载inotify源码包

https://github.com/rvoicilas/inotify-tools/wiki#getting

直接yum安装提示错误

[[email protected] backup]# yum install inotify-tools
已加载插件:fastestmirror
设置安装进程
Loading mirror speeds from cached hostfile
 * base: mirrors.aliyun.com
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
No package inotify-tools available.
错误:无须任何处理

接下来使用第三方的源:

[[email protected] backup]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
--2017-01-23 13:43:48--  http://mirrors.aliyun.com/repo/epel-6.repo
正在解析主机 mirrors.aliyun.com... 112.124.140.210, 115.28.122.210, 112.124.140.210
正在连接 mirrors.aliyun.com|112.124.140.210|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:1083 (1.1K) [application/octet-stream]
正在保存至: “/etc/yum.repos.d/epel.repo”

100%[====================================================================>] 1,083       --.-K/s   in 0s      

2017-01-23 13:43:49 (90.3 MB/s) - 已保存 “/etc/yum.repos.d/epel.repo” [1083/1083])

[[email protected] backup]# yum install inotify-tools -y 


[[email protected] backup]# rpm -qa inotify-tools
inotify-tools-3.14-1.el6.x86_64

3)编译安装:

从下载inotify工具的源Github上项目页面然后编译并安装:

法一:

[[email protected] inotify-tools-3.14]# wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz

[[email protected] inotify-tools-3.14]# wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz

[ro[email protected] inotify-tools-3.14]# ./configure --prefix=/usr && make && su -c ‘make install‘

[[email protected] inotify-tools-3.14]# ./configure --prefix=/usr && make && su -c ‘make install‘
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make sets $(MAKE)... (cached) yes
checking for gcc... gcc
checking for C compiler default output file name... a.out
checking whether the C compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for style of include used by make... GNU
checking dependency style of gcc... gcc3
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking for a sed that does not truncate output... /bin/sed
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for fgrep... /bin/grep -F



centos 6 最小化安装之后,要安装所需要的库。之后再yum安装就可以了。

[[email protected] inotify-tools-3.14]# yum install gcc -y

[[email protected] backup]# yum install inotify-tools -y

法二:

wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz

tar zxf inotify-tools-3.14.tar.gz

cd inotify-tools-3.14

./configure --prefix=/usr && make && su -c ‘make install‘

make && make install

cd ../

ln -s /usr/local/inotify-tools-3.15 /usr/local/inotify-tools

ls -l /usr/local/|grep inotify

参数:
--prefix=PATH 指定编译安装的路径
提示:更多的编译参数可以使用./configure -h 查看,编译成功后会生成4个目录,分别是:

bin:inotify执行命令(二进制)

include:inotify程序所需用的头文件

lib:动态链接的库文件

share:帮助文档

cd /usr/local/inotify-tools/

tree

4)工具集介绍:

义工安装了两个工具(命令),即inotifywait和inotifywatch

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

[[email protected] ~]# which inotifywait
/usr/bin/inotifywait

[[email protected] ~]# /usr/bin/inotifywait --help        (查看帮助)

-r|--recursive	Watch directories recursively. (递归查询目录)
	
-q|--quiet    	Print less (only print events).  (打印很少的信息,仅仅打印监控事件的信息)

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

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

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

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

-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		file or directory closed, regardless of read/write mode(文件或目录封闭,无论读/写模式)
	
	open		file or directory opened(文件或目录被打开)
	
	moved_to	file or directory moved to 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(文件或目录被删除)

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

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

5)人工测试监控事件

开启两个窗口:

1、测试create

脚本实现 同步目录

[[email protected] scripts]# vim inotify.sh 
#!/bin/bash
Path=/data
Ip=172.16.1.41
/usr/bin/inotifywait -mrq --format ‘%w%f‘ -e close_write,delete $Path | while read file
 do
  cd $Path &&  rsync -az ./  --delete [email protected]$Ip::nfsbackup --password-file=/etc/rsync.password
 done

优化:让它同步文件

[[email protected] scripts]# cat inotify1.sh 
#!/bin/bash
Path=/data
Ip=172.16.1.41
/usr/bin/inotifywait -mrq --format ‘%w%f‘ -e close_write,delete $Path | while read file
 do
  cd $Path 
 if [ if $file ];then
  rsync -az $file  --delete [email protected]$Ip::nfsbackup --password-file=/etc/rsync.password
 else
   cd $Path &&  rsync -az ./  --delete [email protected]$Ip::nfsbackup --password-file=/etc/rsync.password
 fi
 done

通过start/stop控制inotify.sh脚本的启动和停止(高级架构师课程存储系统高可用时会用到)

[[email protected] scripts]# vim  /etc/init.d/syncd
#chkconfig: 2345 38 46
#this scripts is by created by oldboy

. /etc/init.d/functions

if [ $# -ne 1 ];then
   usage: $0 [start|stop]
   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 "inotif yservice 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|grep -v grep|wc -l` -eq 0 ];then
       action "inotify service is stopped" /bin/true
    else
       action "inotify service is stopped" /bin/false
    fi
   ;;
*)
    usage: $0 {start|stop}
    exit 1
esac


[[email protected] scripts]# chkconfig --add syncd

[[email protected] scripts]# chkconfig --list syncd

[[email protected] scripts]# chmod +x /etc/init.d/syncd 

[[email protected] scripts]# /etc/init.d/syncd start

[[email protected] scripts]# /etc/init.d/syncd start  (有时候需要开关再开就成功,多开几次)

[[email protected] scripts]# /etc/init.d/syncd stop

[[email protected] scripts]# ps -ef|grep inotify
成功后看一下端口

事件相关参数大小:

默认
[[email protected] data]# cd /proc/sys/fs/inotify/

[[email protected] inotify]# ls
max_queued_events  max_user_instances  max_user_watches

[[email protected] inotify]# cat max_queued_events 
16384

[[email protected] inotify]# cat max_user_instances 
128

[[email protected] inotify]# cat max_user_watches 
8192

关键参数说明:

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

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

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

max_queued_events:设置inotify实例事件(event)队列可容纳的事件数量。

实战调整

[[email protected] inotify]# cat /proc/sys/fs/inotify/max_user_watches 
8192

[[email protected] inotify]# cat /proc/sys/fs/inotify/max_user_instances 
128

[[email protected] inotify]# cat /proc/sys/fs/inotify/max_queued_events 
16384

[[email protected] inotify]# echo "655350" > /proc/sys/fs/inotify/max_queued_events 

[[email protected] inotify]# echo "655350" >/proc/sys/fs/inotify/max_user_watches 

[[email protected] inotify]# cat /proc/sys/fs/inotify/max_queued_events 
655350

[[email protected] inotify]# cat /proc/sys/fs/inotify/max_user_watches 
655350

调完之后重启可能会失效,所以放入rc.local里。

[[email protected] inotify]# vim /etc/rc.local 

[[email protected] inotify]# tail -3 /etc/rc.local 
#inotify by oldboy for laoda 20170123
echo "655350" > /proc/sys/fs/inotify/max_queued_events 
echo "655350" >/proc/sys/fs/inotify/max_user_watches

rsync+inotify实时数据同步并发简单测试

实时同步并发测试(测试的脚本等内容请见sersync部分):

10K-100K文件

每秒100个并发:

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

inotify优点:

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

inotify 缺点:

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

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

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

既然有了inotify-tools,为什么还要开发sersync?

SErsync功能多:

1)支持配置文件管理。

2)真正的守护进程socket。

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

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

5)默认多线程rsync同步。

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

1、inotify(SErsync)+rsync 是文件级别的。

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

3、第三方软件的同步功能:mysql同步,Oracle,mongodb

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

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

6、NFS集群(双写主存储,备存储用inotify(SErsync)+rsync,备没有找主解决延迟问题)

[[email protected] ~]# /etc/init.d/syncd stop
inotify service is stopped                                 [确定]
[[email protected] ~]# ps -ef|grep inotify
root       1917   1527  0 21:07 pts/0    00:00:00 grep inotify
[[email protected] ~]# chkconfig syncd off
[[email protected] ~]# chkconfig --list syncd
syncd          	0:关闭	1:关闭 	2:关闭	3:关闭	4:关闭	5:关闭	6:关闭

SErsync实时复制工具实践

http://study.oldboyedu.com/classModule/video/179199/182281/630837/0/0

安装sersync
程序名:sersync
安装目录:/application/sersync
主要的配置文件:/application/sersync/conf/confxml.xml
主要作用:用于提供文件同步的功能(发送)
注意:由于sersync依赖于rsync,因此,在安装Sersync之前,要先确定rsync是已经配置成功。
安装文件:sersync2.5.4_64bit_binary_stable_final.tar.gz

安装步骤:

1、上传sersync2.5.4_64bit_binary_stable_final.tar.gz到/project目录下

2、创建以下目录结构:

# mkdir /application/sersync/ -p
# mkdir /application/sersync/conf
# mkdir /application/sersync/bin
# mkdir /application/sersync/logs

3、并授予执行权限给sersync2.5.4_64bit_binary_stable_final.tar.gz

#chmod +x sersync2.5.4_64bit_binary_stable_final.tar.gz

4、并解压安装sersync

# tar zxvf sersync2.5.4_64bit_binary_stable_final.tar.gz
# cd /application/GNU-Linux-86


拷贝confxml.xml、sersync2两个文件

# cp confxml.xml /application/sersync/conf
# cp sersync2 /application/sersync/bin

改成SErsync名字
# mv bin/sersync2 bin/sersync

5、修改配置文件

# vim sersync/conf/confxml.xml

按照红色表示的内容及注释修改参数配置:

<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
# 设置本地IP和端口
    <host hostip="localhost" port="8008"></host>
# 开启DUBUG模式
    <debug start="false"/>
# 开启xfs文件系统
    <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和rsync模块名
	    <remote ip="172.16.1.41" name="nfsbackup"/>
	    <!--<remote ip="192.168.8.39" name="tongbu"/>-->
	    <!--<remote ip="192.168.8.40" name="tongbu"/>-->
	</localpath>
	<rsync>
	# rsync指令参数
	    <commonParams params="-avz"/>
	   # rsync同步认证,true开启密码验证。填上rsync密码配置文件里的用户和配置文件路径
	    <auth start="true" users="rsync_backup" passwordfile="/etc/rsync.password"/>
	    # 设置rsync远程服务端口,远程非默认端口则需打开自定义
	    <userDefinedPort start="false" port="874"/><!-- port=874 -->
	    # 设置超时时间
	    <timeout start="true" time="100"/><!-- timeout=100 -->
	   # 设置rsync+ssh加密传输模式,默认关闭,开启需设置ssh加密证书
	    <ssh start="false"/>
	</rsync>
	# SErsync传输失败日志脚本路径,每隔60会重新执行该脚本,执行完毕会自动清空。
	<failLog path="/application/logs/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
	# 设置rsync+crontab定时传输,整体同步,默认关闭,true开启,默认为600分钟
	<crontab start="false" schedule="600"><!--600mins-->
	# 是否开启过滤规则,默认不开启。
	    <crontabfilter start="false">
		<exclude expression="*.php"></exclude>
		<exclude expression="info/*"></exclude>
	    </crontabfilter>
	</crontab>
	# 设置SErsync传输后调用name指定的插件脚本,默认关闭。
	<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>


# chmod +x /application/sersync/bin/sersync 

[[email protected] application]# /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参数,则默认执行同步程序

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

[[email protected] data]# vim /etc/rc.local 

[[email protected] data]# tail -2 /etc/rc.local 
#########################
/application/sersync/bin/sersync -d -r -n 8 -o /application/sersync/conf/confxml.xml

以上是关于5)NFS存储实时复制原理的主要内容,如果未能解决你的问题,请参考以下文章

LAMP集群项目五 nfs存储的数据实时同步到backupserver

nfs存储服务实时同步

centos6.5 nfs实时共享

Rsync+inotify备份

sersync实时复制工具实践

MySQL主从复制