Linux静态文件同步有很多种方式,也有很多的工具,比如rcp(remote file copy:远程文件复制)命令,使用远程主机上的 rsh(远程 shell)服务进行文件传输,这里介绍一个比较成熟的rsync。
rsync是一个远程数据同步工具,可通过lan/wan快速同步多台主机之间的文件,也可以使用rsync同步本地硬盘中的不同目录。它可以监控当前目录下所有文件的变动,然后使用所谓的rsync算法进行数据同步,这种算法只传递两个文件的不同部分,而不是每次都整份传递,因此速度相当快。
rsync主要所用:比对、推送、复制。它有远程比对的过程,如果只有一个文件发生变化,就只推一个文件过去,并且在传输的时候,完成了压缩工作。
安装rsync
查看系统源是否存在rsync,存在就可以直接安装,不存在需要下载rsync后编辑安装,以Debian为例:
apt update
apt list rsync*
apt install rsync
注意:远程服务器和本地服务器都需要安装rsync。
启动rsync
命令:
rsync --daemon
如果报错:
Failed to parse config file: /etc/rsyncd.conf
说明缺失配置文件,在/etc/下创建rsyncd.conf文件(文件为空也能启动,只要存在即可)
使用apt安装的rsync,配置文件默认位置:/usr/share/doc/rsync/examples/rsyncd.conf,可将此文件复制到/etc/rsyncd.conf
查看远程服务器文件
命令:
rsync --list-only 远程IP地址::资源名/
比如:
rsync --list-only 10.168.1.150::ftp/
本地同步远程文件
命令:
rsync -avz -delete 远程IP地址::资源名/ 本地存放目录
比如:
rsync -avz -delete 10.168.1.150::ftp/ /www/swoole
rsync常用指令:
远程服务器增加安全认证
1、设置用户和密码(需要创建密码文件):
在远程服务器中创建/etc/rsyncd.pwd文件,文件内容仅为“用户名:密码”,可使用echo命令将文本快速重定向到文件:
echo "dx:168" >> /etc/rsyncd.pwd
2、修改远程服务器的rsync配置文件:
auth users = dx #设置授权用户
secrets file = /etc/rsyncd.pwd #设置密码文件地址
注意账号密码是虚拟的,仅rsync软件使用,并没有在操作系统中存在。配置文件中若不存在这两项,添加即可。
3、保存后重启rsync,rsync没有重启命令,重启方式为kill进程后重新运行。
ps -ef | grep rsync
kill -9 pid
用户密码连接远程服务器
远程服务器设置了用户和密码后,每次连接都需要携带用户信息:
rsync --list-only 用户名@IP地址::资源名/
比如:
rsync --list-only dx@10.168.1.150::ftp/
输入上面的命令后,再根据提示输入密码即可连接成功。
若远程连接时提示:@ERROR: auth failed on module ftp rsync error: error starting client-server protocol (code 5) at main.c(1863) [Receiver=3.2.7]
这说明远程服务器的密码文件权限过高,有被篡改的风险,需要修改密码文件权限(降权):
chmod 600 /etc/rsyncd.pwd
修改后重启rsync。
由于rsync是后台运行,启动时一般不会报错,连接时rsync虽报了错,但却不能及时看到错误提示。所以如果发现用户名+密码连接不上,先查看密码文件权限(权限不能设置太高)。
设置免密登录
1、远程服务器设置了用户密码后,本地服务器也需要创建密码文件,内容仅为密码:
echo "111" >> /etc/rsyncd.pwd.client
2、修改权限(降权):
chmod 600 /etc/rsyncd.pwd.client
本地的密码文件类似远程服务器的密码文件,同样需要降权,如果不降权,连接远程服务器时会报错,提示需要修改密码文件的权限。
3、查看远程服务器文件列表:
rsync --list-only --password-file=密码文件地址 用户名@IP地址::资源名/
比如:
rsync --list-only --password-file=/etc/rsyncd.pwd.client dx@10.168.1.150::ftp/
注意:每次创建密码文件时,一定要修改权限。
同步更新/删除文件,命令:
rsync -avz -delete --password-file=/etc/rsyncd.pwd.client dx@10.168.1.150::ftp/ /www/swoole
近时推送方案:
在本地服务器中制作一个脚本(或安排一个频繁运行的 cron 任务),定时发送网络请求,查询远程服务器目标目录的文件是否有变化,如果发生变化,拉取变化的文件到本地进行更新。
这样做的弊端是,即使远程服务器文件长时间没有变化,但在这期间网络请求依然在不停发送,这样繁忙的轮询,消耗大量资源并且具有不确定性,并不是很理想。
实时推送方案:
远程服务器主动连接本地服务器,如果文件发生变化,远程服务器将文件推送给本地服务器。想要实现推送的动作,每个服务器都要启动rsync进程(建议配置用户和密码)。
推送命令有多种写法,这里举例说两种。
⑴ 类似上文提到的拉取命令,仅把远程服务器地址和本地服务器地址互换位置:
rsync -avz --password-file=密码文件地址 本地文件地址 用户名@目标服务器IP地址::资源名/
比如:
rsync -avz --password-file=/etc/rsyncd.pwd.client /www/swoole/ dx@10.168.1.203::ftp/
⑵ 通过rsync协议推送:
rsync -avz --password-file=/etc/rsyncd.ftp.client /www/swoole/ rsync://dx@10.168.1.203:/ftp
默认情况下,本地服务器接受提交过来的文件,有一定风险,所以会拒绝并报错:ERROR: module is read only
这时需要修改本地服务器的read only配置,打开rsync的配置文件,找到read only并把它改为read only=no,如果没有read only这一项,添加到配置文件中即可。
如果远程服务器推送执行完成后,提示这种错误:rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1333) [sender=3.2.3](如下图)
这是因为本地服务器的rsync权限不足,经测试将本地服务器的目标文件夹及子目录设置为777,依然会提示这种错误。所以建议使用如下方法:
打开本地服务器rsync的配置文件,将uid和gid改为root,如果配置文件中没有这两项,添加即可。
nano /etc/rsyncd.conf
uid = root
gid = root
rsync配置文件参考(完善中)
# sample rsyncd.conf configuration file
uid = root
gid = root
# GLOBAL OPTIONS
# motd file=/etc/motd
# log file=/var/log/rsyncd
# for pid file, do not use /var/run/rsync.pid if
# you are going to run rsync out of the init.d script.
# The init.d script does its own pid file handling,
# so omit the "pid file" line completely in that case.
# pid file=/var/run/rsyncd.pid
# syslog facility=daemon
# socket options=
# MODULE OPTIONS
# 增加授权用户
# auth users = dx
# 增加密码文件地址
# secrets file = /etc/rsyncd.pwd
[ftp]
# comment = public archive
path = /www/swoole
# use chroot = yes
# max connections=10
# lock file = /var/lock/rsyncd
# the default for read only is yes...
# read only = yes
# list = yes
# uid = nobody
# gid = nogroup
# exclude =
# exclude from =
# include =
# include from =
auth users = dx
secrets file = /etc/rsyncd.ftp.secrets
# read only = no
# strict modes = yes
# hosts allow =
# hosts deny =
# ignore errors = no
# ignore nonreadable = yes
# transfer logging = no
# log format = %t: host %h (%a) %o %f (%l bytes). Total %b bytes.
# timeout = 600
# refuse options = checksum dry-run
# dont compress = *.gz *.tgz *.zip *.z *.rpm *.deb *.iso *.bz2 *.tbz
rsync+inotify做自动化同步
inotify可以监控文件系统的读写删等操作,所以用它监测某个目录内的文件有无变化,如果发生变化,调用rsync命令,同步两台服务器的数据。
inotify不是系统内置进程,需要先安装,如果apt源中没有,也可以编译安装
apt install inotify-tool
安装成功后,查找inotifywait程序的位置,编译安装的inofity在bin目录下,使用apt安装的位置是:/usr/bin/inotifywait
下面是监测目录变化的命令:
/usr/bin/inotifywait -mrq --timefmt '%Y-%m-%d %H:%M:%S' --format '%T %w%f %e' -e close_write,modify,delete,create,attrib,move /www/swoole/
-r 表示地柜查询目录
-m 表示始终保持监听状态
-q 表示仅打印监控事件信息
--timefmt 显示事件日期
-e close_write,modify,delete,create,attrib,move 显示做了什么操作