rsync

什么是RSYNC

rsync是类unix下的一款数据镜像备份工具——remote sync。
备份服务器
Rsync 的基本特点如下:

  • 可以镜像保存整个目录树和文件系统;
  • 可以很容易做到保持原来文件的权限、时间、软硬链接等;
  • 无须特殊权限即可安装;
  • 优化的流程,文件传输效率高;
  • 可以使用 rcp、ssh 等方式来传输文件,当然也可以通过直接的 socket 连接;
  • 支持匿名传输;
  • rsync的主要特点就是增量传输,只对变更的部分进行传送。

RSYNC原理
rsycn原理
rsync 是 linux 下同步文件的一个高效算法,用于同步更新两处计算机的文件和目录,并适当利用查找文件中的不同块以减少数据传输。 rsync 的主要特点就是增量传输,只对变更的部分进行传送。

增量同步算法
假如我们现在需要同步两个文件保持一致,并且只想传送不同的部分,那么我们就需要对两边的文件做diff ,但是这两个文件在两台不同的机器上,无法做 diff 。如果我们做 diff ,就要把一个文件传到另一台机器上做 diff ,但这样一来,我们就传了整个文件,这与我们只想传输不同部的初衷相背。于是我们就要想一个办法,让这两边的文件见不到面,但还能知道它们间有什么不同。这就是 rsync 的算法。

rsync 同步算法
我们将同步源文件名称为 fileSrc ,同步目的文件叫 fileDst 。
linux里面diff命令可以判断两个文件是否相同

