rsync完全教程+百万级小文件实时同步

1)在node1 node2上实现双向无密码验证
[root@node1 ~]# ssh-keygen
[root@node1 ~]# ssh-copy-id -i .ssh/id_rsa.pub node2

[root@node2 ~]# ssh-keygen
[root@node2 ~]# ssh-copy-id -i .ssh/id_rsa.pub node1

2)node1 node2 安装软件 rsync
[root@node1 ~]# yum install -y rsync
[root@node2 ~]# yum install -y rsync

本地同步
语法:rsync -avz  [源] [目的]

在node2上测试本地同步

[root@node2 ~]# ll /test1
总用量 0
-rw-r--r-- 1 root root 0 3月  27 16:33 dfqwer
-rw-r--r-- 1 root root 0 3月  27 16:33 qwer
-rw-r--r-- 1 root root 0 3月  27 16:33 rd
[root@node2 ~]# ll /test2
总用量 0

本地同步开始

[root@node2 ~]# rsync -avz /test1/ /test2/         /test1是源  /test2是目的
sending incremental file list
./
dfqwer
qwer
rd

sent 180 bytes  received 72 bytes  504.00 bytes/sec
total size is 0  speedup is 0.00
[root@node2 ~]#


查看目的

[root@node2 ~]# ll /test2/
总用量 0
-rw-r--r-- 1 root root 0 3月  27 16:33 dfqwer
-rw-r--r-- 1 root root 0 3月  27 16:33 qwer
-rw-r--r-- 1 root root 0 3月  27 16:33 rd
[root@node2 ~]#


异地同步

从本地推送到别的机器上
语法:      rsync     -avz    [源]      IP:[目的]


从别的机器上拉取到自己的本机上
语法:      rsync     -avz   IP:[源]       [目的]


实验1:从本地推送到别的机器上(node2推送到node1)

[root@node2 /]# ll /lianshou/   本机
总用量 0
-rw-r--r-- 1 root root 0 3月  27 16:42 lllllll
-rw-r--r-- 1 root root 0 3月  27 16:42 ooooooo

[root@node1 ~]# ll /lianshou/   对方
总用量 0

[root@node2 /]# rsync -avz /lianshou/ node1:/lianshou/  本机推送到对方
sending incremental file list
./
lllllll
ooooooo

sent 133 bytes  received 53 bytes  124.00 bytes/sec
total size is 0  speedup is 0.00

[root@node1 ~]# ls /lianshou/               对方查看接受到的东西
lllllll  ooooooo

实验2:从对方机器上拉取内容到本机

[root@node1 ~]# ll /lianshou/                 对方的内容
总用量 0
-rw-r--r-- 1 root root 0 3月  27 16:42 lllllll
-rw-r--r-- 1 root root 0 3月  27 16:42 ooooooo
-rw-r--r-- 1 root root 0 3月  27 17:08 sdfasdfasdfasd
-rw-r--r-- 1 root root 0 3月  27 17:08 ttttttt

[root@node2 ~]# ll /lianshou/               本机的内容
总用量 0
-rw-r--r-- 1 root root 0 3月  27 16:42 lllllll
-rw-r--r-- 1 root root 0 3月  27 16:42 ooooooo

[root@node2 ~]# rsync -avz node1:/lianshou/ /lianshou/           从对方连拉取内容过来
receiving incremental file list
./
lllllll
ooooooo
sdfasdfasdfasd
ttttttt

sent 90 bytes  received 253 bytes  137.20 bytes/sec
total size is 0  speedup is 0.00

[root@node2 ~]# ll /lianshou/               查看本机接受的东西
总用量 0
-rw-r--r-- 1 root root 0 3月  27 16:42 lllllll
-rw-r--r-- 1 root root 0 3月  27 16:42 ooooooo
-rw-r--r-- 1 root root 0 3月  27 17:08 sdfasdfasdfasd
-rw-r--r-- 1 root root 0 3月  27 17:08 ttttttt

 


在下面附上rsync常用参数说明

