一、简介
Rsync 是一个远程数据同步工具,可通过 LAN/WAN 快速同步多台主机间的文件。Rsync 本来是用以取代rcp 的一个工具,它当前由 Rsync.samba.org 维护。Rsync 使用所谓的“Rsync 演算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。运行 Rsync server 的机器也叫 backup server,一个 Rsync server 可同时备份多个 client 的数据;也可以多个Rsync server 备份一个 client 的数据。
Rsync 可以搭配 rsh 或 ssh 甚至使用 daemon 模式。Rsync server 会打开一个873的服务通道(port),等待对方 Rsync 连接。连接时,Rsync server 会检查口令是否相符,若通过口令查核,则可以开始进行文件传输。第一次连通完成时,会把整份文件传输一次,下一次就只传送二个文件之间不同的部份。
Rsync 支持大多数的类 Unix 系统,无论是 Linux、Solaris 还是 BSD 上都经过了良好的测试。此外,它在windows 平台下也有相应的版本,比较知名的有 cwRsync 和 Sync2NAS。
1、基本特点
可以镜像保存整个目录树和文件系统;
可以很容易做到保持原来文件的权限、时间、软硬链接等;
无须特殊权限即可安装;
优化的流程,文件传输效率高;
可以使用 rcp、ssh 等方式来传输文件,当然也可以通过直接的 socket 连接;
支持匿名传输。
2、核心算法
假定在名为 α 和 β 的两台计算机之间同步相似的文件 A 与 B,其中 α 对文件A拥有访问权,β 对文件 B 拥有访问权。并且假定主机 α 与 β 之间的网络带宽很小。那么 Rsync 算法将通过下面的五个步骤来完成:
β 将文件 B 分割成一组不重叠的固定大小为 S 字节的数据块。最后一块可能会比 S 小。
β 对每一个分割好的数据块执行两种校验:一种是32位的滚动弱校验,另一种是128位的 MD4 强校验。
β 将这些校验结果发给 α。
α 通过搜索文件 A 的所有大小为 S 的数据块(偏移量可以任选,不一定非要是 S 的倍数),来寻找与文件B 的某一块有着相同的弱校验码和强校验码的数据块。这项工作可以借助滚动校验的特性很快完成。
α 发给 β 一串指令来生成文件 A 在 β 上的备份。这里的每一条指令要么是对文件 B 经拥有某一个数据块而不须重传的证明,要么是一个数据块,这个数据块肯定是没有与文件 B 的任何一个数据块匹配上的。
3、工作过程
- 机器A构造FileList,FileList包含了需要与机器B sync的所有文件信息对name->id,(id用来唯一表示文件例如MD5);
- 机器A将FileList发送到机器B;
- 机器B上运行的后台程序处理FileList,构建NewFileList,其中根据MD5的比较来删除机器B上已经存在的文件的信息对,只保留机器B上不存在或变化的文件;
- 机器A得到NewFileList,对NewFileList中的文件从新传输到机器B;
二、基本用法
2.1 -r 参数
-r表示递归,即包含子目录。如果目标文件是一个目录,-r是必须的,否则 rsync 运行不会成功
-p作用是保持文件属性
$ rsync -rp 源目录 目标目录
如果有多个文件或目录需要同步,可以写成下面这样。
$ rsync -r 源目录1 源目录2 目标目录
2.2 -a 参数
-a参数可以替代-r,除了可以递归同步以外,还可以同步元信息(比如修改时间、权限等。其作用等于:rtopgDl 参数的合体
-v 显示传输时的进度信息
-t 保持修改时间不变
-o 保持文件属主信息不变
-g 保持文件属组信息不变
如何让-o和-g生效,需要将配置文件uid和gid改为root,且fake super值改为no
-p 保持文件权限信息不变
-D 保持设备文件信息不变
-l 保持软链接文件属性不变
-P显示文件啊上传进度信息
#目标目录destination如果不存在,rsync 会自动创建。
#执行上面的命令后,源目录source被完整地复制到了目标目录destination下面,即形成了destination/source的目录结构
[root@backup clyu]# rsync -av source destination
如果只想同步源目录source里面的内容到目标目录destination,则需要在源目录后面加上斜杠。
#source目录里面的内容,就都被复制到了destination目录里面,并不会在destination下面创建一个source子目录
[root@backup clyu]# rsync -av source/ destination
2.3 -n 参数
如果不确定 rsync 执行后会产生什么结果,可以先用-n或–dry-run参数模拟执行的结果。
#-n参数模拟命令执行的结果,并不真的执行命令。-v参数则是将结果输出到终端,这样就可以看到哪些内容会被同步
[root@backup clyu]# rsync -anv source/ destination
-z 传输时压缩数据,提高传输速率
2.4 --delete 参数
默认情况下,rsync 只确保源目录的所有内容(明确排除的文件除外)都复制到目标目录。它不会使两个目录保持相同,并且不会删除文件。如果要使得目标目录成为源目录的镜像副本,则必须使用–delete参数,这将删除只存在于目标目录、不存在于源目录的文件。
$ rsync -av --delete source/ destination
上面命令中,–delete参数会使得destination成为source的一个镜像。
2.5 --exclude 参数
有时,我们希望同步时排除某些文件或目录,这时可以用–exclude参数指定排除模式。
#向服务器192.168.93.223推送数据
[root@save clyu]# tree dog
dog
├── dog1.txt
├── dog2.txt
├── dog3.txt
└── dog4.txt
[root@save clyu]# rsync -avz dog --exclude=dog1.txt --exclude=dog3.txt rsync_backup@192.168.93.223::backup --password-file=/etc/rsync.password
#在192.168.93.223服务器上查看数据
[root@backup backup]# tree dog
dog
├── dog2.txt
└── dog4.txt
三、远程同步:SSH 协议
这种远程同步不需要开启rsync服务
rsync 除了支持本地两个目录之间的同步,也支持远程同步。
它可以将本地内容,同步到远程服务器:
rsync -av source/ username@remote_host:destination
# 以clyu身份将demo文件夹拷贝到192.168.93.223服务器的/home/clyu文件夹下
[root@backup clyu]# rsync -av demo clyu@192.168.93.223:/home/clyu
# 以clyu身份将demo文件夹中到文件拷贝到192.168.93.223服务器的/home/clyu文件夹下,但不会拷贝demo目录
[root@backup clyu]# rsync -av demo/ clyu@192.168.93.223:/home/clyu
也可以将远程内容同步到本地:
rsync -av username@remote_host:source/ destination
# 将192.168.93.223服务器的/home/clyu文件夹下的demo.txt拷贝到本地文件夹
[root@backup clyu]# rsync -av 192.168.93.223:/home/clyu/demo.txt
四、远程同步:rsync协议
这种远程同步需要开启rsync服务
4.1 rsync服务端环境设置
4.1.1 下载rsync
[root@backup clyu]# yum install -y rsync
4.1.2 配置/etc/rsyncd.conf
uid = rsync #指定管理备份目录的用户,需要创建
gid = rsync #指定管理备份目录的用户组,需要创建
port = 873 #定义rsync备份服务的网络端口号
fake super = yes #将rsync虚拟用户伪装成超级管理员
use chroot = no #和安全相关的配置
max connections = 200 #最大连接数
timeout = 300 #超时时长,单位是秒
pid file = /var/run/rsyncd.pid #储存rsync服务进程的pid,自动生成
lock file = /var/run/rsync.lock #锁文件,自动生成
log file = /var/log/rsyncd.log #服务日志文件,自动生成
ignore errors #忽略传输中的简单错误,
read only = false #指定备份目录可读可写
list = false
hosts allow = 172.16.1.0/24 #白名单
hosts deny = 0.0.0.0/32 #黑名单
auth users = rsync_backup #指定认证用户
secrets file = /etc/rsync.password #指定认证用户密码文件,需要创建
[backup] #模块信息 ,可配置多个
comment = "模块注释"
path = /backup #模块中配置参数,指定模块的备份目录
4.1.3 创建rsync服务的虚拟用户
如果没有rsync用户,就要创建rsync用户
[root@backup clyu]# useradd rsync -M -s /sbin/nologin
[root@backup clyu]# id rsync
uid=1001(rsync) gid=1001(rsync) 组=1001(rsync)
4.1.4 设置/etc/rsync.password
[root@backup clyu]# echo "rsync_backup:123456">/etc/rsync.password
[root@backup clyu]# cat /etc/rsync.password
rsync_backup:123456
#设置文件权限
[root@backup clyu]# ll /etc/rsync.password
-rw-r--r-- 1 root root 20 12月 3 23:48 /etc/rsync.password
[root@backup clyu]# chmod 600 /etc/rsync.password
[root@backup clyu]# ll /etc/rsync.password
-rw------- 1 root root 20 12月 3 23:48 /etc/rsync.password
4.1.5 配置备份目录
[root@backup ~]# mkdir /backup
[root@backup /]# ll -d /backup/
drwxr-xr-x 2 root root 6 12月 3 23:53 /backup/
#修改备份目录用户组为配置文件的用户
[root@backup /]# chown rsync.rsync /backup/
[root@backup /]# ll -d /backup/
drwxr-xr-x 2 rsync rsync 6 12月 3 23:53 /backup/
4.1.6 启动rsync服务
[root@backup /]# systemctl restart rsyncd #重启启动
[root@backup /]# systemctl start rsyncd #启动
[root@backup /]# systemctl enable rsyncd #设置开机自启
4.2 推送数据到服务端
服务端ip是192.168.93.223
[root@save clyu]# ll boy.txt
-rw-r--r-- 1 root root 0 12月 4 00:03 boy.txt
[root@save clyu]# rsync -avz boy.txt rsync_backup@192.168.93.223::backup
Password:
sending incremental file list
boy.txt
rsync: chgrp ".boy.txt.XF0b6X" (in backup) failed: Operation not permitted (1)
sent 89 bytes received 126 bytes 47.78 bytes/sec
total size is 0 speedup is 0.00
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1179) [sender=3.1.2]
查看服务端/backup目录是否存在boy.txt
[root@backup backup]# ll
-rw------- 1 rsync rsync 0 12月 4 00:06 boy.txt
文件已经上传成功,那这个错误是什么原因?
因为源文件用户组和用户是root,而上传到服务端是以普通用户rsync的身份上传的。在普通用户rsync的身份下,要把其用户组和用户改为rsync,这就属于权限越界。所以就报这个错误。至于文件最后用户组和用户还是修改成功了,不知道啥原因。
如果想避免这个错误,可以在/etc/rsyncd.conf中报把fake super = yes
可以看到我们每次在客户端推送都要输入密码,可以不输入密码么。这件涉及到客户端的配置
4.3 客户端环境配置
客户端不需要开启rsync服务
1、创建密码文件
[root@backup clyu]# echo "123456">/etc/rsync.password
[root@backup clyu]# chmod 600 /etc/rsync.password
2、推送数据到服务端
[root@backup clyu]# rsync -avz boy.txt rsync_backup@192.168.93.223::backup --password-file=/etc/rsync.password
sending incremental file list
sent 49 bytes received 20 bytes 46.00 bytes/sec
total size is 0 speedup is 0.00
现实公司中,同一种服务器会有多台主机,所以如果我们想更细致的备份,那怎么办
192.168.93.211客户端,我们先要在备份目录dog下创建192.168.93.211目录,然后把需要备份的数据放到里面
rsync -avz /dog/ rsync_backup@192.168.93.223::backup --password-file=/etc/rsync.password
192.168.93.212客户端,我们先要在备份目录dog下创建192.168.93.212目录,然后把需要备份的数据放到里面
rsync -avz /dog/ rsync_backup@192.168.93.223::backup --password-file=/etc/rsync.password
查看192.168.93.223服务端backup
[root@backup backup]# tree
├── 192.168.93.211
├── 192.168.93.212
4.4 查看服务器模块信息
如果想知道服务器模块信息,可以操作一下命令
1、把/etc/rsyncd.conf中的list值设置为true
2、在客户端使用下面命令
[root@save clyu]# rsync rsync_backup@192.168.93.223::
backup "backup dir by ol dboy"
为了避免安全问题,还是不要开启这个功能,list值为false就好
4.5 验证数据的完整性
1、客户端发送数据
客户端备份目录最好和服务端一直,否则验证数据的完整性时,会出现文件查询不到的情况
#生成指纹文件
[root@save backup]# find /backup/ -type f -mtime -1 ! -name findger.txt|xargs md5sum >/backup/192.168.93.22/findger.txt
[root@save backup]# cat /backup/192.168.93.22/findger.txt
d41d8cd98f00b204e9800998ecf8427e /backup/192.168.93.22/dog1.txt
d41d8cd98f00b204e9800998ecf8427e /backup/192.168.93.22/dog2.txt
d41d8cd98f00b204e9800998ecf8427e /backup/192.168.93.22/dog3.txt
d41d8cd98f00b204e9800998ecf8427e /backup/192.168.93.22/dog4.txt
d41d8cd98f00b204e9800998ecf8427e /backup/192.168.93.22/dog5.txt
[root@save backup]# tree /backup
/backup
└── 192.168.93.22
├── dog1.txt
├── dog2.txt
├── dog3.txt
├── dog4.txt
├── dog5.txt
└── findger.txt
#发送数据
[root@save backup]# rsync -avz /backup/ rsync_backup@192.168.93.223::backup --password-file=/etc/rsync.password
2、服务端验证指纹文件
[root@backup backup]# tree /backup
/backup
└── 192.168.93.22
├── dog1.txt
├── dog2.txt
├── dog3.txt
├── dog4.txt
├── dog5.txt
└── findger.txt
[root@backup backup]# md5sum -c /backup/192.168.93.22/findger.txt
/backup/192.168.93.22/dog1.txt: 确定
/backup/192.168.93.22/dog2.txt: 确定
/backup/192.168.93.22/dog3.txt: 确定
/backup/192.168.93.22/dog4.txt: 确定
/backup/192.168.93.22/dog5.txt: 确定
我们可以把这个结果发送到邮箱中,便于我们查看
五、监控服务inotify学习
inotify 是一种文件系统的变化通知机制,如文件增加、删除等事件可以立刻让用户态得知,他里面一共安装了2个工具
inotifywait:在被监控的文件或目录上等待特定文件系统事件(open,close,delete等)发生,执行后处于阻塞状态,适合shell脚本中使用。
inotifywatch:收集被监视的文件系统使用度统计数据,指文件系统事件发生的次数统计。
#在客户端安装监控服务
[root@save data]# yum install -y inotify-tools
语法:inotifywait 参数 监控目录
-m : 实现一直监控目录变化 (如果没有这个参数,inotifywait默认只对目录监控一次)
-r : 实现递归监控 (如果没有这个参数,inotifywait默认只对监控目录一级文件进行监控)
-q : 打印很少的信息,仅仅打印监控事件的信息
–format : 打印使用指定的输出类似格式字符串
–timefmt : 指定时间输出的格式
-e : 通过此参数可以指定需要监控的事件
events 含义
access 文件或目录被读取
modify 文件或目录内容被修改
attrib 文件或目录属性被改变
close 文件或目录封闭,无论读/写模式
open 文件或目录被打开
move 文件或目录被移动到另一个目录或从另一个目录移动至当前目录
create 文件或目录被创建在当前目录
delete 文件或目录被删除
umount 文件系统被卸载
[root@save data]# inotifywait -m /data
Setting up watches.
Watches established.
//这边,我打开另一个窗口,创建了demo1.txt文件 故inotify产生如下信息
/data/ CREATE demo1.txt //文件被创建
/data/ OPEN demo1.txt //打开创建文件
/data/ ATTRIB demo1.txt //修改文件属性信息
/data/ CLOSE_WRITE,CLOSE demo1.txt //保存和关闭文件
//这边,我修改了demo1.txt文件 故inotify产生如下信息
/data/ OPEN demo1.txt //打开文件
/data/ MODIFY demo1.txt //修改文件
/data/ CLOSE_WRITE,CLOSE demo1.txt //保存和关闭文件
//这边,我删除了demo1.txt文件 故inotify产生如下信息
/data/ DELETE demo1.txt //删除文件
常用格式如下
[root@save data]# inotifywait -mrq --timefmt "%F" --format "%T %w %f 事件信息 %e" /data
2021-01-06 /data/ demo2.txt 事件信息 OPEN
2021-01-06 /data/ demo2.txt 事件信息 ATTRIB
2021-01-06 /data/ demo2.txt 事件信息 CLOSE_WRITE,CLOSE
六、实时同步服务sersync学习
软件是从https://github.com/wsgzao/sersync下载的
6.1 安装软件
# /server/tools/是我们自己创建的目录,用于放开发工具
[root@save data]# ll /server/tools/
-rw-r--r-- 1 root root 1981010 1月 6 17:14 sersync-master.zip
[root@save tools]# unzip sersync-master.zip //解压zip文件
[root@save tools]# ll sersync-master
-rw-r--r-- 1 root root 358772 8月 14 2015 inotify-tools-3.14.tar.gz
-rw-r--r-- 1 root root 10838 8月 14 2015 README.md
-rw-r--r-- 1 root root 890124 8月 14 2015 rsync-3.1.1.tar.gz
-rw-r--r-- 1 root root 727290 8月 14 2015 sersync2.5.4_64bit_binary_stable_final.tar.gz
[root@save tools]# cd sersync-master
[root@save sersync-master]# tar xf sersync2.5.4_64bit_binary_stable_final.tar.gz
[root@save sersync-master]# mv GNU-Linux-x86 /usr/local/sersync
6.2 配置confxml.xml文件
<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>
<!--rsync -az /data rsync_backup@192.168.93.223::backup --password-file=/etc/rsync.password-->
<localpath watch="/data"> <!--指定要监控的目录-->
<remote ip="192.168.93.223" name="backup"/> <!--ip是备份服务器地址,name是备份服务器的模块信息-->
<!--<remote ip="192.168.8.39" name="tongbu"/>-->
<!--<remote ip="192.168.8.40" name="tongbu"/>-->
</localpath>
<rsync> <!--指定rsync命令信息-->
<commonParams params="-az"/> <!--指定rsync的参数-->
<auth start="true" users="rsync_backup" passwordfile="/etc/rsync.password"/> <!--指定rsync的认证用户,和认证文件-->
<userDefinedPort start="true" port="873"/><!--rsync备份服务器的网络端口号-->
<timeout start="false" time="100"/><!-- 备份服务器和客户端链接超时时长 -->
<ssh start="false"/>
</rsync>
<failLog path="/tmp/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>
6.3 启动sersync服务
[root@save sersync]# ./sersync2
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
daemon thread num: 10
parse xml config file
host ip : localhost host port: 8008
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 12 = 1(primary thread) + 1(fail retry thread) + 10(daemon sub threads)
Max threads numbers is: 22 = 12(Thread pool nums) + 10(Sub threads)
please according your cpu ,use -n param to adjust the cpu rate
run the sersync:
watch path is: /data
[root@save /]# sersync2 -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参数,则默认执行同步程序