diff 1.txt 2.txt
如果没有任何返回代表两个文件相同
  1. 分块 Checksum 算法
    找到文件不同的地方
    首先,我们会把 fileDst 的文件平均切分成若干个小块,比如每块 512 个字节(最后一块会小于这个数),然后对每块计算两个 checksum :

    1. 一个叫 rolling checksum ,是弱 checksum , 32 位的 checksum
    2. 另一个是强 checksum , 128 位的,以前用 md4 ,现在用 md5 hash 算法。
      为什么要这样?因为若干年前的硬件上跑 md4 的算法太慢了,所以,我们需要一个快算法来鉴别文件块的不同,但是弱的 adler32 算法碰撞概率太高了,所以我们还要引入强的 checksum 算法以保证两文件块是相同的。也就是说,弱的 checksum 是用来区别不同,而强的是用来确认相同。
  2. 传输算法
    同步目标端会把 fileDst 的一个 checksum 列表传给同步源,这个列表里包括了三个东西, rolling checksum(32bits),md5 checksume(128bits) ,文件块编号。
    同步源机器拿到了这个列表后,会对 fileSrc 做同样的 checksum ,然后和 fileDst 的 checksum 做对比,这样就知道哪些文件块改变了。
    但是,聪明的你一定会有以下两个疑问:
    如果我 fileSrc 这边在文件中间加了一个字符,这样后面的文件块都会位移一个字符,这样就完全和fileDst 这边的不一样了,但理论上来说,我应该只需要传一个字符就好了。这个怎么解决?
    如果这个 checksum 列表特别长,而我的两边的相同的文件块可能并不是一样的顺序,那就需要查找,线性的查找起来应该特别慢吧。这个怎么解决?
    很好,让我们来看一下同步源端的算法。

  3. checksum 查找算法
    同步源端拿到 fileDst 的 checksum 数组后,会把这个数据存到一个 hash table (特殊的数据结构体,可以快速检索)中,用 rolling checksum 做 hash ,以便获得 O(1) 时间复杂度的查找性能。这个 hash table 是 16bits 的,所以, hash table 的尺寸是 2的16次方 ,对 rolling checksum 的hash 会被散列到 0 到 2^16 – 1 中的某个整数值。

  4. 比对算法
    在这里插入图片描述1. 取 fileSrc 的第一个文件块(我们假设的是 512 个长度),也就是从 fileSrc 的第 1 个字节到第512 个字节,取出来后做 rolling checksum 计算。计算好的值到 hash 表中查。

  5. 如果查到了,说明发现在 fileDst 中有潜在相同的文件块,于是就再比较 md5 的 checksum ,因为 rolling checksume 太弱了,可能发生碰撞。于是还要算 md5 的 128bits 的 checksum ,这样一来,我们就有 2^-(32+128) = 2^-160 的概率发生碰撞,这太小了可以忽略。如果 rollingchecksum 和 md5 checksum 都相同,这说明在 fileDst 中有相同的块,我们需要记下这一块在fileDst 下的文件编号。

  6. 如果 fileSrc 的 rolling checksum 没有在 hash table 中找到,那就不用算 md5 checksum了。表示这一块中有不同的信息。总之,只要 rolling checksum 或 md5 checksum 其中有一个在 fileDst 的 checksum hash 表中找不到匹配项,那么就会触发算法对 fileSrc 的 rolling 动作。于是,算法会住后 step 1 个字节,取 fileSrc 中字节 2-513 的文件块要做 checksum,go to(1.) – 现在你明白什么叫 rolling checksum 了吧。

  7. 这样,我们就可以找出 fileSrc 相邻两次匹配中的那些文本字符,这些就是我们要往同步目标端传的文件内容了。

  8. 传输
    在这里插入图片描述最终在同步源这端,我们的 rsync 算法可能会得到这个样子的一个数据数组,图中,红色块表示在目标端已匹配上,不用传输(注:我专门在其中显示了两块 chunk #5 ,代表数据中有复制的地方,不用传输),而白色的地方就是需要传输的内容(注意:这些白色的块是不定长的),这样,同步源这端把这个数组(白色的就是实际内容,红色的就放一个标号)压缩传到目的端,在目的端的 rsync 会根据这个表重新生成文件,这样,同步完成。

参考博客:
https://segmentfault.com/a/1190000018391604?utm_source=tag-newest

安装部署服务端

  • 安装xineted服务
[root@server1 ~]# yum install rsync.x86_64 -y
[root@server1 ~]# yum install xinetd -y
  • 修改xineted配置文件(当启动xineted时,里面可以做一些配置,可以同时启动什么文件或者服务)(不是很有用)
[root@server1 ~]# vim /etc/xinetd.d/rsync
service rsync
{
disable = no
socket_type = stream
wait = no
user = root
server = /usr/bin/rsync
server_args = --daemon
port = 873
log_on_failure = USERID
}
  • 修改rsync配置文件(873端口)
[root@server1 ~]# vim /etc/rsyncd.conf
[test] // 模块名,主要是定义服务器哪个目录要被同步
path = /test // 指定文件目录所在位置,这是必须指定的
uid = root
gid = root
max connections = 2
timeout = 300
read only = false
auth users = root // 认证用户是 root,必须是服务器上真实存在的用户
secrets file = /etc/rsync.passwd // 密码存在哪个文件
strict modes = yes
use chroot = yes // 在传输文件之前,服务器守护程序在将chroot 到文件系统中
的目录中
  • 准备密码文件
[root@server1 ~]# vim /etc/rsync.passwd
root:123456
[root@server1 ~]# chmod 600 /etc/rsync.passwd
提高权限只能让root用户查看密码
  • 启动服务
[root@server1 ~]# systemctl start xinetd.service
[root@server1 ~]# ss -tanl | grep 873
LISTEN 0 64 :::873 :::*
  • 准备文件
[root@server1 ~]# mkdir /test
[root@server1 ~]# touch /test/123

六种不同的工作模式

  • 在server2上安装rsync
[root@server2 ~]# yum install rsync.x86_64 -y

rysnc工具的参数

rsync 相关参数
-v --verbose详细
-a --avchive归档模式,表示递归方式传输文件,并保持所有文件属性,等于-rlptgoD
-z 传递过程中使用zip压缩传递,速度更快
-p, --perms 保持文件权限
-P --partial 保留那些因故没有完全传输的文件,以便加快随后的再次传输
-r --recursiv递归目录
-e --rsh=COMMAND指定使用rsh、ssh方式进行数据同步
--progress 在传输时现实传输过程(显示备份过程)
-topg 保持文件原有属性,o=owner,t=time,p=perms(权限),g=group
-b --backup创建备份,也就是对于目的已经存在有同样的文件名时,将老的文件重新命名为
~filename
-u --update仅仅进行更新,也就是跳过已经存在的文件

-l--links保留软连接
--delete 删除那些DST中SRC没有的文件(就是在目的目录中只保留传输过去的文件,其它的都删
除),保持和源文件相同
-q, --quiet 精简输出模式
-c, --checksum 打开校验开关,强制对文件传输进行校验
-R, --relative 使用相对路径信息
-b, --backup 创建备份,也就是对于目的已经存在有同样的文件名时,将老的文件重新命名为
~filename。可以使用--suffix选项来指定不同的备份文件前缀。
--backup-dir 将备份文件(~filename)存放在在目录下。
-suffix=SUFFIX 定义备份文件前缀
-u, --update 仅仅进行更新,也就是跳过所有已经存在于DST,并且文件时间晚于要备份的文件。
(不覆盖更新的文件)
-l, --links 保留软链结
-L, --copy-links 想对待常规文件一样处理软链结
--copy-unsafe-links 仅仅拷贝指向SRC路径目录树以外的链结
--safe-links 忽略指向SRC路径目录树以外的链结
-H, --hard-links 保留硬链结
-o, --owner 保持文件属主信息
-g, --group 保持文件属组信息
-D, --devices 保持设备文件信息
-t, --times 保持文件时间信息
-S, --sparse 对稀疏文件进行特殊处理以节省DST的空间
-n, --dry-run现实哪些文件将被传输
-W, --whole-file 拷贝文件,不进行增量检测
-x, --one-file-system 不要跨越文件系统边界
-B, --block-size=SIZE 检验算法使用的块尺寸,默认是700字节
-e, --rsh=COMMAND 指定使用rsh、ssh方式进行数据同步
--rsync-path=PATH 指定远程服务器上的rsync命令所在路径信息
-C, --cvs-exclude 使用和CVS一样的方法自动忽略文件,用来排除那些不希望传输的文件
--existing 仅仅更新那些已经存在于DST的文件,而不备份那些新创建的文件
--delete-excluded 同样删除接收端那些被该选项指定排除的文件
--delete-after 传输结束以后再删除
--ignore-errors 及时出现IO错误也进行删除
--max-delete=NUM 最多删除NUM个文件
--partial 保留那些因故没有完全传输的文件,以是加快随后的再次传输
--force 强制删除目录,即使不为空
--numeric-ids 不将数字的用户和组ID匹配为用户名和组名
--timeout=TIME IP超时时间,单位为秒
-I, --ignore-times 不跳过那些有同样的时间和长度的文件
--size-only 当决定是否要备份文件时,仅仅察看文件大小而不考虑文件时间
--modify-window=NUM 决定文件是否时间相同时使用的时间戳窗口,默认为0
-T --temp-dir=DIR 在DIR中创建临时文件
--compare-dest=DIR 同样比较DIR中的文件来决定是否需要备份
--exclude=PATTERN 指定排除不需要传输的文件模式
--include=PATTERN 指定不排除而需要传输的文件模式
--exclude-from=FILE 排除FILE中指定模式的文件。
如果排除单个文件或者目录,可以直接指定 --exclude-from=File_Name
如果是多个文件或目录,可以新建一个文件 exclude,里面写上要排除的文件名或目录名,可以使用正
则,然后使用--exclude-from='/../exclude'指定
--include-from=FILE 不排除FILE指定模式匹配的文件。用法同上
--version 打印版本信息
--address 绑定到特定的地址
--config=FILE 指定其他的配置文件,不使用默认的rsyncd.conf文件
--port=PORT 指定其他的rsync服务端口
--blocking-io 对远程shell使用阻塞IO
-stats 给出某些文件的传输状态
--log-format=formAT 指定日志文件格式
--password-file=FILE 从FILE中得到密码
--bwlimit=KBPS 限制I/O带宽,KBytes per second
-h, --help 显示帮助信息
  • 模式一,查看服务端有哪些可用数据源
[root@server2 ~]# rsync --list-only root@192.168.175.10::
test
  • 模式二,本地文件拷贝到本地,当src和dest都不包含有冒号时就启动从本地进行拷贝
[root@server2 ~]# mkdir /backup
[root@server2 ~]# touch local.txt
[root@server2 ~]# rsync local.txt /backup/
[root@server2 ~]# ls /backup/
local.txt
  • 模式三,本地文件拷贝到远程,当dest包含冒号时就启动拷贝到远程
[root@server2 ~]# rsync local.txt root@192.168.175.10:/test
The authenticity of host '192.168.175.10 (192.168.175.10)' can't be
established.
ECDSA key fingerprint is SHA256:x573vWoEULGOYwloNT7s9EqxZa6lA1k5zZMFk7bU0xg.
ECDSA key fingerprint is
MD5:60:21:e0:bf:3c:c0:d8:09:74:b8:23:26:55:4e:d1:0e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.175.10' (ECDSA) to the list of known
hosts.
root@192.168.175.10's password:
[root@server1 ~]# ll /test/local.txt
-rw-r--r-- 1 root root 0 324 11:05 /test/local.txt
  • 模式四,将远程文件拷贝到本地,当src包含冒号的时候就启动远程拷贝到本地
[root@server2 ~]# rsync root@192.168.175.10:/test/123 /backup/
root@192.168.175.10's password:
[root@server2 ~]# ll /backup/123
-rw-r--r-- 1 root root 0 324 11:07 /backup/123
  • 模式五,从远程服务器拷贝到本地,当src使用两个冒号的时候启用这种方式,冒号后面跟的是服务端设置的模块
[root@server2 ~]# rsync -r root@192.168.175.10::test /backup/
Password:
#这时的密码就不是主机root用户的密码而是rsync设置的密码了
[root@server2 ~]# ls /backup/
123 local.txt
  • 模式六,从本地拷贝到远程服务器
[root@server2 ~]# touch 456
[root@server2 ~]# rsync -r 456 root@192.168.175.10::test
Password:
[root@server1 ~]# ls /test/
123 456 local.txt

案例,定时备份

客户端需求
1.客户端提前准备存放的备份的目录,目录规则如下:/backup/主机_ip_时间
⒉客户端在本地打包备份(系统配置文件、应用配置等)拷贝至/backup/主机_ip_时间
3.客户端最后将备份的数据进行推送至备份服务器
4.客户端每天凌晨1点定时执行该脚本
5.客户端服务器本地保留最近7天的数据,避免浪费磁盘空间
服务端需求
1.服务端部署rsync,用于接收客户端推送过来的备份数据
⒉.服务端需要每天校验客户端推送过来的数据是否完整
3.服务端需要每天校验的结果通知给管理员
4.服务端仅保留6个月的备份数据,其余的全部删除

客户端准备

  • 创建目录
[root@server2 ~]# mkdir /backup
  • 安装expect工具
[root@server2 ~]# yum install expect* -y
  • 准备expect脚本【可以帮我们进行自动化交互脚本】
[root@server2 ~]# vim rsync.exp
#!/usr/bin/expect
#set: 进行赋值
set mulu [lindex $argv 0]
#位置参数,0 表示第一个参数
set timeout 10
spawn rsync -avzr /backup/$mulu root@192.168.175.10::test
#spawn: 启动新的进程
expect Password
#expect: 从进程接收字符串
send "123456\n"
#send: 用于向进程发送字符串
expect eof
  • 准备备份脚本
[root@server2 ~]# vim beifen.sh
#!/bin/bash
# 准备压缩文件的目录
mulu=`ip a | grep global|awk -F'[ /]+' '{print $3}'`_`date +%F`
echo $mulu
mkdir -pv /backup/$mulu &> /dev/null
# 打包待发送的数据
tar zcf /backup/$mulu/conf.tar.gz /etc/passwd /etc/vimrc &> /dev/null
# 为了后面模拟一个月数据的变化
touch /backup/$mulu
# 发送数据
#rsync -avzr /backup/$mulu root@192.168.175.10::test
expect rsync.exp $mulu
# 保留七天以内的数据
find /backup -mtime +7 -delete
[root@server2 ~]# chmod +x beifen.sh
  • 计划任务
    定时任务
crontab -e
0 1 * * * root /root/beifen.sh
[root@server2 ~]# cat /etc/crontab
......
0 1 * * * root /root/beifen.sh
[root@server2 backup]# crontab -l
0 1 * * * root /root/beifen.sh

服务端准备

  • 安装rsync
[root@server1 ~]# yum install rsync.x86_64 -y
  • 修改配置文件
[root@server1 ~]# vim /etc/rsyncd.conf
[test]
path = /test
uid = root
gid = root
max connections = 2
timeout = 300
read only = false
auth users = root
secrets file = /etc/rsync.passwd
strict modes = yes
use chroot = yes
  • 创建目录
[root@server1 ~]# mkdir /test -pv
  • 准备密码文件
[root@server1 ~]# cat /etc/rsync.passwd
root:123456
[root@server1 ~]# chmod 600 /etc/rsync.passwd
  • 启动rsync
[root@server1 ~]# systemctl start rsyncd.service
[root@server1 ~]# ss -tnl
State Recv-Q Send-Q Local
Address:Port Peer
Address:Port
LISTEN 0 128
*:22 *:*
LISTEN 0 100
127.0.0.1:25
*:*
LISTEN 0 5
*:873 *:*
LISTEN 0 128
:::22 :::*
LISTEN 0 100
::1:25
:::*
LISTEN 0 5
:::873 :::*
  • 验证服务端
[root@server2 ~]# rsync --list-only root@192.168.175.10::
test
  • 模拟一个月数据来验证结果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Docker是一种开源的容器化平台,可以帮助开发人员和系统管理员更轻松地构建、部署和运行应用程序。而rsync是一个用于文件同步和备份的工具,它可以在本地或远程系统之间同步文件和目录。 要在Docker中使用rsync,你可以使用两种不同的镜像:eeacms/rsync和apnar/rsync-server。这两个镜像都可以通过Docker Hub获取。 1. 使用eeacms/rsync镜像: - 首先,你需要准备好rsync的密码文件。可以使用以下命令创建密码文件并设置权限: ```shell echo "pass" >/etc/rsync.password chmod 600 /etc/rsync.password ``` - 然后,你可以使用以下命令从Docker Hub上拉取eeacms/rsync镜像: ```shell docker pull eeacms/rsync ``` - 最后,你可以使用以下命令来构建容器并运行rsync: ```shell docker run -d --name rsync-server -p 873:873 -v /path/to/source:/data -v /etc/rsync.password:/etc/rsync.password eeacms/rsync ``` 其中,`/path/to/source`是你要同步的源文件或目录的路径。 2. 使用apnar/rsync-server镜像: - 首先,你需要准备好rsync的配置文件。可以使用以下命令创建一个简单的配置文件: ```shell echo "uid = root" >/path/to/rsyncd.conf echo "gid = root" >>/path/to/rsyncd.conf echo "[data]" >>/path/to/rsyncd.conf echo "path = /data" >>/path/to/rsyncd.conf echo "read only = false" >>/path/to/rsyncd.conf ``` - 然后,你可以使用以下命令从Docker Hub上拉取apnar/rsync-server镜像: ```shell docker pull apnar/rsync-server ``` - 最后,你可以使用以下命令来构建容器并运行rsync-server: ```shell docker run -d --name rsync-server -p 873:873 -v /path/to/rsyncd.conf:/etc/rsyncd.conf -v /path/to/source:/data apnar/rsync-server ``` 其中,`/path/to/rsyncd.conf`是你准备好的rsync配置文件的路径,`/path/to/source`是你要同步的源文件或目录的路径。 请注意,上述命令中的`-p`参数用于将容器的873端口映射到主机的873端口,以便可以通过rsync客户端访问。`-v`参数用于将主机上的文件或目录挂载到容器中,以便进行同步操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值