20.2.0: 同步工具 rsync



1. 工具:rsync

作用:一个快速、万能、可远程的文件复制工具
语法:

参数:

rsync是增量备份,默认-av参数时在目标目录已经存在且内容无更改的文件不会被重新拷贝

1.1 基本用法演示:

1. rsync本地同步文件

自动创建并不存在的/tmp/111目录,只能创建1层目录

# 如果是2层及以上就会报错该目录不存在了
rsync -av perm/ /tmp/111
sending incremental file list
created directory /tmp/111
./
001.txt
002.txt
......
377.log
777.log

sent 792 bytes  received 262 bytes  234.22 bytes/sec
total size is 0  speedup is 0.00

SRC是”perm”时与”perm/“的不同

# 这样会把perm文件夹整个复制到目标目录里去
rsync -av perm /tmp/111
sending incremental file list
perm/
perm/001.txt
perm/002.txt
......
perm/377.log
perm/777.log

sent 810 bytes  received 263 bytes  2146.00 bytes/sec
total size is 0  speedup is 0.00

2. rsync远程同步文件

以ssh的方式用rsync与web02远程同步文件

# 如果ssh端口不是22,那么需要写成:
# rsync -av --rsh="ssh -p <port>" perm/ 192.168.0.27:/tmp/rsyncdir/
# 或rsync -av -e "ssh -p <port>" perm/ 192.168.0.27:/tmp/rsyncdir/

# 本机上执行rsync,同步文件到192.168.0.27
rsync -av perm/ root@192.168.0.27:/tmp/rsyncdir/
root@192.168.0.27's password:
sending incremental file list
./
001.txt
002.txt
......
377.log
777.log

sent 792 bytes  received 262 bytes  234.22 bytes/sec
total size is 0  speedup is 0.00

# 192.168.0.27上同步文件到本地
rsync -avuL root@192.168.0.27:/tmp/rsyncdir perm/
root@192.168.0.27's password:
receiving incremental file list
rsyncdir/
rsyncdir/001.txt
rsyncdir/002.txt
......
rsyncdir/377.log
rsyncdir/777.log
rsyncdir/testu

sent 281 bytes  received 888 bytes  155.87 bytes/sec
total size is 5  speedup is 0.00

3. 软连接拷贝相关参数”-L”和”-l”

# -l会将软连接以软连接的形式拷贝过去
ll perm/ps.soft
lrwxrwxrwx 1 root root 11 Jan  6 17:18 perm/ps.soft -> /etc/passwd     
rsync -av perm/ /tmp/111
sending incremental file list
./
001.txt
002.txt
......
377.log
777.log
ps.soft -> /etc/passwd

sent 828 bytes  received 265 bytes  2186.00 bytes/sec
total size is 11  speedup is 0.01

# 查看结果
ll /tmp/111/ps.soft perm/ps.soft
lrwxrwxrwx 1 root root 11 Jan  6 17:18 perm/ps.soft -> /etc/passwd
lrwxrwxrwx 1 root root 11 Jan  6 17:18 /tmp/111/ps.soft -> /etc/passwd
# -a中包含-l,加上此参数,rsync会把软链接保持原有属性复制到目标目录,


# -L参数会把软连接指向的源文件同步过去

# 清空111目录后我们用-L再次复制
rsync -avL perm/ /tmp/111
sending incremental file list
./
001.txt
002.txt
......
377.log
777.log
ps.soft

sent 2495 bytes  received 281 bytes  5552.00 bytes/sec
total size is 1639  speedup is 0.59

# 查看结果
ll /tmp/111/ps.soft /etc/passwd
-rw-r--r-- 1 root root 1639 Dec 29 20:23 /etc/passwd
-rw-r--r-- 1 root root 1639 Dec 29 20:23 /tmp/111/ps.soft

4. –no-OPTION参数用来指定不使用的参数

# -a含-l,我们用--no-l把-l规避掉
# 因为规避了-l参数,所以并不处理软连接文件
rsync -av --no-l perm/ /tmp/111
sending incremental file list
./
001.txt
......
777.log
skipping non-regular file "ps.soft"

sent 813 bytes  received 262 bytes  2150.00 bytes/sec
total size is 11  speedup is 0.01

