RSYNC
概述
定义
rsync是Linux下的一款数据镜像备份工具
- sync数据同步:刷新文件系统缓存,强制将修改过的数据块写入磁盘,并且更新很快。
- async数据异步:将数据先放到缓冲区,再周期性(一般是30s)的去同步到磁盘。
- rsync 远程同步:remote sync
特点
-
可以镜像保存整个目录树和文件系统
-
可以保持原来文件的权限,时间,软硬链接,属性等
-
无须特殊权限即可安装
-
文件传输效率高,增量传输,只对变更的部分进行传送
-
可以使用 rcp、ssh 等方式来传输文件,当然也可以通过直接的 socket 连接
-
支持匿名传输
增量同步算法
我们将同步源文件名称为 fileSrc ,同步目的文件叫 fileDst 。
分块 Checksum 算法
-
我们会把 fileDst 的文件平均切分成若干个小块,然后对每块计算两个 checksum
-
一个叫 rolling checksum ,是弱checksum , 32 位的checksum
-
另一个是md5 checksum ,是强checksum,128 位的checksum
-
弱的 checksum (速度快)是用来区别不同,而强的是用来确认相同。
传输算法
-
同步目标端会把 fileDst 的一个 checksum 列表传给同步源,这个列表里包括了三个东西, rolling checksum(32bits),md5 checksume(128bits) ,文件块编号。
-
同步源机器拿到了这个列表后,会对 fileSrc 做同样的 checksum ,然后和 fileDst 的 checksum 做对比,这样就知道哪些文件块改变了。
但是,聪明的你一定会有以下两个疑问:
如果我 fileSrc 这边在文件中间加了一个字符,这样后面的文件块都会位移一个字符,这样就完全和fileDst 这边的不一样了,但理论上来说,我应该只需要传一个字符就好了。这个怎么解决?如果这个 checksum 列表特别长,而我的两边的相同的文件块可能并不是一样的顺序,那就需要查找,线性的查找起来应该特别慢。这个怎么解决?
checksum 查找算法
- 同步源端拿到 fileDst 的 checksum 数组后,会把这个数据存到一个 hash table (特殊的数据结构体,可以快速检索)中, hash table 的尺寸是 216,对 rolling checksum 的 hash 会被散列为0 到 216 – 1 中的某个整数值。
比对算法
-
取 fileSrc 的第一个文件块(我们假设的是 512 个长度),也就是从 fileSrc 的第 1 个字节到第512 个字节,取出来后做 rolling checksum 计算。计算好的值到 hash 表中查。
- 查到了,说明fileDst与fileSrc的第一个文件块可能相同 ,继续比较 md5 的 checksum
- 相同,说明在 fileDst 中有相同的块,记下这一块在fileDst 下的文件编号(出错的概率为1/2(32+128) =1/ 2160太小了可以忽略)
- 不同,算法会住后 step 1 个字节,取 fileSrc 中字节 2-513 的文件块要做 checksum,再去hash表中查
- 未查到,说明这一块中有不同的信息。,算法会住后 step 1 个字节,取 fileSrc 中字节 2-513 的文件块要做 checksum,再去hash表中查
- 查到了,说明fileDst与fileSrc的第一个文件块可能相同 ,继续比较 md5 的 checksum
-
这样,我们就能找到哪些是相同的文件块,哪些不同
传输
最终在同步源这端,我们的 rsync 算法可能会得到这个样子的一个数据数组,
- 红色块表示在目标端已匹配上,不用传-
- 白色的地方就是需要传输的内容(不定长)
- 这样,同步源这端把这个数组压缩传到目的端,在目的端的 rsync 会根据这个表重新生成文件,同步完成。
RSYNC基本用法
[root@server1 ~]# yum install -y rsync
[root@server1 ~]# man rsync
本地文件同步Local:rsync [OPTION...] SRC... [DEST]
远程文件同步Access via remote shell:
Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]
Push: rsync [OPTION...] SRC... [USER@]HOST:DEST
选项说明
-v 详细模式输出
-a 归档模式,相当于-rlptgoD
-R 保留相对路径
--delete删除多余文件
-e 指定要执行的远程shell命令,ssh更改端口常用选项
#下面了解
-r 递归拷贝目录
-l 保留软链接
-p 保留原有权限
-t 保留原有时间
-g 保留属组权限
-o 保留属主权限
-D 等于--devices --specials 表示支持b,c,s,p类型的文件
-H 保留硬链接
-A 保留ACL策略
-E 保留可执行权限
-X 保留扩展属性信息 a属性
本地文件同步
[root@server1 tmp]# mkdir dir1
[root@server1 tmp]# mkdir dir2
[root@server1 tmp]# touch dir1/{a..d}.txt
[root@server1 tmp]# mkdir dir3
[root@server1 tmp]# touch dir3/{e,f}.txt
[root@server1 tmp]# rsync -av dir1 dir2 将dir1目录同步到dir2中
[root@server1 tmp]# rsync -av dir3/ dir2 将dir3目录下的文件同步到dir2中
[root@server1 tmp]# ls dir2
dir1 e.txt f.txt
[root@server1 tmp]# mkdir -p dir4/dir4.1
[root@server1 tmp]# touch dir4/dir4.1/file1
[root@server1 tmp]# rsync -avR dir4/dir4.1/ dir2 保留相对路径
[root@server1 tmp]# ls dir2
dir1 dir4 e.txt f.txt
[root@server1 tmp]# rsync -av --delete dir1/ dir2 删除dir2中的多余文件
[root@server1 tmp]# ls dir2
a.txt b.txt c.txt d.txt
远程文件同步
[root@server1 tmp]# rsync -av dir2 root@192.168.226.20:/tmp 上传
The authenticity of host '192.168.226.20 (192.168.226.20)' can't be established.
ECDSA key fingerprint is SHA256:+RvxL8ZDWnyO030Z5rOfjBuJaOG1yFvD9ieOY9uzWBA.
ECDSA key fingerprint is MD5:d2:a2:8c:c6:60:15:46:9b:09:75:ce:3f:e1:ea:6e:aa.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.226.20' (ECDSA) to the list of known hosts.
root@192.168.226.20's password:
sending incremental file list
dir2/
dir2/a.txt
dir2/b.txt
dir2/c.txt
dir2/d.txt
sent 287 bytes received 96 bytes 153.20 bytes/sec
total size is 0 speedup is 0.00
[root@server1 tmp]# rsync -av root@192.168.226.20:/tmp/dir2/ /root 下载
root@192.168.226.20's password:
receiving incremental file list
./
a.txt
b.txt
c.txt
d.txt
sent 103 bytes received 271 bytes 149.60 bytes/sec
total size is 0 speedup is 0.00
[root@server1 tmp]# cd
[root@server1 ~]# ls
anaconda-ks.cfg a.txt b.txt c.txt d.txt
远程服务器更改了sshd端口号(22-->2882)
[root@server1 ~]# rsync -ave "ssh -p 2882" root@192.168.226.20:/dir1/ ./
部署RSYNC服务,定时备份
IP地址 | 主机名 |
---|---|
192.168.226.10 | server |
192,168.226.20 | Backup |
环境准备
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/SELINUX=enforced/SELINUX=disabled/' /etc/selinux/config
[root@server1 ~]# hostnamectl set-hostname server
[root@server1 ~]# su
[root@server2 ~]# hostnamectl set-hostname backup
[root@server2 ~]# su
ntpdate cn.ntp.org.cn #时间同步
yum install -y rsync
-----------------------------------------------------------------
启动服务
[root@server ~]# systemctl start rsyncd
[root@server ~]# systemctl status rsyncd
[root@server ~]# ps -ef |grep rsync
root 8701 1 0 13:17 ? 00:00:00 /usr/bin/rsync --daemon --no-detach
root 8733 8481 0 13:26 pts/0 00:00:00 grep --color=auto rsync
准备相应的文件
[root@server ~]# mkdir -p /app/java_project/
[root@server ~]# touch /app/java_project/file.java
修改配置文件
[root@server ~]# vim /etc/rsyncd.conf
1 # /etc/rsyncd: configuration file for rsync daemon mode
2
3 # See rsyncd.conf man page for more options.
4
5 # configuration example:
6
7 # uid = nobody
8 # gid = nobody
9 # use chroot = yes 是否禁锢目录
10 # max connections = 4 最大连接数
11 # pid file = /var/run/rsyncd.pid 进程文件,提供pid
12 # exclude = lost+found/ 忽略该目录
13 # transfer logging = yes 传输日志是否写入日志文件
14 # timeout = 900 超时时间
15 # ignore nonreadable = yes 是否忽略不可读文件
16 # dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 该格式文件不压缩
17
18 # [ftp]
19 # path = /home/ftp
20 # comment = ftp export area
21 [app]
22 path=/app/java_project 需要备份的文件路径
23 log file=/var/log/rsync.log 日志文件
[root@server ~]# systemctl restart rsyncd
-----------------------------------------------------------------
创建备份目录
[root@backup ~]# mkdir /backup/app/java_project -p
测试能否连接到rsync服务
[root@backup ~]# rsync -a root@192.168.226.10::
app
编写脚本
[root@backup ~]# touch rsync_java.sh
[root@backup ~]# chmod +x rsync_java.sh
[root@backup ~]# vim rsync_java.sh
1 #!/bin/bash
2 rsync -av root@192.168.226.10::app /back/app/java_project &>/dev/null
编写计划任务
[root@backup ~]# crontab -e
0 1 * * * /root/rsync_java.sh
如何给RSYNC服务添加密码:
[root@server ~]# vim /etc/rsyncd.secrets user1:1 user2:2 [root@server ~]# chmod 600 /etc/rsyncd.secrets [root@server ~]# vim /etc/rsyncd.conf 24 auth users=user1,user2 用户名 25 secrets file=/etc/rsyncd.secrets 存放用户密码 [root@server ~]# systemctl restart rsyncd [root@backup ~]# rsync -av user2@192.168.226.10::app Password:
文件实时同步
环境准备
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i 's/SELINUX=enforced/SELINUX=disabled/' /etc/selinux/config
yum install -y rsync.x86_64
systemctl start rsyncd
#backup端也要启动rsync服务
安装inotify-tools监控器
[root@server ~]# yum install -y lrzsz
[root@server ~]# rz
#上传inotify-tools-3.14.tar.gz
[root@server ~]# ls
anaconda-ks.cfg inotify-tools-3.14.tar.gz
[root@server ~]# tar -xzf inotify-tools-3.14.tar.gz
[root@server ~]# ls
anaconda-ks.cfg inotify-tools-3.14 inotify-tools-3.14.tar.gz
[root@server ~]# mv inotify-tools-3.14 /usr/local
[root@server ~]# cd /usr/local/inotify-tools-3.14
[root@server inotify-tools-3.14]# yum install make gcc gcc-c++
[root@server inotify-tools-3.14]# ./configure
[root@server inotify-tools-3.14]# make
[root@server inotify-tools-3.14]# make install
编写脚本,用于监控
[root@server ~]# vim inotify.sh
#!/bin/bash
/usr/local/bin/inotifywait -mrq -e modify,delete,create,attrib,move /app/java_project |while read events
do
rsync -av --delete /app/java_project/ root@192.168.226.20:/backup/app/java_project
echo "`date +%F\ %T`出现事件$events" >> /var/log/rsync.log 2>&1
done
[root@server ~]# chmod +x inotify.sh
让监控程序一直执行
[root@server ~]# nohup ./inotify.sh &
[1] 17791
#nohup : 让程序一直运行,即使关闭终端
[root@server ~]# nohup: 忽略输入并把输出追加到"nohup.out"
#回车
[root@server ~]# jobs
[1] 运行中 nohup ./inotify.sh &
/usr/local/bin/inotifywait命令选项说明
-m : 一直监控某个目录,create,delete,modify等行为
-r : 递归,不仅仅监控目录还要监控目录下的文件
-q : 获取操作信息,但是不输出
-e : 哪些行为需要被监控,modify,delete,create,attrib,move
modify: 修改
delete: 删除
create: 创建
attrib: 修改属性
move : 移动
托管操作
安装
[root@server ~]# yum install -y xinetd.x86_64
编写子配置文件
[root@server ~]# vim /etc/xinetd.d/rsync
service rsync
{
disable = no
flags = IPv6
socket_type = stream
wait = no
user = root
server = /usr/bin/rsync
server_args = --daemon
port = 873
log_on_failure += USERID
}
[root@server1 ~]# systemctl start xinetd
[root@server1 ~]# ss -naltp|grep 873
LISTEN 0 64 [::]:873 [::]:* users:(("xinetd",pid=8571,fd=5))