Centos7 使用 Rsync 同步文件

前言

Rsync 是一个增量备份工具,可压缩数据传输,速度快且增量备份,占用流量少。

准备工作

创建用户

1
2
3
4
5
# 创建用户组
# groupadd www

# 创建用户
# useradd -g www www -s /bin/false

创建配置文件

1
2
# 创建Rsync服务器信息提示文件
# echo "Welcome To Access" > /etc/rsyncd.motd
1
2
3
4
5
6
# 创建Rsync服务器密码文件,其中 RsyncUser 是用户名,123456 是密码
# echo "RsyncUser:123456" > /etc/rsyncd.secrets

# Rsync服务器密码文件授权,所属的用户和用户组必须都是 root,同时权限必须为 600
# chown root:root /etc/rsyncd.secrets
# chmod 600 /etc/rsyncd.secrets

安装 Rsync

安装 Rsync 服务

1
2
3
4
5
# 安装
# yum install rsync

# 开机自启动
# systemctl enable rsyncd

注意

这里还需要更改 systemd 的配置文件,加入以下内容,否则 Rsync 服务开机无法正常自启动。

1
2
3
4
5
6
7
8
# 更改systemd的配置文件,加入以下内容
# vim /usr/lib/systemd/system/rsyncd.service
[Unit]
...
After=network.target

# 让配置文件生效
# systemctl daemon-reload

配置 Rsync 服务

1
2
3
4
5
# 备份默认的配置文件
# cp /etc/rsyncd.conf /etc/rsyncd.conf.bak

# 编辑配置文件,添加以下内容(请自行根据实际情况更改对应的配置内容)
# vim /etc/rsyncd.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 设置服务器信息提示文件名称,在该文件中编写提示信息
motd file = /etc/rsyncd.motd
# 开启Rsync数据传输日志功能
transfer logging = yes
# 设置日志文件名称,可以通过log format参数设置日志格式
log file =/var/log/rsyncd.log
# 设置Rsync进程号保存文件名称
pid file =/var/run/rsyncd.pid
# 设置锁文件名称
lock file =/var/run/rsync.lock
# 设置服务器监听的端口号,默认为873
port = 873
# 设置服务器所监听网卡接口的IP地址(内网IP)
address = 172.0.25.18
# 设置进行数据传输时所使用的账户名称或ID号,默认使用nobody
uid = www
# 设置进行数据传输时所使用的组名称或GID号,默认使用nobody
gid = www
# 设置user chroot为yes后,rsync会首先进行chroot设置,将根映射到path参数路径下,对客户端而言,系统的根就是path参数所指定的路径。但这样做需要root权限,并且在同步符号连接资料时仅会同步名称,而内容将不会同步。
use chroot = no
# 是否允许客户端上传数据,这里设置不为只读。
read only = no
# 设置并发连接数,0代表无限制。超出并发数后,如果依然有客户端连接请求,则将会收到稍后重试的提示消息
max connections = 10
# 模块,Rsync通过模块定义同步的目录,模块以[name]的形式定义,这与Samba定义共享目录是一样的效果,在Rsync中也可以定义多个模块
[blog]
# comment定义注释说明字串
comment = rsync blog files
# 同步目录的真实路径通过path指定
path = /home/www/blog
# 忽略一些IO错误
ignore errors
# exclude可以指定例外的目录,即将common目录下的某个目录设置为不同步数据
# exclude = test/
# 设置允许连接服务器的账户,账户可以是系统中不存在的用户
auth users = RsyncUser
# 设置密码文件名称,注意该文件的权限要求为只读,建议权限为600,仅在设置auth users参数后有效
secrets file = /etc/rsyncd.secrets
# 设置允许哪些主机可以同步数据,可以是单个IP,也可以是网段,多个IP与网段之间使用空格分隔
hosts allow = *
# 设置拒绝所有(除hosts allow定义的主机外)
# hosts deny = *
# 客户端请求显示模块列表时,本模块名称是否显示,默认为true
list = true

启动 Rsync 服务

1
2
3
4
5
# 启动服务
# systemctl start rsyncd

# 查看服务的运行状态
# systemctl status rsyncd

值得一提的是,还可以使用以下命令管理 Rsync 服务:

1
2
3
4
5
# 关闭服务
# systemctl stop rsyncd

# 重启服务
# systemctl restart rsyncd

配置系统防火墙

1
2
3
4
5
6
7
8
# 开放Rsync监听的端口(默认端口是873)
# firewall-cmd --permanent --add-port=873/tcp

# 让防火墙规则生效
# firewall-cmd --reload

# 查看所有开放的端口
# firewall-cmd --list-ports

测试文件同步服务

提示