5. “-u”参数,当目标机器上文件时间比源文件时间新时不覆盖重传,即使文件内容不一致

# 创建测试环境
mkdir src
mkdir dest
touch src/test01
rsync -av src/ dest
sending incremental file list
./
test01

sent 83 bytes  received 34 bytes  234.00 bytes/sec
total size is 0  speedup is 0.00

# 修改源文件内容,但是去touch目标文件,保证目标文件时间新于源文件
echo "good" > src/test01
touch dest/test01

# 加上-u参数,不重传文件,即使文件内容不一致
rsync -auv src/ dest
sending incremental file list

sent 45 bytes  received 12 bytes  114.00 bytes/sec
total size is 5  speedup is 0.09

# 而不加-u参数时,即使目标文件新于源文件也拷贝
rsync -av src/ dest
sending incremental file list
test01

sent 93 bytes  received 31 bytes  248.00 bytes/sec
total size is 5  speedup is 0.04

6. ‘–delete’参数可删除SRC没有,DEST有的文件

# 先在SRC删除ps.soft,用--delete实现另一端自动删除
rm -f perm/ps.soft
rsync -av --delete perm/ /tmp/111/
sending incremental file list
./
deleting ps.soft
testu

sent 352 bytes  received 34 bytes  772.00 bytes/sec
total size is 5  speedup is 0.01

7. “–exclude”参数可指定排除复制的文件

#把以.log结尾的文件排除在复制目标之外
# rm -rf /tmp/111/*
# rsync -av --exclude='*.log' perm/ /tmp/111/
sending incremental file list        
./
001.txt
002.txt
003.txt
004.txt
005.txt
006.txt
007.txt
testu

sent 503 bytes  received 167 bytes  1340.00 bytes/sec
total size is 5  speedup is 0.01

8. “-c”强制使用checksum来代替size和mtime的检测机制

