是一款开源的、快速的、多功能的、可实现全量及增量的本地或远程数据同步备份的优秀工具。软件适用于unix、linux、windows等多种操作系统平台。全称为Remote Rynchronization。
ssh带的scp,但优于scp命令的功能,scp每次都是全量拷贝,而rsync可以增量拷贝。
Rsync还可以在本地主机的不同分区或目录之间全量及增量的复制数据,类型cp命令。
Rsync还可以实现删除文件和目录的功能。
一个rsync相当于scp,cp,rm,但是还优于他们每一个命令。
在同步备份数据时,默认情况下,Rsync通过其独特的“quick check”算法,它仅同步大小或者最后修改时间发生变化的文件或目录。也可以根据权限,属主等属性的变化同步,但需要制定相应的参数,甚至可以实现只同步一个文件里有变化的内容部分,所以能实现快速的同步备份数据。
版本区别:
version2版本会把要同步的文件加载和已有的文件比较,如果发生变化就同步过去。version3版本边比较边同步。
Rsync是文件系统之上,基于文件的同步;基于block的同步用drbd。
union双机互相同步,csync2多机同步。
语法: rsync [option...] src... [dest]
说明:
[option]为同步时的参数选项 -avz
-z --compress 传输时进行压缩以提高传输效率,--compress-level=NUM可按级别压缩。
-v --verbose 详细模式输出,传输时的进度等信息。
-a --archive归档模式,表示以递归方式传输文件,并保持所有文件属性。等于-rtopgDl
-r --对子目录以递归模式,及目录下的所有目录都同样传输。
-t --保持文件时间信息。
-o --保持文件属主信息。
-p --保持文件权限。
-g --保持文件属组信息。
-P --显示同步的过程及传输时的进度信息。
-D --保持设备文件信息。
-l --保留软连接。
-e 使用的信道协议,指定替代rsh的shell。
--exclude=PATTERN 指定排除不需要传输的文件模式。
[src]为源,即需要拷贝的分区、文件或目录等。
[dest]为目的分区、文件或目录等。
单个主机本地之间的数据传输 本地传输模式(local-only mode)
rsync -avz /etc /tmp/ ---增量的拷贝方式
如果拷贝目录不带”/“,表示拷贝的内容包括本层目录,如果带"/"表示拷贝本层目录以下的内容。
删除(删除性的复制)--- 就是让/tmp和/data/null中的内容完全一致。
rsync -avz --delete /data/null/ /tmp/
rsync -r --delete /tmp/cc/ /tmp/data
借助rsync命令,通过ssh通道来传输数据(此时类似于scp命令的功能)
推方式
rsync -avz /tools/httpd-2.2.27.tar.gz -e 'ssh -p 19527' [email protected]:/tools
/tools/libiconv-1.14.tar.gz ---本地文件
[email protected]:/tools ---远程主机的系统用户和地址、路径
拉方式
rsync -avz -e 'ssh -p 19527' [email protected]:/tools/xy /tmp/
从客户端推送内容时,客户端内容与服务器端内容一致,如果服务器端有其他内容,直接被删除与客户端内容保持一致。
从服务端拉取内容时,服务端内容与客户端内容一致,如果客户端有其他内容,直接被删除与服务端内容保持一致。
rsync -avz --delete /tmp/ rsync://[email protected]/oldboy/ --password-file=/etc/rsync.password
本地目录内容会被清除:
rsync -avz --delete rsync://[email protected]/oldboy/ /tmp --password-file=/etc/rsync.password
排除单个文件(客户端)
rsync -avz --exclude=6.txt /tmp/ rsync://[email protected]/backup --password-file=/etc/rsync.password
排除多个文件(客户端)
rsync -avz --exclude={1..5}.txt /tmp/ rsync://[email protected]/backup --password-file=/etc/rsync.password
rsync -avz --exclude={1,2,3,4,5}.txt /tmp/ rsync://[email protected]/backup --password-file=/etc/rsync.password
通过排除文件进行排除(客户端)
rsync -avz --exclude-from=paichu.log /tmp/ rsync://[email protected]/backup --password-file=/etc/rsync.password
服务端排除(配置完成后,需要重启服务)
服务端配置文件中增加
exclude=a b --通过空格隔开
将相同性内容放在一起,创建不同的框
服务端配置文件中增加
[backup]
path = /oldboy/
ignore errors
[backup1]
path = /oldboy1/
Web客户端从Rsync服务端拉取最新网站代码。
需求环境:3台服务器
安装服务(依赖epel源)
yum install rsync -y
设置rsync服务开机自启动
systemctl enable rsyncd
创建rsync用户
useradd rsync -s /sbin/nologin -M
创建共享目录、改权限
mkdir /data/generate_page/ -p
chown -R rsync.rsync /data/generate_page/
将用户和密码写入密码文件、并修改访问权限
echo "web_rsync:web_pass" >/etc/rsync.password
chmod 600 /etc/rsync.password
#web_rsync表示用户名
#web_pass表示密码
编辑rsyncd.conf配置文件
uid = rsync
gid = rsync
use chroot = no
max connections = 200
timeout = 300
#log file = /var/log/rsyncd.log
[webpage]
path=/data/generate_page/
ignore errors
read only=no
list=no
exclude=lost+found/
hosts allow=192.168.0.0/16
auth users=web_rsync
secrets file=/etc/rsync.password
注释
uid = rsync --rsync 用户 (默认是nobody)
gid = rsync --rsync 用户 (默认是nobody)
use chroot = no
max connections = 200 --最大连接数 有多少客户端能连接
timeout = 300 --连接超时
[webpage] --模块名字
path = /data/generate_page/ --服务端共享的目录(可以理解为NFS的共享目录)
ignore errors -- 忽略错误
read only = false --可写
list = false --不容许列表
hosts allow = 192.168.0.0/16 --容许的主机段
auth users = web_rsync --连接的用户(虚拟用户,非系统用户)
secrets file = /etc/rsync.password --用户对应的密码文件(将密码写入到文件中,省去手敲的麻烦)
在客户端将密码写入密码文件、并修改访问权限,只放入密码,不用用户名。
echo "web_pass" >/etc/rsync.password
chmod 600 /etc/rsync.password
客户端从服务器端拉取
需要输入密码的命令:
rsync -avz --delete [email protected]::webpage/ /data/static/
Password:
#[email protected] --服务器端用户和IP地址
#backup/ --服务器端模块名字(框目录)
#/opt/ --拉到本地文件夹
#password-file=/etc/rsync.password --虚拟用户(rsync_backup)的密码
使用密码文件的命令:
rsync -avz --delete [email protected]::webpage/ /data/static/ --password-file=/etc/rsync.password
基本情况
安装配置
# Epel源自行安装
yum install inotify-tools
对于百万级文件的实施拷贝,我个人的想法和这位兄弟不谋而合,讲的很透彻,这才是实践出真知的文章,以下内容摘自真正的inotify+rsync实时同步 彻底告别同步慢
背景
我们公司在用inotify+rsync做实时同步,来解决分布式集群文件一致性的问题。但当web文件越来越多(百万级数量html,jpg等小 文件),同步就越来越慢,根本做不到实时,按照网上的调优方法都尝试过,问题根本没有解决。经过我一翻细致研究,终于把慢的核心问题研究明白,先总结一句 inotifywait响应不会有延迟,rsync也很快。大家同样有慢的烦恼,那是因为网上的inotify+rsync的教程都是坑。下面我们来分析。
inotifywait 单独分析
/usr/local/bin/inotifywait -mrq --format '%Xe %w%f' -e modify,create,delete,attrib /data/
# 执行上面命令,是让inotifywait监听/data/目录,当监听到有发生modify,create,delete,attrib等事件发生时,按%Xe %w%f的格式输出。
# 在/data/目录touch几个文件
touch /data/{1..5}
观看inotify输出
ATTRIB /data/1 -- 表示发生了ATTRIB事件 路径为/data/1
ATTRIB /data/2
ATTRIB /data/3
ATTRIB /data/4
ATTRIB /data/5
知道上面的输出效果之后 我们应该想得到,可以用rsync获取inotifywait监控到的文件列表来做指定的文件同步,而不是每次都由rsync做全目录扫描来判断文件是否存在差异。
网上的inotify+rsync分析
我们来看网上的教程,我加了注释。(网上所有的教程基本都一模一样,尽管写法不一样,致命点都是一样的)
#!/bin/bash
/usr/bin/inotifywait -mrq --format '%w%f'-e create,close_write,delete /backup |while read file
#把发生更改的文件列表都接收到file 然后循环,但有什么鬼用呢?下面的命令都没有引用这个$file 下面做的是全量rsync
do
cd /backup && rsync -az --delete /backup/ [email protected]::backup/--password-file=/etc/rsync.password
done
#注意看 这里的rsync 每次都是全量的同步(这就坑爹了),而且 file列表是循环形式触发rsync ,等于有10个文件发生更改,就触发10次rsync全量同步(简直就是噩梦),那还不如直接写个死循环的rsync全量同步得了。
#有很多人会说 日志输出那里明明只有差异文件的同步记录。其实这是rsync的功能,他本来就只会输出有差异需要同步的文件信息。不信你直接拿这句rsync来跑试试。
#这种在需要同步的源目录文件量很大的情况下,简直是不堪重负。不仅耗CPU还耗时,根本不可以做到实时同步。
备注:backup为rsync server配置module,除了编写脚本以外,还需要配置一个rsync server,rsync server配置参考《http://www.ttlsa.com/linux/rsync-install-on-linux/》
改良方法
要做到实时,就必须要减少rsync对目录的递归扫描判断,尽可能的做到只同步inotify监控到已发生更改的文件。结合rsync的特性,所以这里要分开判断来实现一个目录的增删改查对应的操作。
#!/bin/bash
src=/data/www # 需要同步的源路径
des=test # 目标服务器上 rsync --daemon 发布的名称,rsync --daemon这里就不做介绍了,网上搜一下,比较简单。
#rsync_passwd_file=/etc/rsyncd.passwd # rsync验证的密码文件
ip1=172.19.5.20 # 目标服务器1
cd ${src} # 此方法中,由于rsync同步的特性,这里必须要先cd到源目录,inotify再监听 ./ 才能rsync同步后目录结构一致
/usr/bin/inotifywait -mrq --format '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ./ | while read file # 把监控到有发生更改的"文件路径列表"循环
do
INO_EVENT=$(echo $file | awk '{print $1}') # 把inotify输出切割 把事件类型部分赋值给INO_EVENT
INO_FILE=$(echo $file | awk '{print $2}') # 把inotify输出切割 把文件路径部分赋值给INO_FILE
echo "-------------------------------$(date)------------------------------------"
echo $file
#增加、修改、写入完成、移动进事件
#增、改放在同一个判断,因为他们都肯定是针对文件的操作,即使是新建目录,要同步的也只是一个空目录,不会影响速度。
if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'MODIFY' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]] # 判断事件类型
then
echo 'CREATE or MODIFY or CLOSE_WRITE or MOVED_TO'
rsync -avzcR $(dirname ${INO_FILE}) ${ip1}::${des} # INO_FILE变量代表路径哦 -c校验文件内容
#仔细看 上面的rsync同步命令 源是用了$(dirname ${INO_FILE})变量 即每次只针对性的同步发生改变的文件的目录(只同步目标文件的方法在生产环境的某些极端环境下会漏文件 现在可以在不漏文件下也有不错的速度 做到平衡) 然后用-R参数把源的目录结构递归到目标后面 保证目录结构一致性
fi
#删除、移动出事件
if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
then
echo 'DELETE or MOVED_FROM'
rsync -avzR --delete $(dirname ${INO_FILE}) ${ip1}::${des}
#看rsync命令 如果直接同步已删除的路径${INO_FILE}会报no such or directory错误 所以这里同步的源是被删文件或目录的上一级路径,并加上--delete来删除目标上有而源中没有的文件,这里不能做到指定文件删除,如果删除的路径越靠近根,则同步的目录月多,同步删除的操作就越花时间。这里有更好方法的同学,欢迎交流。
fi
#修改属性事件 指 touch chgrp chmod chown等操作
if [[ $INO_EVENT =~ 'ATTRIB' ]]
then
echo 'ATTRIB'
if [ ! -d "$INO_FILE" ] # 如果修改属性的是目录 则不同步,因为同步目录会发生递归扫描,等此目录下的文件发生同步时,rsync会顺带更新此目录。
then
rsync -avzcR $(dirname ${INO_FILE}) ${ip1}::${des}
fi
fi
done
每两小时做1次全量同步
因为inotify只在启动时会监控目录,他没有启动期间的文件发生更改,他是不知道的,所以这里每2个小时做1次全量同步,防止各种意外遗漏,保证目录一致。
#crontab -e
* */2 * * * rsync -avz --password-file=/etc/rsync-client.pass /data/ [email protected]::data && rsync -avz --password-file=/etc/rsync-client.pass /data/ [email protected]::data
改良后我们公司这种百万级小文件也能做到实施同步了。
inotifywait 参数说明
参数名称 | 参数说明 |
---|---|
-m,–monitor | 始终保持事件监听状态 |
-r,–recursive | 递归查询目录 |
-q,–quiet | 只打印监控事件的信息 |
–excludei | 排除文件或目录时,不区分大小写 |
-t,–timeout | 超时时间 |
–timefmt | 指定时间输出格式 |
–format | 指定时间输出格式 |
-e,–event | 后面指定删、增、改等事件 |
inotifywait events事件说明
事件名称 | 事件说明 |
---|---|
access | 读取文件或目录内容 |
modify | 修改文件或目录内容 |
attrib | 文件或目录的属性改变 |
close_write | 修改真实文件内容 |
close_nowrite | |
close | |
open | 文件或目录被打开 |
moved_to | 文件或目录移动到 |
moved_from | 文件或目录从移动 |
move | 移动文件或目录移动到监视目录 |
create | 在监视目录下创建文件或目录 |
delete | 删除监视目录下的文件或目录 |
delete_self | |
unmount | 卸载文件系统 |
优化参数
# ll /proc/sys/fs/inotify/
max_user_watches #设置inotifywait或inotifywatch命令可以监视的文件数量(单进程)
max_user_instances #设置每个用户可以运行的inotifywait或inotifywatch命令的进程数
max_queued_events #设置inotify实例事件(event)队列可容纳的事件数量
内核参数设置
由于默认参数过小,根据需要增加内核参数
fs.inotify.max_queued_events = 90000000
fs.inotify.max_user_instances = 1024
fs.inotify.max_user_watches = 90000000
其他fs.epoll.max_user_watches
rsync 推送小文件过慢的原因
日志查看发现每次请求出现了域名解析
2013/10/13 04:01:46 [18610] name lookup failed for xxx.xxx.xxx: Name or service not known
2013/10/13 04:01:46 [18610] connect from UNKNOWN (xxx.xxx.xxx.xxx)
2013/10/13 04:02:47 [18633] name lookup failed for xxx.xxx.xxx.xxx: Name or service not known
2013/10/13 04:02:47 [18633] connect from UNKNOWN (xxx.xxx.xxx.xxx)
解决办法
Rsync服务器创建hosts文件,解析所有IP
权限错误
一共有两种权限
客户端权限
推送到服务端时,设置和rsync server相同的uid用户
服务端权限
rsync server设置的uid要和发布目录权限一致