Rsync简介
Rsync(remote synhronize)是一个远程数据同步共组,可通过LAN/WAN快速同步多台主机间的文件。Rsync使用所谓的“Rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。
Rsync的优点与缺点
优点:
- 快速:第一次同步完成后,下次只会传输修改过的文件。
- rsync:rsync允许通过ssh协议来加密传输数据,也可以使用socket连接。
- 更少的带宽:rsync在传输过程中可以压缩传输。
- 无需要特殊权限。
缺点:
- 由于rsync同步算法需要扫描文件后进行对比,所以rsync并不适合大数据的传输,单独rsync并不能实时检测文件的变化,大多都是处于计划任务中运行。
Inotify简介
Inotify是一种强大的,细粒度的,异步的文件系统监控机制。Linux内核从2.6.13起,加入了inotify支持,通过inotify可以监控文件系统中添加,删除,修改,移动等各种细微时间,利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况,而inotify-tool就是这样的一个第三方软件。
Rsync+Inotify组合
rsync_inotify
简单实际案例,公司存在多台web server,用户通过负载均衡随机访问其中一台服务器,程序员更新版本,只需要更新一台同步服务器,他所更新的内容将由rsync+intify自动同步到线上web server。
Rsync服务端准备
- 安装rsync服务器
1 | [root@node1 ~]#rpm -qa | grep rsync |
2 | [root@node1 ~]#yum install rsync |
3 | 创建rsync的配置文件 |
4 | [root@node1 ~]#vim /etc/rsyncd.conf |
5 | port=873 #监听端口 |
6 | #address=127.0.0.1 #监听地址,默认0.0.0.0 |
7 | use chroot=yes # 是否限制在指定目录,为了安全,一般需要启动 |
8 | read only=no #如果需要只是需要从服务器拉取数据,选择yes,如果需要推送数据到服务器,选择no |
9 | hosts allow=10.211.55.0/24 #允许的网段,全局配置 |
10 | max connections = 5 #最大连接数 |
11 | timeout = 300 #连接超时时间 |
12 | motd file = /etc/rsyncd/rsyncd.motd |
13 | log file = /var/log/rsyncd.log |
14 | pid file = /var/run/rsyncd.pid |
15 | lock file = /var/lock/rsyncd.lock |
16 | [server] #单个模块设置 |
17 | path=/data/web #此模块对应的路径 |
18 | ignore errors #忽略无关的io报错 |
19 | list = no #禁止展开列表 |
20 | #hosts allow= #针对该模块的访问限制,可以对单个模块作出限制 |
21 | auth users = web #认证用户名 |
22 | secrets file =/etc/web.passwd #认证密码文件 |
- 启动服务器
1 | [root@node1 ~]#mkdir -pv /data/web |
2 | [root@node1 ~]#echo "web:123456789" > /etc/web.passwd |
3 | [root@node1 ~]#chmod 600 /etc/test.passwd |
4 | [root@node1 ~]#rsync --daemon --config=/etc/rsyncd.conf |
5 | [root@node1 ~]#echo "rsync --daemon --config=/etc/rsyncd.conf" >> /etc/rc.local |
6 | [root@node1 my]# ss -ntlp |
7 | State Recv-Q Send-Q Local Address:Port Peer Address:Port |
8 | LISTEN 0 5 :::873 :::* |
9 | users:(("rsync",3861,5)) |
10 | LISTEN 0 5 *:873 *:* |
11 | users:(("rsync",3861,4)) |
12 | LISTEN 0 50 *:3306 *:* |
13 | users:(("mysqld",1521,10)) |
14 | LISTEN 0 128 :::22 :::* |
15 | users:(("sshd",1371,4)) |
16 | LISTEN 0 128 *:22 *:* |
17 | users:(("sshd",1371,3)) |
18 | LISTEN 0 128 127.0.0.1:631 *:* |
19 | users:(("cupsd",1327,7)) |
20 | LISTEN 0 128 ::1:631 :::* |
21 | users:(("cupsd",1327,6)) |
22 | LISTEN 0 100 ::1:25 :::* |
23 | users:(("master",1616,13)) |
24 | LISTEN 0 100 127.0.0.1:25 |
这样我么就设置好服务器端的配置与服务,终上整个案例,这些配置是需要在两台web服务器上作出的rsync服务器配置,在整个服务器配置中我们需要注意的是:
- rsync配置共设置了两层安全配置,白名单和密码文件
- rsync密码文件必须为600权限,禁止除拥有者外的用户修改与查看
- rsync密码文件在配置的时候需要按照 ‘用户名:密码’ 的格式配置,可以配置多个
Rsync+Inotify实时同步客户端配置
- 安装rsync与测试rsync
1 | [root@node2 ~]# yum install -y rsync |
2 | [root@node2 ~]# echo '123456789' > /etc/web.passwd |
3 | [root@node2 ~]# chmod 600 /etc/web.passwd |
4 | [root@node2 ~]# rsync -avz /etc/fstab --password-file=/etc/web.passwd web@10.211.55.35::server |
- 安装inotify
测试可以正常同步文件,这样rsync我们就准备好了,由于inotify特性需要linux内核版本的支持,在安装inotify-tools前要确认linux系统内核是否达到了2.6.13以上,如果没有,就要重新编译内核。
1 | [root@node2 ~]# uname -a |
2 | Linux node2 2.6.32-642.el6.x86_64 #1 SMP Tue May 10 17:27:01 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux |
3 | [root@node2 ~]# ll /proc/sys/fs/inotify/ |
4 | total 0 |
5 | -rw-r--r-- 1 root root 0 Feb 14 02:52 max_queued_events |
6 | -rw-r--r-- 1 root root 0 Feb 14 02:52 max_user_instances |
7 | -rw-r--r-- 1 root root 0 Feb 14 02:52 max_user_watches |
- /proc/sys/fs/inotify/max_queued_evnets 表示调用inotify_init时分配给inotify instance中可排队的event的数目的最大值,超出这个值的事件被丢弃,但会触发IN_Q_OVERFLOW事件。
- /proc/sys/fs/inotify/max_user_instances 表示每一个real user ID可创建的inotify instatnces的数量上限。
- /proc/sys/fs/inotify/max_user_watches 表示每个inotify instatnces可监控的最大目录数量。如果监控的文件数目巨大,需要根据情况,适当增加此值的大小。
1 | [root@node2 ~]# wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz |
2 | [root@node2 ~]# tar xf inotify-tools-3.14.tar.gz |
3 | [root@node2 ~]# cd inotify-tools-3.14 |
4 | [root@node2 inotify-tools-3.14]# ./configure |
5 | [root@node2 inotify-tools-3.14]# make && make install |
inotifywait [opotion]:
- -r #递归查询目录
- -q #打印监控事件信息
- -m #始终保持事件监听状态
- –excludei {pattern} #排除文件或目录,不区分大小写
- –timefmt {fmt} #打印指定的输出类似格式字符串
-e #通常此参数可以指定需要监控的事件
1 | Events: |
2 | access file or directory contents were read #文件或目录被读取 |
3 | modify file or directory contents were written #文件或目录内容被修改 |
4 | attrib file or directory attributes changed #文件或目录属性被修改 |
5 | close_write file or directory closed, after being opened in |
6 | writeable mode #文件或目录被关闭,在后可写模式 |
7 | close_nowrite file or directory closed, after being opened in |
8 | read-only mode #文件或目录被关闭,在后可读模式 |
9 | close file or directory closed, regardless of read/write mode #文件或目录被关闭,无论读写 |
10 | open file or directory opened #文件或目录被打开 |
11 | moved_to file or directory moved to watched directory #文件或目录移动到另一个目录 |
12 | moved_from file or directory moved from watched directory #文件或目录从别地目录移到当前目录 |
13 | move file or directory moved to or from watched directory #文件或目录从移到另一个目录或者从别地目录移到当前目录 |
14 | create file or directory created within watched directory #文件或目录被当前目录创建 |
15 | delete file or directory deleted within watched directory #文件或目录在当前目录删除 |
16 | delete_self file or directory was deleted #文件或目录被删除 |
17 | unmount file system containing file or directory unmounted #文件系统被卸载 |
inotify脚本示例
1 | [root@node2 ~]#vim inotify.sh |
2 | #!/bin/bash |
3 | hosts={10.211.55.35,10.211.55.36} #同步的目标主机 |
4 | src=/data/web #本地监控的目录 |
5 | dst=server #inotify-slave的rsync服务的模块名 |
6 | user=web #rsync服务的虚拟用户 |
7 | rsync_passfile=/etc/web.passwd #本地调用rsync服务的密码文件 |
8 | inotify_home=/usr/local/bin/ |
9 | if [ ! -e "$src" ] \ |
10 | || [ ! -e "${rsync_passfile}" ] \ |
11 | || [ ! -e "${inotify_home}/inotifywait" ] \ |
12 | || [ ! -e "/usr/bin/rsync" ]; |
13 | then |
14 | echo "Check File and Folder" |
15 | exit 9 |
16 | fi |
17 | ${inotify_home}/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e close_write,delete,create,attrib $src \ |
18 | | while read file |
19 | do |
20 | for host in ${hosts};do |
21 | rsync -avzP --delete --password-file=${rsync_passfile} $src $user@${host}::$dst >/dev/null 2>&1 |
22 | done |
23 | done |
我们来运行脚本:
1 | [root@node2 ~]# bash -x inotify.sh |
2 | + hosts={10.211.55.35,10.211.55.36} |
3 | + src=/date/web |
4 | + dst=server |
5 | + user=web |
6 | + rsync_passfile=/etc/web.passwd |
7 | + inotify_home=/usr/local/bin/ |
8 | + read file |
9 | + /usr/local/bin//inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e close_write,delete,create,attrib /etc/hosts |
10 | + for host in '${hosts}' |
11 | + rsync -avzP --delete --password-file=/etc/test.pass /etc/hosts web@10.211.55.35::server |
12 | + rsync -avzP --delete --password-file=/etc/test.pass /etc/hosts web@10.211.55.36::server |
13 | + read file |
我们修改了下/data/web下的数据,这个脚本将会立即执行同步操作。
我们可以nuhup ./inotify.sh &
启动,忽略挂断信号并在后台一致运行,这样我们就可以一直监视着指定目录的变化,并第一时间同步线上服务器,方便高效。
最后解释下rsync的几个选项:
1 | --delete:本地与服务器完全一样,如果本地存在不一样的,则删除,慎用 |
2 | --password-file:指定密码文件,如果不指定,则需手动输入 |
3 | -a :参数,相当于-rlptgoD,-r 是递归 -l 是链接文件,意思是拷贝链接文件;-p 表示保持文件原有权限;-t 保持文件原有时间;-g 保持文件原有用户组;-o 保持文件原有属主;-D 相当于块设备文件; |
4 | -z :传输时压缩; |
5 | -P :传输进度; |
6 | -v :传输时的进度等信息 |
7 | -u :--update 仅仅进行更新,也就是跳过所有已经存在于DST,并且文件时间晚于要备份的文件。(不覆盖更新的文件 |