Linux 运维手册之 rsync 数据同步服务
后知后觉 暂无评论

RsyncRemote Synchronize,远程数据同步)可通过LAN/WAN快速同步多台主机间的文件,是一种用于跨越主机或硬盘实现数据同步(备份)的工具。

rsync is an open source utility that provides fast incremental file transfer. rsync is freely available under the GNU General Public License and is currently being maintained by Wayne Davison.

RSYNC 服务简介

rsync是一款开源的备份工具,可以在不同主机之间进行同步,可实现全量备份与增量备份,保持链接和权限,且采用优化的同步算法,传输前执行压缩,因此非常适合用于架构集中式备份或异地备份等应用。

rsync 是用于取代 rcp 的一个工具,独有的 rsync 算法来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是全量传输,因此速度相当快。

rsync 的初始作者是 Andrew TridgellPaul Mackerras,本项目现已转由 Samba 维护。

默认监听端口:873
默认运行模式:C/S

Rsync 有三种同步方式:

举个例子:

假设客户端上有 file1 file2 file3 文件,服务端上已有 file1 文件,现要将客户端上的数据备份至服务端。

完全备份:将客户端所有的数据内容file1 file2 file3全部备份至服务端(效率低下,占用空间)
增量备份:将客户端的file2 file3增量备份至服务端 (提高备份效率,节省空间,适合异地备份)

RSYNC 同步方式

数据同步的两种方式:
推:(push)一台主机负责把数据推送至其他主机,服务器资源开销大。(适合推送少量主机)
拉:(pull)所有主机定时去找同一主机拉取数据,可能会占用极大带宽导致数据同步缓慢。


RSYNC 传输模式

有三种主要的数据传输方式:

//Local:  本地传输
rsync [OPTION...] SRC... [DEST]  

Access via remote shell:    远程通道传输
    Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]
    Push: rsync [OPTION...] SRC... [USER@]HOST:DEST

Access via rsync daemon:    守护进程方式传输
    Pull: rsync [OPTION...] [USER@]HOST::SRC... [DEST]
          rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]
    Push: rsync [OPTION...] SRC... [USER@]HOST::DEST
          rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST

命令选项及参数

-a           //归档模式传输, 等于-tropgDl
-v           //详细模式输出, 打印速率, 文件数量等
-z           //传输时进行压缩以提高效率
-r           //递归传输目录及子目录,即目录下得所有目录都同样传输。
-t           //保持文件时间信息
-o           //保持文件属主信息
-p           //保持文件权限
-g           //保持文件属组信息
-l           //保留软连接
-P           //显示同步的过程及传输时的进度等信息
-D           //保持设备文件信息
-L          //保留软连接指向的目标文件
-e           //使用的信道协议,指定替代rsh的shell程序
--exclude=PATTERN   //指定排除不需要传输的文件模式
--exclude-from=file //文件名所在的目录文件
--bwlimit=100       //限速传输
--partial           //断点续传
--delete            //让目标目录和源目录数据保持一致

本地模式

单个主机本地之间的数据传输(此场景下等同于 cp 命令)

Local:  rsync [OPTION...] SRC... [DEST]
rsync         ---数据备份命令
[OPTION...]   ---命令相关参数
SRC...        ---要进行本地备份的数据信息
[DEST]        ---把数据备份到本地什么位置

举个栗子:备份 /etc/hosts/tmp 目录下

[root@nfs01 ~]# rsync -avz /etc/hosts /tmp/

远程模式

多个主机通过SSH进行远程数据传输(此场景下等同于 scp 命令,依赖于 SSH 服务)

Access via remote shell:
    Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]
    Push: rsync [OPTION...] SRC... [USER@]HOST:DEST

拉(下载)
Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]
rsync           ---命令
[OPTION...]     ---选项
[USER@]         ---远程主机用户(系统用户)
HOST:           ---远程主机地址  
SRC...          ---远程主机数据
[DEST]          ---将远程主机数据备份至本地什么位置

推(上传)     
Push: rsync [OPTION...] SRC... [USER@]HOST:DEST
rsync           ---命令
[OPTION...]     ---选项
SRC...          ---本地文件或目录
[USER@]         ---远程主机用户(系统用户)
HOST:           ---远程主机地址
[DEST]          ---本地数据备份至远端什么目录

举个栗子:推送本地数据至 backup 服务器(上传)

[root@nfs01 ~]# rsync -avz /etc/hosts root@172.16.1.41:/etc/hosts

举个栗子:拉取 backup 服务器数据至本地(下载)

[root@nfs01 ~]# rsync -avz root@192.172.16.1.41:/etc/hosts /etc/hosts

守护模式

不使用其他通道,不依赖其他服务(不使用系统用户,更加安全)

Access via rsync daemon:
    Pull: rsync [OPTION...] [USER@]HOST::SRC... [DEST]
          rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]
    Push: rsync [OPTION...] SRC... [USER@]HOST::DEST
          rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST

Pull: rsync [OPTION...] [USER@]HOST::SRC... [DEST]
rsync           ---命令
[OPTION...]     ---选项
[USER@]         ---远程主机用户(虚拟用户)
HOST::          ---远程主机地址  
SRC...          ---远程主机模块(不是目录)
[DEST]          ---将远程主机数据备份至本地什么位置