-v                                      详细输出模式
-q                                      精简输出模式
-c                                      打开校验开关,强制对文件传输进行校验
-a                                   归档模式,表示以递归方式传输文件,并且爆保持所有文件属性,等于-rlptgoD
-r                                    对子目录以递归模式处理
-R                                  使用相对路径信息
-p                                   保持文件权限
-o                                  保持文件属主信息
-g                                   保持文件属组信息
-t                                  保持文件时间信息
-n                                  指定那些文件将被传输
-W                                  复制文件,不进行增量检测
-e                                  使用rsh,ssh方式进行数据同步
-delete                           删除那些DST中SRC没有的文件
-timeout=TIMEIP              超时时间,单位为秒
-z                                   对备份的文件在传输时进行压缩处理
--exclude=PATTERN          指定排除不需要的传输的文件模式
--include=PATTERN           指定不排除而需要传输的文件模式
--exclude-from=FILE         排除FILE中指定模式的文件
--include-from=FILE         不排除FILE指定模式匹配的文件
--version                           打印版本信息
-address                            绑定到特定的地址
--config=FILE                     指定其他的配置文件,不使用默认的rsyncd.conf文件
--port=PORT                       指定其他的rsync服务端口
--progress                          在传输时实现传输过程
--log-format=format             指定日志文件格式
--password-file=FILE            从FILE中得到密码

rsync在数据同步时,需要扫描所有的文件进行对比,然后进行差量传输,但是文件很多,扫描文件是非常耗时的,使用rsync反而比较低效

 

rsync以守护模式启动

 

在node1上写配置文件,配置文件里主要写的是指定node1上哪个文件夹,远程对他推动,还是拉取这个这个文件夹,取决与别人的机器写的命令
在node1上写密码文件,密码文件写用户名和密码
然后在node1以守护模式启动就行了

编辑配置文件
[root@node1 ~]# vim /etc/rsyncd.conf
uid = nobody
gid = nobody
use chroot = no
max connections = 10        //最大连接数,0是没有限制
strict modes = yes              检查口令文件的权限,要求是600
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
log file = /var/log/rsyncd.log
[tui]                     //定义了一个模块,模块的名字任意,有代表性的
path = /tui            //备份的目录
comment = tui       //描述
ignore errors           //忽略一些无关紧要的错误
read only = no         //可以上传;yes 拒绝
write only = no          //可以下载;yes 拒绝
hosts allow = *         //允许连接的主机,* 所有的
hosts deny = 0.0.0.0/32     //拒绝连接的主机
list = false                           //禁止列表模式
uid = root                              //给这个模块设置一个单独的用户和组
gid = root
auth users = backup             //验证连接的用户,用户名自定义,这个用户和系统用户无关,如果有多个,使用 , 分隔。
secrets file = /etc/server.pass  //口令文件
编辑密码口令文件
[root@node1 ~]# cat /etc/server.pass   
backup:etc123
设置密码口令文件权限
[root@node1 ~]# chmod 600 /etc/server.pass
然后以守护进程模式启动
[root@node1 ~]# /usr/local/bin/rsync --daemon

到此node1的配置就完成了


node2上的配置,只需要密码口令文件
[root@node2 ~]# echo etc123 > /etc/server.pass
[root@node2 ~]# chmod 600 /etc/server.pass
[root@node2 ~]# cat /etc/server.pass
etc123


(1)首先测试node2拉取node1上的文件
把node1中的/tui文件夹下的文件拉取到node2的/tmp文件夹中


[root@node2 ~]# ll /tmp
总用量 0
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi1
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi2
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi3
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi4

[root@node1 ~]# ll /tui
总用量 0
-rw------- 1 root root 0 3月  23 11:33 yum.log

拉取的语法  rsynv  各种选项   源  目的 密码文件

语法
rsync -avzr   [选项]   用户名@IP::模式名  目的  --password-file=本地密码文件路径

[root@node2 ~]# rsync -avzr backup@node1::tui /tmp/ --password-file=/etc/server.pass
receiving incremental file list
./
yum.log

sent 78 bytes  received 179 bytes  514.00 bytes/sec
total size is 0  speedup is 0.00

查看本地/tmp文件夹
[root@node2 ~]# ll /tmp
总用量 0
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi1
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi2
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi3
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi4
-rw------- 1 root root 0 3月  23 11:33 yum.log

 

(2)然后测试node2往node1上推送内容
把node2中的/tmp文件夹下的文件推送到node1的/tui文件夹中


[root@node1 ~]# ll /tui
总用量 0
-rw------- 1 root root 0 3月  23 11:33 yum.log

[root@node2 ~]# ll /tmp/
总用量 0
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi1
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi2
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi3
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi4
-rw------- 1 root root 0 3月  23 11:33 yum.log

推送的语法    rsynv  各种选项   源  目的 密码文件