在下述的案例里,各命令参数的说明如下:

  • 183.242.11.186:服务器的 IP 地址
  • blog:在 /etc/rsyncd.conf 配置文件中定义的模块名称
  • RsyncUser:在 /etc/rsyncd.secrets 配置文件中定义的用户名
  • --delete:表示同步文件时,删除目标目录比源目录多余的文件

同步目录授权

在服务器上,确保用户拥有在 /etc/rsyncd.conf 配置文件中定义的 path 同步目录的访问权限。

1
2
# 同步目录授权
# chown -R www:www /home/www/blog

客户端同步服务器文件到本地

1
2
3
4
5
# 客户端同步服务器的某个文件到本地
$ rsync -vzrtopg --progress RsyncUser@183.242.11.186::blog/index.html ./

# 客户端同步服务器的某个目录到本地
$ rsync -vzrtopg --progress RsyncUser@183.242.11.186::blog/posts/ ./posts/

客户端同步本地文件到服务器

1
2
3
4
5
6
7
8
# 客户端同步本地的某个文件到服务器
$ rsync -rlptDv index.html RsyncUser@183.242.11.186::blog/

# 客户端同步本地的某个目录到服务器(本地的目录路径必须不以'/'结尾)
$ rsync -avzP --delete ./posts RsyncUser@183.242.11.186::blog/

# 客户端同步本地某个目录下的所有文件到服务器(本地的目录路径必须以'/'结尾)
$ rsync -avzP --delete ./posts/ RsyncUser@183.242.11.186::blog/

设置同步时不手动输入密码

在客户端同步文件时指定密码文件,这样可以避免每次都手动输入密码。

1
2
3
4
5
6
# 在本地创建密码文件,其中 123456 是密码,这里不需要指定用户名
# echo "123456" > /etc/rsyncd.password

# 密码文件授权,所属的用户和用户组必须都是 root,同时权限必须为 600
# chown root:root /etc/rsyncd.password
# chmod 600 /etc/rsyncd.password
1
2
# 客户端同步服务器的某个文件到本地(指定密码文件)
# rsync -vzrtopg --progress RsyncUser@183.242.11.186::blog/index.html ./ --password-file=/etc/rsyncd.password

提示

除了上述的方法之外,还可通过设置环境变量的方式,避免每次都手动输入密码。

1
2
3
4
5
# 通过环境变量设置密码
# export RSYNC_PASSWORD="123456"

# 客户端同步服务器的某个文件到本地
# rsync -vzrtopg --progress RsyncUser@183.242.11.186::blog/index.html ./

不同步文件的所有者和用户组信息

rsync -a dir/ remote:/dir/ 命令中,-a 相当于 -rlptgoD,各参数选项的说明如下:

1
2
3
4
5
6
7
8
9
-o, --owner                 preserve owner (super-user only)
-g, --group preserve group
-r, --recursive recurse into directories
-l, --links copy symlinks as symlinks
-p, --perms preserve permissions
-t, --times preserve modification times
-D same as --devices --specials
--devices preserve device files (super-user only)
--specials preserve special files

若希望不同步文件的所有者和用户组信息,那么可以通过移除 -o-g 参数选项来实现,示例命令如下:

1
$ rsync -a --no-o --no-g dir/ remote:/dir/

用参数控制 Rsync 同步时的比较算法

Rsync 默认只会比较文件大小和最后修改时间,只要这两者一样,Rsync 就认为文件相同;此时如果其它属性(包括文件内容)的不同,并不会让 Rsync 同步该文件。所以,如果本地文件与远程文件大小一样,修改时间也一样,那么默认情况下,即使文件内容不一样的文件也不同被同步。通过设置合适的参数,可以控制 Rsync 的比较算法,其中 Rsync 使用以下三个步骤来比较文件:

  • a) 比较文件大小
  • b) 比较文件最后修改日期
  • c) 比较文件内容,通过 checksum,例如使用 md5sum

可以用参数来控制 Rsync 执行上面的哪些步骤:

  • 默认的比较算法只执行 a 和 b
  • 参数 --size-only 只检查 a ,即只要文件大小一样,即使修改日期不一样,就认为文件一样,更不会去检查文件内容
  • 参数 --ignore-times 是忽略所有检查,直接认为文件都不一样,然后总是复制文件
  • 参数 --checksum 是在 a 的基础上执行 c ,比较文件内容。如果文件大小不一样,可以确保内容不一样。如果文件大小一样,那么直接比较文件内容,不会执行 b 中的比较最后修改时间。该方法最安全,但需要读取两边的文件内容,某些情况下要慢很多(尤其是最后比较出来的文件内容一样的情况)

命令参数的使用示例如下:

1
$ rsync -avzP --delete --checksum dir/ remote:/dir/

常见问题

delete 参数不生效