Push: rsync [OPTION...] SRC... [USER@]HOST::DEST
rsync           ---命令
[OPTION...]     ---选项
SRC...          ---远程主机模块(不是目录)
[USER@]         ---远程主机用户(虚拟用户)
HOST::          ---远程主机地址
[DEST]          ---将远程主机模块备份至本地什么位置

举个例子:将本地数据推送至 backup 服务器

[root@nfs01 ~]# rsync -avz /mnt/ rsync_backup@192.172.16.1.41::backup/ --password-file=/etc/rsync.pas

举个例子:将 backup 服务器数据拉至本地服务器

[root@nfs01 ~]# rsync -avz rsync_backup@192.172.16.1.41::backup/ /mnt/ --password-file=/etc/rsync.pas

RSYNC 服务部署

本文环境在未特殊声明时默认为 CentOS 7.5

角色外网IP(NAT)内网IP(LAN)主机名
服务端10.0.0.41172.16.1.41backup
客户端10.0.0.31172.16.1.31nfs01

从仓库安装

[root@backup ~]# yum -y install rsync
[root@backup ~]# rpm -qa rsync
rsync-3.1.2-4.el7.x86_64

配置及启动服务

配置文件位置 /etc/rsyncd.conf

写入配置文件

# /etc/rsyncd: configuration file for rsync daemon mode

# See rsyncd.conf man page for more options.

# configuration example:

# uid = nobody
# gid = nobody
# use chroot = yes
# max connections = 4
# pid file = /var/run/rsyncd.pid
# exclude = lost+found/
# transfer logging = yes
# timeout = 900
# ignore nonreadable = yes
# dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2

# [ftp]
#        path = /home/ftp
#        comment = ftp export area
uid = rsync
gid = rsync
fake super = yes
use chroot = no
max connections = 10
pid file = /var/run/rsyncd.pid
exclude = lost+found/
timeout = 300
ignore errors
read only = false
list = false
hosts allow = 172.16.1.0/24
hosts deny = 0.0.0.0/32
auth users = rsync
secrets file = /etc/rsync.pas
log file = /var/log/rsyncd.log
[backup]
comment = crond backup
path = /backup

附件:配置文件说明

# 全局模块
uid = rsync                       # 运行进程的用户
gid = rsync                       # 运行进程的用户组
fake super = yes                  # 临时提权(若不使用,3.1.2版本会报错)
port = 873                        # 监听端口
use chroot = no                   # 关闭假根功能
max connections = 10              # 最大连接数
pid file = /var/run/rsyncd.pid    # 指定PID文件位置
exclude = lost+found/             # 默认排除文件夹
timeout = 300                     # 超时时间
ignore errors                     # 忽略错误信息
read only = false                 # 对备份数据可读写
list = false                      # 不允许查看模块信息
hosts allow = 172.16.56.0/24      # 允许某个IP或网段访问
hosts deny = 0.0.0.0/32           # 拒绝某个网段或IP访问
auth users = rsync                # 定义虚拟用户,作为连接认证用户
secrets file = /etc/rsync.pas  # 定义虚拟用户连接认证密码文件
log file = /var/log/rsyncd.log    # 定义日志存放文件

# 局部模块
[backup]                          # 定义模块信息
comment = crond backup            # 模块注释信息
path = /backup                    # 定义接收备份数据目录

创建账户,且不允许登录不创建家目录

[root@backup ~]# useradd -M -s /sbin/nologin rsync

创建备份目录并授权

[root@backup ~]# mkdir /backup
[root@backup ~]# chown -R rsync.rsync /backup/

创建虚拟用户密码文件

[root@backup ~]# echo "rsync:123456" >/etc/rsync.pas
[root@backup ~]# chmod 600 /etc/rsync.pas
注意:密码文件权限必须为 600

启动服务并配置开机自启动

[root@backup ~]# systemctl start rsyncd
[root@backup ~]# systemctl enable rsyncd

检查服务状态及端口监听状态

端口状态

[root@backup ~]# ss -lntup | grep "rsync"
tcp    LISTEN     0      5         *:873                   *:*                   users:(("rsync",pid=642,fd=3))
tcp    LISTEN     0      5        :::873                  :::*                   users:(("rsync",pid=642,fd=5))

服务状态