语法
rsync -avzr   [选项]   源  用户名@IP::模式名    --password-file=本地密码文件路径


[root@node2 ~]# rsync -avzr /tmp/ backup@node1::tui --password-file=/etc/server.pass

查看node1上是否推送过去

[root@node1 ~]# ll /tui
总用量 0
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi1
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi2
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi3
-rw-r--r-- 1 root root 0 3月  27 17:59 cishi4
-rw------- 1 root root 0 3月  23 11:33 yum.log

推送的命令写入计划任务:
每天凌晨2点半 30 2 * * * /usr/bin/rsync -avzr /tmp/
backup@node1::tui --password-file=/etc/server.pass

也可以写拉取的

 

 

rsync写入计划任务有两点缺陷

缺欠1:在2次触发同步数据之间如果出现数据丢失,那就找不到了。
缺欠2:rsync使用自己的内部算法,比对每个文件,备份的文件越多,比对的时间就越长  很容易卡死

解决缺欠1:rsync+inotify。

在node2上安装inotify工具,因为使用inotify,只能使用推送模式,检查推送的文件夹是否有内容变动,如果有,就推送过去

因为我电脑之前inotify用源码包装的,所以我就默认使用了源码包安装的路径,就不演示inotify yum的安装了,/usr/bin/inotifywait为YUM安装的命令存放路径,我自己的是
源码安装的所以,我把路径设置为/usr/local/inotify/bin//inotifywait
大家看我脚本的时候注意下路径


[root@node2 ~]# yum install -y inotify-tools-3.14-1.el6.x86_64

编写实时推送脚本
这是一个node2检测/tmp目录是否有变化,有变化就把/tmp下的内容推送到node1上的/test目录中

[root@node2 tmp]# cat inotify.sh
#!/bin/bash
ip=192.168.1.225
src=/tmp
dst=test
user=backup
rsync_passfile=/etc/server.pass
inotify_home=/usr/local/inotify
if [ ! -e "$src" ] || [ ! -e "${rsync_passfile}" ] || [ ! -e "${inotify_home}/bin/inotifywait" ] || [ ! -e "/usr/bin/rsync" ];
then
echo "Check File and Folder"
exit 9
fi
${inotify_home}/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e close_write,delete,create,attrib $src | while read line
do
rsync -azr  --delete ${src}/  $user@$ip::$dst --password-file=${rsync_passfile} >/dev/null 2>&1
done
exit 0


查看下node2 /tmp下内容

[root@node2 tmp]# ls
inotify.sh

查看下node1 /test中的内容
[root@node1 test]# ll
总用量 0

在node2上执行脚本,我们开启调试,查看脚本运行过程

[root@node2 tmp]# sh -x inotify.sh
+ ip=192.168.1.225
+ src=/tmp
+ dst=test
+ user=backup
+ rsync_passfile=/etc/server.pass
+ inotify_home=/usr/local/inotify
+ '[' '!' -e /tmp ']'
+ '[' '!' -e /etc/server.pass ']'
+ '[' '!' -e /usr/local/inotify/bin/inotifywait ']'
+ '[' '!' -e /usr/bin/rsync ']'
+ read line
+ /usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f' -e close_write,delete,create,attrib /tmp
//到这开始监听/tmp


[root@node2 tmp]# touch 123  //在/tmp创建123文件
[root@node2 tmp]# ll
总用量 4
-rw-r--r-- 1 root root   0 3月  27 18:51 123
-rw-r--r-- 1 root root 547 3月  27 18:40 inotify.sh


node1上有了node2上的推送内容

[root@node1 test]# ll
总用量 4
-rw-r--r-- 1 root root   0 3月  27 18:51 123
-rw-r--r-- 1 root root 547 3月  27 18:40 inotify.sh

但是看脚本执行过程

+ rsync -azr --delete /tmp/ backup@192.168.1.225::test --password-file=/etc/server.pass
+ read line
+ rsync -azr --delete /tmp/ backup@192.168.1.225::test --password-file=/etc/server.pass
+ read line
+ rsync -azr --delete /tmp/ backup@192.168.1.225::test --password-file=/etc/server.pass
+ read line

创建一个文件居然同步了三次 

那么更改个文件内容呢

[root@node2 tmp]# vim 123
123456
"123" 1L, 7C 已写入