## 传统av参数会在size改变和mtime修改条件改变时同步文件
echo "good" >> test1/file1
rsync -av test1/* test2/
sending incremental file list
file1

sent 130 bytes  received 35 bytes  330.00 bytes/sec
total size is 22  speedup is 0.13

touch test1/file1
rsync -av test1/* test2/
sending incremental file list
file1

sent 130 bytes  received 35 bytes  330.00 bytes/sec
total size is 22  speedup is 0.13

## 而-c参数仅会在checksum校验后发现不同才会同步文件
touch test1/file1
rsync -acv test1/* test2/
sending incremental file list

sent 99 bytes  received 19 bytes  236.00 bytes/sec
total size is 22  speedup is 0.19
# 在我们touch源文件之后,并未发送源文件

## 对比使用vim打开文件,不做任何修改,然后保存是否会同步文件
# 无-c,会同步文件
vim test1/file1
rsync -av test1/* test2/
sending incremental file list
file1

sent 232 bytes  received 35 bytes  534.00 bytes/sec
total size is 124  speedup is 0.46

# 加-c,不会同步文件
vim test1/file1
rsync -avc test1/* test2/
sending incremental file list

sent 99 bytes  received 19 bytes  236.00 bytes/sec
total size is 124  speedup is 1.05

2. rsync daemon模式:

2.1 服务器配置文件/etc/rsyncd.conf(需要手动创建)

vi /etc/rsyncd.conf
*************************************************
uid=www
gid=www
use chroot=no
max connections=5
incoming chmod = D755,F644
## 全局配置
port=8700
#监听端口,默认是873,若不是873,客户端需要增加--port 8700指定端口
#默认端口的配置和服务信息可在/etc/services和/etc/xinetd.d/rsync里查到
log file=/var/log/rsync.log
#默认就是这个文件,可通过此行设置其他文件,日志很重要,用于排错
pid file=/var/run/rsyncd.pid
#进程文件,默认就是这个文件
lock file = /var/run/rsync.lock
log file = /var/log/rsync.log

## 模块1
[test1]
#模块名称,用在客户端命令里
path=/root/perm
#指定此模块共享文件的目录
ignore errors
use chroot=yes
#指定是否限定用户的活动范围就是path指定的目录
max connections=4
#指定最大连接数
read only=no
#如果设为只读,那客户端用户不可push文件进来,只能读取走
list=yes
#设定用户是否可以通过--list来查看server端的模块
uid=root
#若client写入文件,写入文件的属主归属
gid=root
#同上,写入文件的属组归属
auth users=testguy
#授权使用复制命令时的登录角色
secrets file=/etc/rsyncd.passwd
#登录角色的指定密码文件
hosts allow=192.168.0.1/24
#指定允许的ip网段及子网掩码(有子网掩码即为一个网段)
*************************************************

2.2 服务端密码文件/etc/rsyncd.passwd

# vi /etc/rsyncd.passwd
*************************************************
#可通过多行定义多个用户
用户名:密码
*************************************************

2.3 启动rsync守护进程(pid文件保存的内容是守护进程的pid)

# 用--daemon启动rsync服务
# 默认/etc/rsyncd.conf,也可手动指定--config=/.../rsyncd.conf
rsync --daemon

## 若pid文件已存在会报错
# failed to create pid file /var/run/rsyncd.pid: File exists

2.4 传输示例

2.4.1 服务端和客户端的密码文件(用–password-file指定客户端密码文件)

# 客户端配置密码文件
vi /etc/rsyncd.d/rsyncd.pass
*************************************************
testguy:password
*************************************************

# 必须要修改权限为600,否则报错
chmod 600 /etc/rsyncd.d/rsyncd.pass

#指定客户端密码文件后不需要输入密码
rsync -avL --port=8700 --password-file=/etc/rsyncd.d/rsyncd.pass testguy@192.168.0.5::test1 /tmp/222

2.4.2 常规语法格式

# port不是默认873,远程客户端需要用--port指定端口
rsync -av --password-file=/path/to/password_file --port=8700 testguy@192.168.0.5::test1 /tmp/222

2.4.3 rsync协议语法格式

rsync -av --password-file=/path/to/password_file rsync://testguy@192.168.0.5:8700/test1 /tmp/222

2.5 daemon模式下的配置

2.5.1 “use chroot=yes”产生的效果

## 现在服务端创建一个软连接
# ll /root/perm/rc.soft
lrwxrwxrwx 1 root root 18 Jan  7 10:49 /root/perm/rc.soft -> /etc/rc.d/rc.local

## client端同步出现报错,这是因为chroot把用户限制在path指定的目录里
# rsync -avL --port=8700 testguy@192.168.0.5::test1 /tmp/222
Password:
receiving incremental file list
symlink has no referent: "/rc.soft" (in test1)
./

sent 61 bytes  received 431 bytes  75.69 bytes/sec
total size is 5  speedup is 0.01
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1505) [generator=3.0.6]


## 编辑服务端配置文件"use chroot=no",然后再在client端再次尝试
## 无报错,成功传输
# rsync -avL --port=8700 testguy@192.168.0.5::test1 /tmp/222
Password:
receiving incremental file list
rc.soft

sent 77 bytes  received 652 bytes  162.00 bytes/sec
total size is 225  speedup is 0.31

2.5.2 配置hosts allow

# "hosts allow=192.168.0.1/24"若没有/24则仅为192.168.0.1可以访问
# 修改服务端配置文件"hosts allow=192.168.0.1",客户端同步
rsync -avL --port=8700 --password-file=/etc/rsyncd.d/rsyncd.pass testguy@192.168.0.5::test1 /tmp/222
@ERROR: Unknown module 'test1'
rsync error: error starting client-server protocol (code 5) at main.c(1503) [receiver=3.0.6]

# 服务端查看log信息,用于排错
cat /var/log/rsync.log
......
2015/01/07 11:16:17 [21454] building file list
2015/01/07 11:16:17 [21454] sent 404 bytes  received 59 bytes  total size 225
2015/01/07 11:26:14 [21468] connect from Unknown_00-0c-29-24-9e-dd.gateway.2wire.net (192.168.0.27)
2015/01/07 11:26:14 [21468] rsync denied on module test1 from unknown_00-0c-29-24-9e-dd.gateway.2wire.net (192.168.0.27)
# 将hosts段增加为"hosts allow=192.168.0.1/24"后即正常,
# 那/24代表什么含义呢,如下面所示
#/8=255.0.0.0
#/16=255.255.0.0
#/24=255.255.255.0
#/32=255.255.255.255
## /24代表了255.255.255.0的子网掩码,而子网掩码的作用是和传来的封包ip地址进行"与"计算,如果结果和本机网段一致,则可通信。

2.5.3 配置list=yes or no

# "list=no"用来设定服务端模块是否可被列出(推荐设为no)
# 客户端尝试list
rsync --port=8700 --list-only 192.168.0.5::

# 在服务器段设置配置文件为list=yes
rsync --port=8700 --list-only 192.168.0.5::
test1

# --list-only可省略不写
rsync --port=8700  192.168.0.5::
test1

3. rsync报错

3.1 报错1

错误信息

rsync -av /root/ root@192.168.0.5:/root/
rsync: Failed to exec ssh: No such file or directory (2)
rsync error: error in IPC code (code 14) at pipe.c(84) [sender=3.0.6]
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(600) [sender=3.0.6]

解决办法

# 检查ssh命令是否存在
which ssh
/usr/bin/which: no ssh in......
# 安装ssh命令
yum install openssh-clients

3.2 报错2

错误信息

rsync -av /data/tongchiang/ root@124.6.62.13:/data/www/
root@124.6.62.13\'s password:
sending incremental file list
eighth/
eighth/bk.png
eighth/eighth.css
eighth/eighth.html
rsync: connection unexpectedly closed (70 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(600) [sender=3.0.6]

解决过程:

# 查看目标主机的硬盘,发现硬盘满了,没空间了
df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/vzfs        80G   80G     0 100% /
none            512M  4.0K  512M   1% /dev
none            512M     0  512M   0% /dev/shm

# 利用"du -sh ./*"来逐步排查,终于找到了罪魁祸首
du -sh error_log
79G     error_log

解决方案:

# 解决方案:创建日志分割与删除脚本,并制定计划定期执行
vim /root/sh/error_log_del.sh
**********************************************************
#!/bin/bash
#
#created by zhaopeiwu @ 2015-04-20
#FOR control the size of error log of apache
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/apache2/bin:/usr/local/mysql/bin
export PATH

log_path="/usr/local/apache2/logs/"
log_size=`du -s $log_path/error_log|cut -f 1`
if [ $log_size -gt 100000 ];
        then
                mv $log_path/error_log $log_path/error_log_`date +%Y%m%d`;
                touch $log_path/error_log;
fi

num_del=`ls -t $log_path/error*|wc -l`
if [ $num_del -gt 4 ];
        then
                ls -t $log_path/error*|tail -$[$num_del-2]|xargs -i rm -f {} 2 > /dev/null
fi

exit 0
*********************************************************

# 制作计划任务
crontab -e
*********************************************************
*/20 * * * * sh /root/sh/error_log_del.sh
*********************************************************
# 此脚本可让日志每20分钟把大于100M的日志分割,然后当日志大于4个的时候只保留最新的两个

3.3 报错3

3.3.0 理论

rsync man 文档

max connections This parameter allows you to specify the maximum number of simultaneous connections you will allow. Any clients connecting when the maximum has been reached will receive a message telling them to try later. The default is 0, which means no limit. A negative value disables the module. See also the “lock file” parameter.
lock file This parameter specifies the file to use to support the “max connections” parameter. The rsync daemon uses record locking on this file to ensure that the max connections limit is not exceeded for the modules sharing the lock file. The default is /var/run/rsyncd.lock.

3.3.1 错误信息

@ERROR: max connections (1) reached - try again later

3.3.2 解决办法

按照官方文档上的介绍,这个错误是因为有最大连接数的限制造成的,那干脆就将其设置为0,意为无限制

max connections = 0

3.4 报错4

3.4.1 属主和权限问题

我们常用-a参数的archive模式来使用rsync命令,但是-a参数中的-o,-p,-g这三个保持属主属组和权限的参数有时候会造成属主属组和权限混乱的结果,为了明确目标文件的属主属组和权限,我们就需要这两个好用的参数--chmod--chown了,使用这两个参数可以手动指定目标文件的属主属组和权限。

--chown只在rsync3.1及之后的版本中有