[root@backup ~]# systemctl status rsyncd
● rsyncd.service - fast remote file copy program daemon
   Loaded: loaded (/usr/lib/systemd/system/rsyncd.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2018-07-27 09:46:15 CST; 4h 6min ago
 Main PID: 642 (rsync)
   CGroup: /system.slice/rsyncd.service
           └─642 /usr/bin/rsync --daemon --no-detach

若显示active (running)为绿色且端口监听正常则配置无问题。

客户端配置密码并设置权限

方式一:使用密码文件

[root@nfs01 ~]# yum install rsync -y
[root@nfs01 ~]# echo "123456" > /etc/rsync.pas
[root@nfs01 ~]# chmod 600 /etc/rsync.pas 

方式二:定义密码变量(脚本中推荐使用)

export RSYNC_PASSWORD=123456

实战一: 客户端推送数据至服务端

[root@nfs01 ~]# rsync -avz /backup/ rsync@172.16.1.41::backup/ --password-file=/etc/rsync.pas

实战二: 客户端拉取服务端数据至本地

[root@nfs01 ~]#rsync -avz rsync@172.16.1.41::backup /backup/ --password-file=/etc/rsync.pas

实战三: 实现数据无差异同步
拉取远端数据:远端与本地保持一致,远端没有本地有会被删除,造成客户端数据丢失。

[root@nfs01 ~]# rsync -avz --delete rsync@172.16.1.41::backup/ /data/ --password-file=/etc/rsync.pas

推送数据至远端:本地与远端保持一致,本地没有远端会被删除,造成服务器端数据丢失。

[root@nfs01 ~]# rsync -avz --delete /data/ rsync@172.16.1.41::backup/ --password-file=/etc/rsync.pas

RSYNC 定时备份

使用系统定时任务执行脚本(此处省略定时任务配置,请自行补充)

[root@nfs01 ~]# cat /opt/scripts/backup.sh 
#!/bin/bash

Path=/backup
Host=$(hostname)
Addr=$(ip a s eth1 | awk -F "[ /]+" 'NR==3{print $3}')
Date=$(date +%Y%m%d)
Dest=${Path}/${Host}_${Addr}_${Date}

[ -d $Dest ] || mkdir -p $Dest

cd / && \
# system backup
[ -f $Dest/system.tar.gz ] || tar czf $Dest/system.tar.gz etc/passwd etc/fstab etc/rc.d/rc.local var/spool/cron
# user backup
[ -f $Dest/user.tar.gz ] || tar czf $Dest/user.tar.gz opt/
# config backup
[ -f $Dest/config.tar.gz ] || tar czf $Dest/config.tar.gz etc/rsyncd.conf
# Make MD5 file
[ -f $Path/list-${Host}.md5 ] || md5sum $Dest/*.tar.gz > $Path/list-${Host}.md5

Rsync_User=rsync
Rsync_Addr=172.16.1.41
Rsync_Module=backup
export RSYNC_PASSWORD=123456
rsync -avz $Path/ ${Rsync_User}@${Rsync_Addr}::${Rsync_Module}

find $Path/ -maxdepth 1 -type d -mtime +7 -exec rm -rf {} \;

RSYNC 应用案例

项目要求

每天晚上 1 点整在 Web 服务器上打包备份系统配置文件、日志文件、其他目录,并通过rsync命令推送备份服务器backup上备份保留。

案例环境

已有 3 台服务器,主机信息见下表:

角色外网IP(NAT)内网IP(LAN)主机名
WEB服务器192.168.56.11172.16.56.11web01
NFS存储服务器192.168.56.12172.16.56.12nfs01
Rsync备份服务器192.168.56.13172.16.56.13backup

解决思路

所有服务器在本地按日期打包, 然后再推到备份服务器 backup 上

具体要求

1)所有服务器的备份目录必须都为/backup。
2)备份的系统配置文件包括但不限于。

//配置文件
/etc/rc.local           //开机自启动配置文件
/etc/fstab              //设备挂载配置文件
/etc/hosts              //本地内网配置文件

//重要目录
/var/spool/cron/        //cron定时任务
/etc/firewalld          //firewalld防火墙
/soft/scripts           //脚本目录

系统日志文件
/var/log/   //系统安全日志、sudo日志、内核日志、rsyslog日志

应用程序日志
/soft/log/nginx
/soft/log/mysql
/soft/log/php
/soft/log/tomcat

3)Web服务器本地保留最近7天的数据,避免浪费磁盘空间。
4)Rsync备份服务器上,其它要保留6个月的数据副本。
5)客户端服务器推送数据,以主机名_IP地址_当前时间作为目录,所有的备份数据存放至该目录下 nfs-server_192.168.69.112_2018-03-28/
6)确保备份的数据完整,在备份服务器上对备份的数据进行检查,把备份的成功及失败结果信息发给系统管理员邮箱中。
7)真实工作中除了服务器之间备份,可能还会需要异地备份,这个地方请大家思考如何异地备份。

案例完整解决方案

一、搭建备份服务端

##backup  create-rsync-server.sh

mkdir -p /soft/scripts
vim /soft/scripts/create-rsync-server.sh
#!/bin/sh
useradd rsync  
mkdir –p /backup
chown rsync.rsync /backup

cat >> /etc/rsyncd.conf <<EOF
uid = rsync
gid = rsync
use chroot = no
max connections = 200
timeout = 300
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
ignore errors
read only = false
list = false
hosts allow = 172.16.56.0/24
hosts deny = 0.0.0.0/32
auth users = rsync_backup
secrets file = /etc/rsync.password

[backup]
path = /backup
EOF

cat >> /etc/rsync.password <<EOF
rsync_backup:xuliangwei
EOF

chmod 600 /etc/rsync.password
####rsync server start###
rsync --daemon
echo "rsync --daemon" /etc/rc.local


//客户端
cat >> /etc/rsync.password <<EOF
xuliangwei
EOF
chmod 600 /etc/rsync.password

//在backup上部署rsync, 并且在客户端上可以推送成功。

二、搭建备份客户端

IP=$(ifconfig eth0|awk -F "[ :]+" 'NR==2{print $4}')
if [ $(date +%w) -eq 0 ]
then
   Date="week$(date +%F-%w -d "-1day")
else
Date=$(date +%F -d "-1day")
fi
Path=/backup
/bin/mkdir $Path/$IP -p
cd / &&\
/bin/tar czf $Path/$IP/backup_$Date.tar.gz var/spool/cron/root   etc/rc.local  etc/sysconfig/iptables var/www/html app/logs &&\
md5sum $Path/$IP/backup_$Date.tar.gz > $Path/$IP/flag_$Date &&\
rsync -az /backup/ rsync_backup@10.0.0.100::backup/ --password-file=/etc/rsync.password &&\

#del
find $Path/ -type f -mtime +7 \(-name "*.log" -o -name "*.tar.gz"\)| xargs rm –f

三、配置定时任务

服务端备份脚本

IP=$(ifconfig eth0|awk -F "[ :]+" 'NR==2{print $4}')
if [ $(date +%w) -eq 0 ]
then
   Date="week$(date +%F-%w -d "-1day")
else
Date=$(date +%F -d "-1day")
fi
Path=/backup
/bin/mkdir $Path/$IP -p

LANG=en
find /backup/ -type f -name "*${Date}*.log"|xargs md5sum -c >>$Path/${Date}_result.log 2>&1 &&\
mail -s "$Date bak result" xxx@163.com <$Path/${Date}_result.log
find $Path/ -type f -mtime +180 ! -name "*_week*_6*" | xargs rm -f


//check.sh
find /backup -type f -name "flag_$(date +%F)" |xargs md5sum -c |grep FAILED &> /tmp/mail_body_$(date +%F).txt

mail -s "$(date +%U%T) backup" xxxxxxxx@qq.com </tmp/mail_body_$(date +%F).txt

四、配置邮箱服务(在末尾追加)

[root@backup /]# vim /etc/mail.rc
set from=xxxxxxxx@qq.com
set smtp=smtps://smtp.qq.com:465
set smtp-auth-user=xxxxxxxx@qq.com
set smtp-auth-password=xxxxxxxx
set smtp-auth=login
set ssl-verify=ignore
set nss-config-dir=/etc/pki/nssdb/
注意:QQ 邮箱启动 SMTP 服务请查阅官方文档。

RSYNC 常见问题

当源(SRC)是一个目录时,带斜线(/)与不带斜线的处理是不同的。

不带斜线 -- 目录自身也会同步到目的(DEST)下。 即 rsync -a src_folder dest_folder,结果会有dest_folder/src_folder
带斜线 -- 目录自身不同步。

下面是几个实验:

# mkdir -p src/folder1 dst && touch src/folder1/file1 src/file2 dst/fileX
# find . -exec ls -Fd {} \;
./
./dst/
./dst/fileX
./src/
./src/file2
./src/folder1/
./src/folder1/file1


src不带斜线:(dst下面也有src了)
# rsync -a src dst
# find . -exec ls -Fd {} \;
./
./dst/
./dst/src/
./dst/src/file2
./dst/src/folder1/
./dst/src/folder1/file1
./dst/fileX
./src/
./src/file2
./src/folder1/
./src/folder1/file1


# rm -rf src dst && mkdir -p src/folder1 dst && touch src/folder1/file1 src/file2 dst/fileX
# rsync -a src/folder1 dst
# find . -exec ls -Fd {} \;
./
./dst/
./dst/fileX
./dst/folder1/
./dst/folder1/file1
./src/
./src/file2
./src/folder1/
./src/folder1/file1


src/带斜线:
# rm -rf src dst && mkdir -p src/folder1 dst && touch src/folder1/file1 src/file2 dst/fileX
# rsync -a src/ dst
# find . -exec ls -Fd {} \;
./
./dst/
./dst/fileX
./dst/file2
./dst/folder1/
./dst/folder1/file1
./src/
./src/file2
./src/folder1/
./src/folder1/file1


删除src中没有的文件:
# rm -rf src dst && mkdir -p src/folder1 dst && touch src/folder1/file1 src/file2 dst/fileX
# rsync -a --delete src/ dst
# find . -exec ls -Fd {} \;
./
./dst/
./dst/file2
./dst/folder1/
./dst/folder1/file1
./src/
./src/file2
./src/folder1/
./src/folder1/file1

RSYNC 实时同步

实时同步的实现方案有三种:

先明确几个概念:
问题 1:什么是实时同步

实时同步是指只要当前目录触发事件(例如:修改文件、创建文件、删除文件),就马上同步到远程的目录。

问题 2:为何要实时同步

保证数据同步的即时可靠(防止宕机发生在定时同步前,则最近的改动并没有备份)
减少人力维护成本

方案 1:rsync + inotify (复杂)

inotify是一个通知接口,用来监控文件系统的各种变化,如文件的存取、删除、移动等。可以非常方便地实现监控文件变化,可以用来监测恶意修改、增量备份等。

rsync + inotify 可以实现事件触发式实时同步增量备份

实际案例:

需求:实现 Web 上传视频文件,写入 NFS 共享存储,然后将存储内容实时复制至备份服务器。

测试环境如下:

角色外网IP(NAT)内网IP(LAN)安装工具主机名
同步服务器10.0.0.41172.16.1.41rsyncbackup
存储服务器10.0.0.31172.16.1.31rsync+inotifynfs01
网页服务器10.0.0.7172.16.1.7nginx+phpweb01

同步服务器 执行以下操作

1). 安装 rsync

[root@backup-41 ~]# yum install -y rsync

2). 配置 rsync

[root@backup-41 ~]# vim /etc/rsyncd.conf
uid = rsync
gid = rsync
port = 873
fake super = yes
use chroot = no
max connections = 200
timeout = 600
ignore errors
read only = false
list = false
auth users = rsync_backup
secrets file = /etc/rsync.password
log file = /var/log/rsyncd.log
#####################################
[backup]
path = /backup

[data]
path = /data

准备密码文件以及虚拟用户对应的虚拟密码
[root@backup-41 ~]# cat /etc/rsync.password 
rsync_backup:123456
[root@backup-41 ~]# ll /etc/rsync.password
-rw------- 1 root root 20 Jul 23 11:42 /etc/rsync.password

创建backup data仓库目录
[root@backup-41 ~]# mkdir /backup
[root@backup-41 ~]# chown -R rsync.rsync /backup/

[root@backup-41 ~]# mkdir /data
[root@backup-41 ~]# chown -R rsync.rsync /data/

3). 启动 rsync

[root@backup-41 ~]# systemctl restart rsyncd
[root@backup-41 ~]# netstat -lntp|grep rsync
tcp        0      0 0.0.0.0:873             0.0.0.0:*               LISTEN      1372/rsync

4). nfs客户端验证rsync是否正常使用

[root@nfs01 ~]# rsync -avz /root/dir rsync_backup@172.16.1.41::backup
Password: 
sending incremental file list
dir

[root@nfs01 ~]# rsync -avz /root/dir rsync_backup@172.16.1.41::data
Password: 
sending incremental file list
dir

存储服务器 执行以下操作

1). 安装 NFS

[root@nfs01 ~]# yum install nfs-utils -y

2). 配置 NFS

[root@nfs01 ~]# cat /etc/exports
/data/ 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)

[root@nfs01 ~]# id www
uid=666(www) gid=666(www) groups=666(www)

[root@nfs01 ~]# mkdir /data
[root@nfs01 ~]# mkdir /data/www
[root@nfs01 ~]# chown -R www.www /data
[root@nfs01 ~]# ll -d /data/
drwxr-xr-x 5 www www 98 Jul 26 09:29 /data/
[root@nfs01 /]# ll -d /data/www/
drwxr-xr-x 2 root root 6 Jul 27 10:40 /data/www/

3). 启动 NFS

[root@nfs01 ~]# systemctl restart rpcbind
[root@nfs01 ~]# systemctl restart nfs-server

4). 安装 inotify

[root@nfs01 ~]# yum install rsync inotify-tools -y

5). 配置 inotify

Linux 内核中,默认为 inotify 机制提供了三个参数

[root@nfs01 ~]# ls /proc/sys/fs/inotify/
max_queued_events  max_user_instances  max_user_watches

附表:inotify 参数及作用

参数默认值作用
max\_queued_events16384监控服务实例可以监控的事件个数
max\_user_instances128用户可以开启的服务进程数
max\_user_watches8192可以监控的最大文件数

参数值修改

cat >> /etc/sysctl.conf <<EOF
fs.inotify.max_queued_events=80000000
fs.inotify.max_user_watches=80000000
fs.inotify.max_user_instances=65535
EOF

配置参数生效

[root@nfs01 ~]# sysctl -p

附表:
inotify 工具中常用于实时同步的命令是inotifywait,参数如下:

-m      表示持续监控
-r      递归形式监视目录
-q      简化输出信息
-e      指定要监视的事件(create,move,delete,modify)
--timefmt 自定义时间格式,常用参数'%y/%m/%d %H:%M'
--format 自定义输出格式信息, 常用的格式符如下
    %e: 使用了什么事件
    %T: 时间
    %w:显示被监控文件的文件名;
    %f:如果发生某事件的对象是目录,则显示被监控

6). 利用 inotifywait 实现数据实时监控

[root@nfs01 ~]# inotifywait -mrq  --format '%e %T %w%f' --timefmt '%y/%m/%d %H:%M'  -e close_write,modify,delete,create,move /backup/

7). 使用 inotifywait 配合 rsync 以脚本方式实现实时同步

[root@nfs01 ~]# vim /server/scripts/inotify_rsync.sh
#!/bin/bash
export RSYNC_PASSWORD=123456
SRC=/data/
DST=rsync_backup@172.16.1.41::backup/

inotifywait -mrq -e modify,delete,create,attrib ${SRC} | while read file
do
        rsync -az --delete $SRC $DST
done
[root@nfs01 ~]# chmod +x /server/scripts/inotify_rsync.sh

网页服务器 执行以下操作

1). 安装nginx php nfs

[root@web01 ~]# yum install nginx php php-fpm php-pdo nfs-utils -y

2). 配置 nfs-client 并配置自动挂载

[root@web01 ~]# mkdir /data/www
[root@web01 ~]# mount -t nfs 172.16.1.31:/data/www /data/www/
[root@web01 ~]# tail -n1  /etc/fstab 
172.16.1.31:/data/www   /data/www nfs defaults 0 0

[root@web01 ~]# umount /data/www/
[root@web01 ~]# mount -a
[root@web01 ~]# df -h
Filesystem               Size  Used Avail Use% Mounted on
172.16.1.31:/data/www     50G  1.6G   49G   4% /data/www

3). 配置 nginx

[root@web01 ~]# vim /etc/nginx/nginx.conf
user www;
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        root   /data/www;
         index  index.php index.html index.htm;
    autoindex on;
        location ~ \.php$ {
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /data/www$fastcgi_script_name;
        include        fastcgi_params;
        }
    }
}

#注意:nginx修改运行用户需要调整对应的临时目录权限
[root@web01 ~]# chown -R www:www /var/lib/nginx/

4). 修改 php 运行的属主和属组

[root@web01 ~]# sed  -i 's#user = apache#user = www#g' /etc/php-fpm.d/www.conf 
[root@web01 ~]# sed  -i 's#group = apache#group = www#g' /etc/php-fpm.d/www.conf 
[root@web01 ~]# egrep "^user|^group" /etc/php-fpm.d/www.conf 
user = www
group = www

5). 启动 nginx php

[root@web01 ~]# systemctl start nginx php-fpm
[root@web01 ~]# ss -lntp | grep -E "nginx|php"
LISTEN     0      128    127.0.0.1:9000                     *:*                   users:(("php-fpm",pid=1282,fd=0),("php-fpm",pid=1281,fd=0),("php-fpm",pid=1280,fd=0),("php-fpm",pid=1279,fd=0),("php-fpm",pid=1278,fd=0),("php-fpm",pid=1277,fd=6))
LISTEN     0      128          *:80                       *:*                   users:(("nginx",pid=1296,fd=6),("nginx",pid=1295,fd=6))

6). 上传对应代码至网站目录,然后进行附件提交测试

补充内容:想实现数据同步,因为备份服务器也需要与存储服务器保持一致

1). 安装 nfs

[root@backup-41 ~]# yum install nfs-utils -y

2). 配置 nfs

[root@backup-41 ~]# cat /etc/exports
/data/ 172.16.1.0/24(rw,sync,all_squash,anonuid=666,anongid=666)

3). 启动 nfs

[root@backup-41 ~]# systemctl enable nfs-server
[root@backup-41 ~]# systemctl start  nfs-server

扩展:后台执行命令的另一种方式:

[root@nfs01 ~]# yum install screen -y
[root@nfs01 ~]# screen -S name
关于 screen 命令的小贴士:
挂起:进入会话后,使用 Ctrl + A + D 即可挂起当前会话(会话整体会隐藏到后台,并不会结束或者停止),也可直接关闭当前终端。
查看:使用 screen -ls 即可查看已经挂起的会话。
恢复:使用 screen -r [PID / name] 若只有一个则无需括号内参数即可恢复。
结束:在会话内执行 exit 即可。

方案 2:rsync + sersync (已无维护项目)

sersync 是国人基于 rsync+inotify-tools 开发的工具,不仅保留了优点同时还强化了实时监控,文件过滤,简化配置等功能,帮助用户提高运行效率,节省时间和网络资源。

官方 Github 地址:点击跳转 内有详细使用说明

优点:

1)支持通过配置文件管理
2)真正的守护进程socket(不需要写脚本)。
3)可以对失败文件定时重传(定时任务功能)。
4)第三方的HTTP接口(可更新CDN缓存)。
5)默认多线程rsync同步。

缺点:

1)配置文件使用XML标签,可读性较差。
2)此项目已停止维护,在新系统上不保证可用及稳定,推荐使用其他方案。

测试环境如下:

角色外网IP(NAT)内网IP(LAN)安装工具主机名
存储服务器10.0.0.31172.16.1.31rsync+inotify+sersyncnfs01
同步服务器10.0.0.41172.16.1.41rsyncbackup


存储服务器 执行以下操作

1). 安装 rsync

[root@backup-41 ~]# yum install rsync -y

2). 配置 rsync

[root@backup-41 ~]# cat /etc/rsyncd.conf 
uid = rsync
gid = rsync
fake super = yes
use chroot = no
max connections = 10
pid file = /var/run/rsyncd.pid
exclude = lost+found/
timeout = 300
ignore errors
read only = false
list = false
hosts allow = 172.16.1.0/24
hosts deny = 0.0.0.0/32
auth users = rsync
secrets file = /etc/rsync.pas
log file = /var/log/rsyncd.log
[backup]
comment = crond backup
path = /backup

[data]
path = /data

3). 建立对应密码文件

[root@backup-41 ~]# echo "rsync:123456" > /etc/rsync.pas

4). 创建对应目录并授权

[root@backup-41 ~]# groupadd -g 666 www
[root@backup-41 ~]# useradd -u 666 -g www www
[root@backup-41 ~]# id www
uid=666(www) gid=666(www) groups=666(www)
[root@backup-41 ~]# mkdir -p /{backup,data}
[root@backup-41 ~]# chown -R www.www /{backup,data}

5). 启动 rsync

[root@backup-41 ~]# systemctl enable rsyncd
[root@backup-41 ~]# systemctl start rsyncd

6). 检查服务状态

[root@backup-41 ~]# ss -lntp | grep "rsync"
LISTEN     0      5            *:873                      *:*                   users:(("rsync",pid=652,fd=3))
LISTEN     0      5           :::873                     :::*                   users:(("rsync",pid=652,fd=5))

同步服务器 执行以下操作

1). 下载安装 sersync 及依赖

[root@nfs01 ~]# yum install rsync inotify -y
[root@nfs01 ~]# mkdir /server/tools -p
[root@nfs01 ~]# cd /server/tools/
[root@nfs01 tools]# wget https://raw.githubusercontent.com/wsgzao/sersync/master/sersync2.5.4_64bit_binary_stable_final.tar.gz
[root@nfs01 tools]# tar xf sersync2.5.4_64bit_binary_stable_final.tar.gz
[root@nfs01 tools]# mv GNU-Linux-x86/ /usr/local/sersync

2.配置 sersync

[root@nfs01 tools]# cd /usr/local/sersync/
[root@nfs01 sersync]# cp confxml.xml confxml.bak
[root@nfs01 sersync]# cat confxml.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
    <host hostip="localhost" port="8008"></host>
    <debug start="false"/>
    <fileSystem xfs="true"/>
    <filter start="false">
    <exclude expression="(.*)\.svn"></exclude>
    <exclude expression="(.*)\.gz"></exclude>
    <exclude expression="^info/*"></exclude>
    <exclude expression="^static/*"></exclude>
    </filter>
    <inotify>
    <delete start="true"/>
    <createFolder start="true"/>
    <createFile start="false"/>
    <closeWrite start="true"/>
    <moveFrom start="true"/>
    <moveTo start="true"/>
    <attrib start="false"/>
    <modify start="false"/>
    </inotify>

    <sersync>
    <localpath watch="/data/www">
        <remote ip="172.16.1.41" name="data"/>
        <!--<remote ip="192.168.8.39" name="tongbu"/>-->
        <!--<remote ip="192.168.8.40" name="tongbu"/>-->
    </localpath>
    <rsync>
        <commonParams params="-az"/>
        <auth start="true" users="rsync" passwordfile="/etc/rsync.pas"/>
        <userDefinedPort start="false" port="874"/><!-- port=874 -->
        <timeout start="true" time="100"/><!-- timeout=100 -->
        <ssh start="false"/>
    </rsync>
    <failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
    <crontab start="false" schedule="600"><!--600mins-->
        <crontabfilter start="false">
        <exclude expression="*.php"></exclude>
        <exclude expression="info/*"></exclude>
        </crontabfilter>
    </crontab>
    <plugin start="false" name="command"/>
    </sersync>

    <plugin name="command">
    <param prefix="/bin/sh" suffix="" ignoreError="true"/>    <!--prefix /opt/tongbu/mmm.sh suffix-->
    <filter start="false">
        <include expression="(.*)\.php"/>
        <include expression="(.*)\.sh"/>
    </filter>
    </plugin>

    <plugin name="socket">
    <localpath watch="/opt/tongbu">
        <deshost ip="192.168.138.20" port="8009"/>
    </localpath>
    </plugin>
    <plugin name="refreshCDN">
    <localpath watch="/data0/htdocs/cms.xoyo.com/site/">
        <cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
        <sendurl base="http://pic.xoyo.com/cms"/>
        <regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/>
    </localpath>
    </plugin>
</head>

3). 启动 sersync 服务守护进程

[root@nfs01 sersync]# ./sersync2 -h
set the system param
execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches
execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events
parse the command param
_______________________________________________________
参数-d:启用守护进程模式
参数-r:在监控前,将监控目录与远程主机用rsync命令推送一遍
参数-n: 指定开启守护线程的数量,默认为10个
参数-o:指定配置文件,默认使用confxml.xml文件
[root@nfs01 ~]# /usr/local/sersync/sersync2 -dro /usr/local/sersync/confxml.xml

4). 进行数据实时同步测试

附表:配置文件说明

<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
 <host hostip="localhost" port="8008"></host>
 <debug start="true"/>
 <fileSystem xfs="false"/>
 <filter start="false">
 <exclude expression="(.*)\.php"></exclude>
 <exclude expression="^data/*"></exclude>
 </filter>
 <inotify>
 <delete start="true"/>
 <createFolder start="true"/>
 <createFile start="false"/>
 <closeWrite start="true"/>
 <moveFrom start="true"/>
 <moveTo start="true"/>
 <attrib start="false"/>
 <modify start="false"/>
 </inotify>
 
 <sersync>
 <localpath watch="/home/"> <!-- 这里填写服务器A要同步的文件夹路径-->
 <remote ip="8.8.8.8" name="rsync"/> <!-- 这里填写服务器B的IP地址和模块名-->
 <!--<remote ip="192.168.28.39" name="tongbu"/>-->
 <!--<remote ip="192.168.28.40" name="tongbu"/>-->
 </localpath>
 <rsync>
 <commonParams params="-artuz"/>
 <auth start="true" users="rsync" passwordfile="/app/local/sersync/user.pass"/> <!-- rsync+密码文件 这里填写服务器B的认证信息-->
 <userDefinedPort start="false" port="874"/><!-- port=874 -->
 <timeout start="false" time="100"/><!-- timeout=100 -->
 <ssh start="false"/>
 </rsync>
 <failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once--><!-- 修改失败日志记录(可选)-->
 <crontab start="false" schedule="600"><!--600mins-->
 <crontabfilter start="false">
 <exclude expression="*.php"></exclude>
 <exclude expression="info/*"></exclude>
 </crontabfilter>
 </crontab>
 <plugin start="false" name="command"/>
 </sersync>
 
 <!-- 下面这些有关于插件你可以忽略了 -->
 <plugin name="command">
 <param prefix="/bin/sh" suffix="" ignoreError="true"/> <!--prefix /opt/tongbu/mmm.sh suffix-->
 <filter start="false">
 <include expression="(.*)\.php"/>
 <include expression="(.*)\.sh"/>
 </filter>
 </plugin>
 
 <plugin name="socket">
 <localpath watch="/home/demo">
 <deshost ip="210.36.158.xxx" port="8009"/>
 </localpath>
 </plugin>
 <plugin name="refreshCDN">
 <localpath watch="/data0/htdocs/cdn.markdream.com/site/">
 <cdninfo domainname="cdn.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
 <sendurl base="http://cdn.markdream.com/cms"/>
 <regexurl regex="false" match="cdn.markdream.com/site([/a-zA-Z0-9]*).cdn.markdream.com/images"/>
 </localpath>
 </plugin>
</head>

方案 3:rsync + lsyncd (推荐)

存储服务器 执行以下操作

配置同上,不再复述。

同步服务器 执行以下操作

1). 安装 lsyncd

[root@nfs01 ~]# yum -y install lsyncd

2). 配置 lsyncd

[root@nfs01 ~]# vim /etc/lsyncd.conf
----
-- User configuration file for lsyncd.
--
-- Simple example for default rsync, but executing moves through on the target.
--
-- For more examples, see /usr/share/doc/lsyncd*/examples/
--
settings{
    statusFile = "/tmp/lsyncd.stat",
    statusInterval = 1,
}
sync{
    default.rsync,
    source="/data/www/",
    target="rsync@172.16.1.41::data",
    rsync = {
        binary = "/usr/bin/rsync",
        archive = true,
        compress = true,
        verbose   = true,
        password_file = "/etc/rsync.pas",
        }
}

3). 启动 lsyncd 并配置默认自启动