+ rsync -azr --delete /tmp/ backup@192.168.1.225::test --password-file=/etc/server.pass
+ read line
+ rsync -azr --delete /tmp/ backup@192.168.1.225::test --password-file=/etc/server.pass
+ read line
+ rsync -azr --delete /tmp/ backup@192.168.1.225::test --password-file=/etc/server.pass
+ read line
+ rsync -azr --delete /tmp/ backup@192.168.1.225::test --password-file=/etc/server.pass
+ read line
+ rsync -azr --delete /tmp/ backup@192.168.1.225::test --password-file=/etc/server.pass
+ read line

居然同步了6次,显然这种写法效率不高

 

解决缺欠2:rsync+inotify+优化脚本。
 
到此大概了解了inotity+rysnc的同步过程,咱们看看网上大部分的写法

#!/bin/bash
/usr/local/inotify/bin/inotifywait -mrq --format '%w%f' -e create,close_write,delete /tmp | while read line
#把发生更改的文件列表都接收到line然后循环,但有什么鬼用呢?下面的命令都没有引用这个$line 下面做的是全量rsync
do
    cd /tmp && rsync -arz --delete /tmp/ backup@192.168.1.225::test --password-file=/etc/server.pass
done


注意看这里的rsync 每次都是全量的同步(这就坑爹了),而且line列表是循环形式触发rsync ,
等于有10个文件发生更改,就至少触发10次rsync全量同步(简直就是噩梦),而且一般创建个
文件,触发好几次同步,如果几百个文件变动,同步动作至少上千次,那还不如直接写个死
循环的rsync全量同步得了。

 

改良的写法


#!/bin/bash
src=/tmp
des=test
rsync_passwd_file=/etc/server.pass
ip1=192.168.1.225
user=backup
cd ${src}    # 此方法中,由于rsync同步的特性,这里必须要先cd到源目录,inotify再监听 ./ 才能rsync同步后目录结构一致,有兴趣的同学可以进行各种尝试观看其效果
/usr/local/inotify/bin/inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ./ | while read line      # 把监控到有发生更改的文件写到line变量中
do
        INO_EVENT=$(echo $line | awk '{print $1}')              # 把inotify输出切割 把事件类型部分赋值给INO_EVENT
        INO_FILE=$(echo $line | awk '{print $2}')                   # 把inotify输出切割 把文件路径部分赋值给INO_FILE
        echo "-------------------------------$(date)------------------------------------"
        echo $line
        #增加、修改、写入完成、移动进事件
        #增、改放在同一个判断,因为他们都肯定是针对文件的操作,即使是新建目录,要同步的也只是一个空目录,不会影响速度。
        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 --password-file=${rsync_passwd_file} $(dirname ${INO_FILE})${user}@${ip1}::${des}              # INO_FILE变量代表路径
        
                #仔细看 上面的rsync同步命令 源是用了$(dirname ${INO_FILE})变量 即每次只针对性的同步发生改变的文件的目录(只同步目标文件的方法在生产环境的某些极端环境下会漏文件 现在可以在不漏文件下也有不错的速度 做到平衡) 然后用-R参数把源的目录结构递归到目标后面 保证目录结构一致性
        fi


        if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
        #删除、移动出事件
        then
                echo 'DELETE or MOVED_FROM'
                rsync -avzR --delete --password-file=${rsync_passwd_file} $(dirname ${INO_FILE})${user}@${ip1}::${des}
                 #看rsync命令 如果直接同步已删除的路径${INO_FILE}会报no such or directory错误 所以这里同步的源是被删文件或目录的上一级路径,并加上--delete来删除目标上有而源中没有的文件,这里不能做到指定文件删除,如果删除的路径越靠近根,则同步的目录月多,同步删除的操作就越花时间。这里有更好方法的同学,欢迎交流。
        fi


        if [[ $INO_EVENT =~ 'ATTRIB' ]]
         #修改属性事件 指 touch chgrp chmod chown等操作
        then
                echo 'ATTRIB'
                if [ ! -d "$INO_FILE" ]             # 如果修改属性的是目录 则不同步,因为同步目录会发生递归扫描,等此目录下的文件发生同步时,rsync会顺带更新此目录。
                then
                        rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE})${user}@${ip1}::${des}
                        
                fi
        fi
done


注意虽然创建一个文件依然会同步好几次,但是这个不会是全部同步,而是同步这个文件的所在的文件夹,假如一个项目中很多个文件夹,只有一个
文件夹一个文件发生了变动,只要同步这个项目中的文件夹就可以了,而不会同步所有的文件

 