[root@nfs01 ~]# systemctl enable lsyncd
[root@nfs01 ~]# systemctl start lsyncd

4). 检查 lsyncd 服务状态

[root@nfs01 www]# systemctl status lsyncd -l
● lsyncd.service - Live Syncing (Mirror) Daemon
   Loaded: loaded (/usr/lib/systemd/system/lsyncd.service; enabled; vendor preset: disabled)
   Active: active (running) since Sun 2018-07-29 10:59:50 CST; 3s ago
  ain PID: 1563 (lsyncd)
▽  CGroup: /system.slice/lsyncd.service
           └─1563 /usr/bin/lsyncd -nodaemon /etc/lsyncd.conf

Jul 29 10:59:50 nfs01 systemd[1]: Started Live Syncing (Mirror) Daemon.
Jul 29 10:59:50 nfs01 systemd[1]: Starting Live Syncing (Mirror) Daemon...
Jul 29 10:59:50 nfs01 lsyncd[1563]: sending incremental file list
Jul 29 10:59:50 nfs01 lsyncd[1563]: sent 269 bytes  received 21 bytes  580.00 bytes/sec
Jul 29 10:59:50 nfs01 lsyncd[1563]: total size is 1,692,867  speedup is 5,837.47

显示 active (running) 即服务启动正常,可去修改文件测试

附表:配置文件说明

----
-- User configuration file for lsyncd.
--
-- Simple example for default rsync, but executing moves through on the target.
--
-- For more examples, see /usr/share/doc/lsyncd*/examples/
--
settings{
    statusFile = "/tmp/lsyncd.stat",
    statusInterval = 1,
}
sync{
    # 默认运行模式
    default.rsync,
    # 本地同步目录
    source="/data/www/",
    # 远程虚拟用户@远端IP或主机::模块
    target="rsync@172.16.1.41::data",
    # 守护模式配置
    rsync = {
        binary = "/usr/bin/rsync",
        archive = true,
        compress = true,
        verbose   = true,
        password_file = "/etc/rsync.pas",
        }
}

附录

参考链接

本文撰写于一年前,如出现图片失效或有任何问题,请在下方留言。博主看到后将及时修正,谢谢!
禁用 / 当前已拒绝评论,仅可查看「历史评论」。