每两小时做1次全量同步

因为inotify只在启动时会监控目录,他没有启动期间的文件发生更改,他是不知道的,所以这里每2个小时做1次全量同步,防止各种意外遗漏,保证目录一致。

crontab -e
* */2 * * * rsync -avz --password-file=/etc/server.pass /tmp/
backup@node1::test

这种百万级小文件也能做到实施同步了。

 

下面附上inotify的参数说明

inotify介绍-- 是一种强大的、细颗粒的、异步的文件系统监控机制,内核从2.6.13起,
加入Inotify可以监控文件系统中添加、删除、修改移动等各种事件,利用这个内核接
口,就可以监控文件系统下文件的各种变化情况。

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                       卸载文件系统

优化 Inotify

# 在/proc/sys/fs/inotify目录下有三个文件,对inotify机制有一定的限制

[root@web ~]# ll /proc/sys/fs/inotify/
总用量0
-rw-r--r--1 root root 09月923:36 max_queued_events
-rw-r--r--1 root root 09月923:36 max_user_instances
-rw-r--r--1 root root 09月923:36 max_user_watches

max_user_watches #设置inotifywait或inotifywatch命令可以监视的文件数量(单进程)

max_user_instances #设置每个用户可以运行的inotifywait或inotifywatch命令的进程数

max_queued_events #设置inotify实例事件(event)队列可容纳的事件数量

 


[root@web ~]# echo 50000000>/proc/sys/fs/inotify/max_user_watches -- 把他加入/etc/rc.local就可以实现每次重启都生效
[root@web ~]# echo 50000000>/proc/sys/fs/inotify/max_queued_events

 

下面是把rsync做成系统服务的样子,还有设置为开机启动服务

[root@node1 init.d]# cat /etc/init.d/rsyncd
#!/bin/bash
#
# rsync Start|Stop script for the Rsync service
#
# chkconfig: - 13 87
# description: The Rsyncd Server management shell script
# processname: rsyncd
# config: /etc/rsyncd.conf
# pidfile: /var/run/rsyncd.pid
# Source function library.
. /etc/rc.d/init.d/functions
start () {
ls /var/run/rsyncd.pid &> /dev/null
if [ $? -ne 0 ]
then
/usr/bin/rsync --daemon
count=$(ps -ef | grep -v grep | grep -c rsync)
        if [ $? -eq 0 -a ${count} -gt 1 ]
        then
        echo -e "Starting rsyncd:\t\t\t[ \e[1;32mOK\e[0m ]"
        else
        echo -e "Starting rsyncd:\t\t\t[\e[1;31mFAILED\e[0m]"
        fi
else
echo -e "Starting rsyncd:\t\t\t[\e[1;31mFAILED\e[0m]"7/12
fi
}


stop () {
ls /var/run/rsyncd.pid &> /dev/null
if [ $? -eq 0 ]
then
kill -9 `cat /var/run/rsyncd.pid` && /bin/rm -rf /var/run/rsyncd.pid
        if [ $? -eq 0 ]
        then
        echo -e "Stopping rsyncd:\t\t\t[ \e[1;32mOK\e[0m ]"
        else
        echo -e "Stopping rsyncd:\t\t\t[\e[1;31mFAILED\e[0m]"
        fi
else
echo -e "Stopping rsyncd:\t\t\t[\e[1;31mFAILED\e[0m]"
fi
}
case $1 in
start)
start
;;
stop)
stop
;;
restart|reload)
stop
start
;;
*)
echo "Usage: rsyncd {start|stop|restart|reload}"
;;
esac
#end

开机自启动
[root@node1 init.d]# chkconfig rsyncd --list
rsyncd 服务支持 chkconfig,但它在任何级别中都没有被引用(运行“chkconfig --add rsyncd”)
[root@node1 init.d]# chkconfig --add rsyncd
[root@node1 init.d]# chkconfig rsyncd on
[root@node1 init.d]# chkconfig rsyncd --list
rsyncd          0:关闭  1:关闭  2:启用  3:启用  4:启用  5:启用  6:关闭


[root@node1 init.d]# find -L /etc -name  rsyncd  
/etc/rc.d/init.d/rsyncd
/etc/init.d/rsyncd

 

 

 

文章部分摘自http://www.ttlsa.com/web/let-infotify-rsync-fast/,我做了些完善

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值