2. 数据同步服务(rsync+inotify)

1 数据同步和备份方式介绍:

1.1 备份方式

1.1.1 按备份频率区分

1. 定期备份: rsync配合计划任务, 定期的从目标主机拉取指定目录其文件到本地. 有时间差, 可能造成数据丢失
2. 实时备份: rsnc配置inotify, 一旦本地被监控的数据发生变化, 马上同步到备份服务器. 实时同步, 保证数据安全性

1.1.2 按备份内容区分

1. 完全备份: 每次备份, 都是备份整个数据集, 比如整个目录, 整个分区, 整个硬盘. 
优点是恢复逻辑简单, 只要用完全备份就可以恢复所有数据, 而且如果备份的是整个硬盘, 那么硬盘可以在其他服务器上使用. 
缺点是备份和恢复过程较长, 完全备份会拷贝整个数据集, 在数据量庞大的情况, 备份和恢复的时间都很长
2. 增量备份: 每次备份都是备份基于上一次备份和当前备份时间点的新增数据.
优点: 每次备份的数据量少, 只要备份基于上一次备份新增的数据即可
缺点: 数据恢复过程慢, 要先恢复上一次完全备份, 然后恢复每一次的增量备份
3: 差异备份: 每次备份都是基于上一次的完全备份, 每次都把从上一次完全备份到当前时间点的数据备份出来
优点: 恢复数据简单, 基于上一次完全备份和最近一次差异备份即可回复
缺点: 如果完全备份频率低, 那么差异备份的数据会累积很多, 导致备份和恢复数据缓慢

1.2 同步方式

定时同步: 基于rsync和定时任务, 定时从目标服务器拉取数据到本地. 因为有时间差, 数据安全性低
即时数据同步, 依赖于Linux内核功能, inotify, 自动监控文件系统文件变化, 比如文件属性, 或者文件发生了一些操作, 文件系统做了某些动作. 
这些操作, Linux内核都可以通过一些方式向外发布. 之后就可以通过一些工具, 来监控这些时间的变化
如果有和文件属性变化相关的事件发生, 就会触发同步行为. 这就是实时同步逻辑. 基本上可以保证数据相对安全, 很少的数据丢失.

2 数据的实时同步

图片.png
在生成环境, 有时会需要两台主机的特定目录实现实时同步, 比如, 将NFS共享目录的数据文件, 自动实时同步到备份服务器的特定目录中

pull vs push

pull: 定是同步
在远程主机创建周期性计划任务, 定期的从数据服务器上利用rsync服务, 来把数据拷贝到远程主机本地. 
rsync可以增量性复制, 根据目标目录信息更新, 与本地目录作比较, 只复制发生了改变的数据.  需要设置ssh基于key验证.
push: 实时同步
服务器上, 通过inotify机制, 内核功能, 监控服务器上文件变化, 当服务器上发生了文件属性变化的操作后, 可以触发脚本执行, 脚本的作用就是把当前服务器上某个指定的资源, 利用rsync拷贝到远程主机.

相同点:

1. 都是用客户端发起操作
2. 利用rsync进行增量复制

不同点:

1. pull, 定期复制, 基于crontab, 容易造成数据丢失, 因为有时间差. 需要设置ssh基于key验证.
2. push, 即使复制, inotify, 相对稳定, 安全.

2.1 实时同步技术介绍

实现实时同步的方法:

inotify+rsync方式实现数据同步
sersync: 在inotify基础上开发, 功能更强大

不同的同步方案本质都是调用内核中的inotify功能

工作原理:

要利用监控服务(inotify), 监控同步数据服务器目录中信息的变化
发现目录中数据产生变化, 就利用rsync服务推送到备份服务器上

inotify:

异步的文件系统事件监控机制, 利用事件驱动机制, 而无须通过诸如cron等的轮询机制来获取时间
Linux内核从2.6.13起支持inotify, 通过inotify可以监控文件系统中添加, 删除, 修改, 移动等各种时间

实现inotify软件:

inotify-tools
sersync
lrsyncd

inotify+rsync使用方式:

inotify对同步数据目录信息进行监控
rsync完成数据同步
利用脚本进行结合

2.2 实现inotify

2.2.1 内核

内核是否支持inotify

Linux支持inotify的内核最小版本为2.6.13
[16:15:29 root@data ~]#grep -i inotify /boot/config-3.10.0-1127.el7.x86_64
CONFIG_INOTIFY_USER=y
[16:16:41 root@data ~]#ls -l /proc/sys/fs/inotify
total 0
-rw-r--r-- 1 root root 0 Feb 12 16:17 max_queued_events
-rw-r--r-- 1 root root 0 Feb 12 16:17 max_user_instances
-rw-r--r-- 1 root root 0 Feb 12 16:17 max_user_watches
[16:17:00 root@data ~]#cat /proc/sys/fs/inotify/max_queued_events 
16384
[16:17:21 root@data ~]#cat /proc/sys/fs/inotify/max_user_instances 
128
[16:17:27 root@data ~]#cat /proc/sys/fs/inotify/max_user_watches  
8192

内核参数说明:

max_queued_events: inotify事件队列最大长度, 如值太小, 会出现Event Queue Overflow错误, 默认值, 16384, 生产环境建议调大, 比如: 327679
max_user_instances: 每个用户创建inotfy实例最大值, 默认值: 128
表示每个用户可以监控不同的对象的数量. 比如, 给5个不同目录, 分别设定了不同的监控策略, 那么每个目录就是一个inotify实例.
max_user_watches: 可以监视的文件的总数量(inotifywait单进程), 默认值: 8192, 建议调大

范例:

[16:17:37 root@data ~]#vim /etc/sysctl.conf

fs.inotify.max_queued_events=66666
fs.inotify.max_user_watches=100000 
[16:22:35 root@data ~]#sysctl -p
fs.inotify.max_queued_events = 66666
fs.inotify.max_user_watches = 100000
[16:22:38 root@data ~]#cat /proc/sys/fs/inotify/*
66666
128
100000

2.2.2 inotify-tools工具

inotify用户空间对应工具, inotify-tools
inotify相关工具包, 可以监控系统内核文件系统信息变化, 输出的屏幕上, 从而配合rsync,达到实时同步效果.

安装inotify-tools: 基于epel源

[16:22:55 root@data ~]#yum -y install inotify-tools

inotify-tools提供了两个工具, 实现了文件的属性跟踪

[16:25:17 root@data ~]#rpm -ql inotify-tools
/usr/bin/inotifywait ***主要使用
/usr/bin/inotifywatch
inotifywait: 在被监控的文件或目录上等待特定文件系统事件(open, close, delete等)发生, 常用于实时同步的目录监控
inotifywatch: 收集被监控的文件系统使用的统计数据, 指文件系统时间发生的次数统计

inotifywait命令

跟踪文件属性变化, 常用于实时同步的目录监控

默认一次性监控, 发生了事件后, inotfifywait命令就退出

格式:

inotifywait [options] file1 [file2] [file3]....

常用选项:

-m 始终保持事件监听
-d 以守护进程方式执行, 和-m相似, 配置-o一起使用
-o <file> 打印事件到文件中, 相当于标准输出, 文件需要使用绝对路径
-r 递归监控目录数据信息变化
-q 静默模式, 输出少量时间信息
--exclude <模式> 指定排除文件或者目录, 使用扩展的正则表达式匹配
--excludei <模式> 和exclude相似, 不区分大小写
-s 发送错误信息到syslog, 相当于错误输出
--timefmt <格式> 指定时间输出格式
--format <格式> 指定的输出格式, 即实际监控的输出内容
-e 指定监听指定的时间, 如果省略, 表示所有事件都进行监听

案例: 排除指定模式的文件, 使用扩展正则

notifywait -mrq /data/www --exclude=".*\.swx|\.swp"

inotifywait的--timefmt时间格式

%Y 年份信息, 包含世纪信息
%y 年份信息, 不包括世纪信息
%m 显示月份, 范围是 01 - 12
%d 每月的第几天, 范围是 01 - 31
%H 小时信息, 使用24小时制, 范围 00 - 23
%M 分钟, 范围 00 - 59
%S 秒, 范例 0 - 60

范例: 指定时间格式

--timefmt "%Y-%m-%d %H:%M:%S"

inotifywait的--format格式定义

%T 输出时间格式中定义的时间格式信息, 通过 --timefmt option 语法格式指定时间信息
%w 事件出现时, 监控文件或目录的名称信息, 相当于dirname
%f 事件出现时, 将显示监控目录下触发时间的文件或目录信息, 否则为空, 相当于basename
%e 显示发生的事件信息, 不同的时间默认用逗分隔
%Xe 显示发生的事件信息, 不同的事件指定用X进行分隔

范例: 定义输出格式

--format "%T %w%f event: %;e"
--format '%T %w %f'

inotifywait -e 选项指定的事件类型

create 文件或目录创建
delete 文件或目录被删除
modify 文件或目录内容被写入
attrib 文件或目录属性改变
close_write 文件或目录关闭, 在写入模式打开之后关闭的
close_nowrite 文件或目录关闭, 在只读模式打开之后关闭的
close 文件或目录关闭, 不管读或是写模式
open 文件或目录被打开
lsdir 浏览目录内容
moved_to 文件或目录被移动到监控的目录中
moved_from 文件或目录从监控的目录中被移动
move 文件或目录不管移动到或是移出监控目录都触发事件
access 文件或目录内容被读取
delete_self 文件或目录被删除, 目录本身被删除
unkount 取消挂载

范例:

-e create,delete,moved_to,close_write,attrib

读操作事件记录为close_nowrite, 对文件没有造成变化, 因此无需监控, 比如cat, ls.

范例: inotifywait的使用

1. 监控一次性事件: 一次性监控, 监控到时间发生后, 就立即退出
inotifywait /data/www
图片.png
2. 持续前台监控: 即使是用tab进行目录或文件补全, 也会被监控
[17:08:41 root@data ~]#inotifywait -mrq /data/www --exclude=".*\.swx|\.swp"
图片.png
3. 持续后台监控, 并记录日志, 指定日志格式, 时间格式, 和记录日志的路径
[17:13:20 root@data ~]#inotifywait -o /root/inotify.log -drq /data/www --timefmt "%Y-%m-%d %H:%M:%S" --format "%T %w$f event: %e"
图片.png
4. 持续前台监控指定事件
[17:21:04 root@data ~]#inotifywait -mrq /data/www --timefmt "%F %H:%M:%S" --format "%T %w%f event: %;e" -e create,delete,moved_to,close_write,attrib
图片.png

实时同步第一种实现方案:

inotify+rsync实现实时同步

脚本中调用inotify监控指定目录, 一定inotify监控到哪个目录发生了变化, 就触发rsync, 把这个目录同步一遍. 

2.3 rsync

rsyns常用于作为Linux系统下的数据镜像备份工具, 实现远程同步, 支持本地复制, 或者与其他ssh, rsync主机同步数据, 支持增量备份
配合计划任务, rsync能实现定时或间隔同步
配合inotify和sersync, 可以实现触发式的实时数据同步
软件包: rsync, rsync-daemon(CentOS8)
服务文件: /usr/lib/systemd/system/rsyncd.service
配置文件: /etc/rsyncd.conf
端口: 873/tcp

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

       Usages with just one SRC arg and no DEST arg will list the source files instead of copying.
       The ':' usuags connect iva remote shell, while '::' & 'rsync://' usages connect to an rsync daemon, and require SRC or DEST to start with a module name.

rsync三种工作方式

  1. 本地同步, 本地文件系统上实时同步. 命令行语法格式为上述"Local"段的格式

  2. 可以基于ssh, 要做key验证. 本地主机使用远程shell和远程主机通信. 命令行语法格式为上述"Access via remote shell"段的格式

  3. 也可以以自己专门的服务来运行, 独立守护服务方式来运行, 通过创建独立的rsync服务器, 监听在独立的端口号, tcp 873上, 可以走自己的rsync协议, 而不用ssh. 在客户端上执行rsync命令, 通过push, 把客户端本地某个目录, 同步到远端rsync服务器上. 本地主机通过网络套接字连接到远程主机上的rsync daemon. 命令行语法格式为上述"Access via rsync daemon"段的格式

前两者的本质是通过本地或者远程shell, 而第三种方式则是让远程主机上运行rsyncd服务, 使其监听在一个端口上, 等待客户端的连接

如果以守护进程方式工作, 需要在rsync服务器上创建rsync服务专用账户.
注意: 该用户是rsync专用虚拟用户

rsync既可以用作客户端命令, 也可以用作服务端命令
rsync 客户端
rsync --daemon 服务端

常见选项:

-v:显示rsync过程中详细信息。可以使用"-vvvv"获取更详细信息。
-P:显示文件传输的进度信息。(实际上"-P"="--partial --progress",其中的"--progress"才是显示进度信息的)。
-n --dry-run  :仅测试传输,而不实际传输。常和"-vvvv"配合使用来查看rsync是如何工作的。
-a --archive  :归档模式,表示递归传输并保持文件属性。等同于"-rtopgDl"。
-r --recursive:递归到目录中去。
-t --times:保持mtime属性。强烈建议任何时候都加上"-t",否则目标文件mtime会设置为系统时间,导致下次更新
          :检查出mtime不同从而导致增量传输无效。
-o --owner:保持owner属性(属主)。
-g --group:保持group属性(属组)。
-p --perms:保持perms属性(权限,不包括特殊权限)。
-D        :是"--device --specials"选项的组合,即也拷贝设备文件和特殊文件。
-l --links:如果文件是软链接文件,则拷贝软链接本身而非软链接所指向的对象
-z        :传输时进行压缩提高效率
-R --relative:使用相对路径。意味着将命令行中指定的全路径而非路径最尾部的文件名发送给服务端,包括它们的属性。用法见下文示例。
--size-only :默认算法是检查文件大小和mtime不同的文件,使用此选项将只检查文件大小。
-u --update :仅在源mtime比目标已存在文件的mtime新时才拷贝。注意,该选项是接收端判断的,不会影响删除行为。
-d --dirs   :以不递归的方式拷贝目录本身。默认递归时,如果源为"dir1/file1",则不会拷贝dir1目录,使用该选项将拷贝dir1但不拷贝file1。
--max-size  :限制rsync传输的最大文件大小。可以使用单位后缀,还可以是一个小数值(例如:"--max-size=1.5m")
--min-size  :限制rsync传输的最小文件大小。这可以用于禁止传输小文件或那些垃圾文件。
--exclude   :指定排除规则来排除不需要传输的文件。
--delete    :以SRC为主,对DEST进行同步。多则删之,少则补之。注意"--delete"是在接收端执行的,所以它是在
            :exclude/include规则生效之后才执行的。
-b --backup :对目标上已存在的文件做一个备份,备份的文件名后默认使用"~"做后缀。
--backup-dir:指定备份文件的保存路径。不指定时默认和待备份文件保存在同一目录下。
-e          :指定所要使用的远程shell程序,默认为ssh。
--port      :连接daemon时使用的端口号,默认为873端口。
--password-file:daemon模式时的密码文件,可以从中读取密码实现非交互式。注意,这不是远程shell认证的密码,而是rsync模块认证的密码。
-W --whole-file:rsync将不再使用增量传输,而是全量传输。在网络带宽高于磁盘带宽时,该选项比增量传输更高效。
--existing  :要求只更新目标端已存在的文件,目标端还不存在的文件不传输。注意,使用相对路径时如果上层目录不存在也不会传输。
--ignore-existing:要求只更新目标端不存在的文件。和"--existing"结合使用有特殊功能,见下文示例。
--remove-source-files:要求删除源端已经成功传输的文件

以守护进程方式, 启动rsync --daemon注意事项

  1. 先手动创建 /etc/rsyncd.conf配置文件, 否则执行 rsync --daemon 启动时会报错
[18:32:01 root@backup~]#touch /etc/rsyncd.conf
  1. 如果本机没有rsync, 需要安装
yum -y install rsync
  1. 启动
[18:32:03 root@backup~]#rsync --daemon
[18:32:14 root@backup~]#ss -ntl
State      Recv-Q Send-Q                                        Local Address:Port                                                       Peer Address:Port              
LISTEN     0      5                                                         *:873                                                                   *:*                  
LISTEN     0      128                                                       *:22                                                                    *:*                  
LISTEN     0      100                                               127.0.0.1:25                                                                    *:*                  
LISTEN     0      5                                                      [::]:873                                                                [::]:*                  
LISTEN     0      128                                                    [::]:22                                                                 [::]:*                  
LISTEN     0      100                                                   [::1]:25                                                                 [::]:*    

通过rsync配置文件, 创建共享文件夹

如果以服务方式, 在备份服务器运行rsync --daemon, 需要指定本地用哪个目录, 接收保存数据

[root@backup ~]#cat /etc/rsyncd.conf
[backup]
path = /data/backup/
read only = no  #默认只读

默认rsync服务用nobody身份访问这个备份目录, 因此要给nobody权限, 否则无法写入

#指定目录给nobody权限,默认用户以nobody访问此目录
[root@backup ~]#setfacl -m u:nobody:rwx /data/backup/

#查看rsync服务器的模块名称
[root@data ~]#rsync  rsync://backup
backup
[root@data ~]#rsync  backup::
backup

#拉操作, 将数据从远程主机拉取到本地. 不一定是备份服务器执行拉操作, 客户端也可从其他主机拉取数据
[root@data~]#rsync 10.0.0.82::backup/* /opt
[root@data~]#rsync rsync://10.0.0.82/backup/* /opt
#推操作, 将数据从客户度退给rsync备份服务器
[root@data~]#rsync  /etc/networks    root@backup::backup
[root@data~]#rsync  /etc/shells    rsync://root@backup/backup

2.4 数据同步案例(手动)

实现从/data/www到/data/back的实时同步, 利用rsync+inotify

image.png

搭建备份服务器

预先创建好备份目录.

mkdir /data/backup
  1. 安装rsync+inotify-tools
yum -y install rsync
yum -y install inotify-tools
rsync --daemon
  1. 创建,并编辑rsyncd配置文件
touch /etc/rsyncd.conf

[20:55:54 root@c8node2 ~]#cat > /etc/rsyncd.conf <<EOF
> [back up]
> path=/data/backup   #备份服务器, 存放备份的目录. 
> read only=no  #默认只能读, 需要修改. 如果设置为no, 那么任何机器都可以通过rsync命令, 向备份服务器传数据, 只要路径指对即可. 无需安全认证. 
> EOF
[20:56:43 root@c8node2 ~]#cat /etc/rsyncd.conf 
[back up]
path=/data/backup
read only=no

  1. 指定备份目录, /data/backup 给nobody权限, 因为rsync默认用nobody访问/data/backup
setfacl -m u:nobody:rwx /data/backup

数据客户端准备

  1. 创建 /data/www目录
  2. 检查rsync是否安装, 没有yum安装一下
  3. 查看备份服务器上, 哪些目录被共享出来
#显示的backup, 就是备份服务器上, /etc/rsyncd.conf里配置的字段名[backup], 也是模块
[18:48:49 root@data-server ~]#rsync rsync://10.0.0.82
backup  

[18:49:48 root@data-server ~]#rsync 10.0.0.82::
backup 
  1. 数据服务器, 利用rsync协议, 把本地 /etc/networks 文件, 同步到备份服务器的备份目录
#这里指定备份目标, 必须是在备份服务器存在, 且写进了/etc/ryncd.conf配置文件的, 否则会报错
#而且, 路径名字要写/etc/ryncd.conf中备份目录对应的模块名, 而不是真实的备份路径名
[18:56:37 root@data-server ~]#rsync /etc/networks rsync://10.0.0.82/data/backup
@ERROR: Unknown module 'data'
rsync error: error starting client-server protocol (code 5) at main.c(1649) [sender=3.1.2]
[18:58:29 root@data-server ~]#rsync /etc/networks rsync://10.0.0.82/backup
  1. 验证传输到备份服务的文件, 是以nobody身份创建的
[18:59:06 root@back-server ~]#cd /data/backup/
[18:59:14 root@back-server /data/backup]#ll
total 4
-rw-r--r-- 1 nobody nobody 58 Feb 12 18:58 networks
  1. 客户端传输时, 可以不指定用户名, 也可以指定任意用名, 无需在客户端或者服务器上存在,因为默认是支持匿名访问的.

至此, 简单的手动同步环境搭建完.

  1. 缺点. 备份服务器通过rsync --daemon启动服务, 无法控制开机,重启,关闭等功能. 只能通过kill进程方式关闭.
  2. 任意主机,无需验证,都可以向备份目录同步数据
  3. rsyncd是以nobody身份, 访问/data/backup目录.

修改:

  1. 如果备份服务器是CentOS 8, 那么可以安装 rsync-daemon包, 此包提供了rsync的service文件, 可以做启动管理. 8以前版本没有提供. 只能使用 rsync --daemon启动, 或者加入到/etc/rc.d/rc.local实现开机自启
    同时rsync-daemon包也提供了/etc/rsyncd.conf
[19:09:59 root@back-server ~]#yum -y install  rsync-daemon

[19:10:06 root@back-server ~]#rpm -ql rsync-daemon
/etc/rsyncd.conf   #rsync-daemon会提供配置文件, 但是因为我们此前自己建好了, 所以不会覆盖
/etc/sysconfig/rsyncd
/usr/lib/systemd/system/rsyncd.service  #提供了rsyncd.service文件
/usr/lib/systemd/system/rsyncd.socket
/usr/lib/systemd/system/rsyncd@.service
/usr/share/man/man5/rsyncd.conf.5.gz

测试service文件

先kill掉此前开启的rsync进程

[19:10:14 root@back-server ~]#killall rsync
[19:19:07 root@back-server ~]#ss -ntl
State                  Recv-Q                 Send-Q                                 Local Address:Port                                 Peer Address:Port                 
LISTEN                 0                      128                                          0.0.0.0:22                                        0.0.0.0:*                    
LISTEN                 0                      128                                             [::]:22                                           [::]:*  

利用service文件启动

[19:19:12 root@back-server ~]#systemctl enable --now rsyncd
Created symlink /etc/systemd/system/multi-user.target.wants/rsyncd.service → /usr/lib/systemd/system/rsyncd.service
  1. 修改配置文件, 指定rsyncd运行用户, 哪些主机和哪些用户能向备份服务器同步数据
[19:19:37 root@back-server ~]#vim /etc/rsyncd.conf

uid=root  #指定以哪个用户来访问共享目录, 将之指定为生成的文件所有者, 默认为nobody
gid=root  #默认为nobody
#port=874  #可指定非标准端口, 默认873/tcp
#use chroot=no  
max connections=0
ignore error
exclude=lost+found/
log file=/var/log/rsyncd.log
pid file=/var/run/rsyncd.pid
lock file=/var/run/rsyncd.lock
reverse lookup=no
#host allow=10.0.0.0/24  #允许哪些主机和我同步

[backup] # 每个模块名对应一个不同的path目录, 如果同名, 后面模块生效
path=/data/backup
read only=no  #默认yes, 只读
comment=backup dir # 给backup添加描述信息, 客户端查看服务器上的共享模块时会显示
auth users=rsyncuser #指定认证用户, 默认anonymous, 所有在数据服务器客户端的系统账户,或者不指定用户名的匿名账号都可以向我同步
secrets file=/etc/rsync.pas  #指定认证账户的认证信息文件路径

  1. 服务器端创建备份目录, 此前已创建完毕
mkdir /data/backup -pv
  1. 服务器端生成验证文件, 修改权限
[19:24:03 root@back-server ~]#echo 'rsyncuser:000000' > /etc/rsync.pas
[19:24:06 root@back-server ~]#chmod 600 /etc/rsync.pas 
  1. 服务器端启动rsync服务
systemctl enable --now rsyncd
  1. 此时, 客户端如果想同步文件, 必须输入正确的用户名密码
[18:58:36 root@data-server ~]#rsync /etc/issue rsync://admin@10.0.0.82/backup
Password: 
@ERROR: auth failed on module backup # 用户名错误
rsync error: error starting client-server protocol (code 5) at main.c(1649) [sender=3.1.2]
[19:25:14 root@data-server ~]#rsync /etc/issue rsync://rsyncuser@10.0.0.82/backup
Password: 
  1. 或者可以在数据服务器, 将密码写入密码文件里, 之后同步命令里指定这个文件目录
[19:27:48 root@data-server ~]#echo '000000' > /etc/rsync.pas
[19:30:15 root@data-server ~]#chmod 600 /etc/rsync.pas 
  1. 客户端测试同步数据
  • 此时客户端/data/www目录内容
  • 此时服务端/data/backup目录内容
图片.png
--delete: 以SRC为主, 对DEST进行同步. 备份服务器上多的文件会被删除, 稍少的会被创建. --delete是在文件接受端执行, 所以是在exclude/include规则生效之后才执行的

[19:33:05 root@data-server ~]#rsync -avz --delete --password-file=/etc/rsync.pas /data/www/ rsyncuser@10.0.0.82::backup
sending incremental file list
deleting networks
deleting issue
./

sent 47 bytes  received 40 bytes  174.00 bytes/sec
total size is 0  speedup is 0.00
  • 执行同步后
图片.png

注意: rsync同步数据时, 一定要注意是要同步整个目录, 还是目录里的内容

如果要同步整个目录, 那么源就不用'/'补全路径
如果要同步目录内的文件, 源一定要补全'/'
  • 同步整个目录
[19:40:47 root@data-server ~]#rsync -avz --delete --password-file=/etc/rsync.pas /data/www rsyncuser@10.0.0.82::backup
/data/www整个目录会被同步到rsync服务器的/data/backup目录下
[19:40:54 root@back-server ~]#ll /data/backup/
total 0
-rw-r--r-- 1 root root  0 Feb 12 19:39 f1.txt
drwxr-xr-x 2 root root 20 Feb 12 19:39 www
  • 同步目录内文件, 不同步目录本身
[19:44:01 root@data-server ~]#rsync -avz --delete --password-file=/etc/rsync.pas /data/www/ rsyncuser@10.0.0.82::backup

只同步目录内数据, 因为/data/www内只要一个f1.txt文件, 因此, 上面同步过去的整个www目录会被删除
[19:44:06 root@back-server ~]#ll /data/backup/
total 0
-rw-r--r-- 1 root root 0 Feb 12 19:39 f1.txt
  • 测试对于文件内容变化的同步
[19:45:13 root@data-server ~]#echo 123 > /data/www/f1.txt
[19:46:36 root@back-server ~]#echo 456 > /data/backup/f1.txt 
[19:46:28 root@data-server ~]#rsync -avz --delete --password-file=/etc/rsync.pas /data/www/ rsyncuser@10.0.0.82::backup
[19:46:40 root@back-server ~]#cat /data/backup/f1.txt 
123 # 内容会以源为基准, 做修改

2.5 实现数据的实时同步

rsync+inotify配合shell脚本

在数据服务器运行脚本, 实现自动实时同步, 数据端需要安装inotify-tools工具

注意, 此脚本执行前, 需要确保两主机初始数据处于同步状态, 此脚本实现后续的数据同步

  • 数据端创建脚本
#!/bin/bash
SRC='/data/www/'
DEST='rsyncuser@10.0.0.82::backup'
rpm -q rsync &> /dev/null || yum -y install rsync
rpm -q inotify-tools &> /dev/null || yum -y install inotify-tools
inotifywait -mrq --exclude=".*\.swp" --timefmt '%Y-%m-%d %H:%M:%S' --format '%T %w %f' -e create,delete,moved_to,close_write,attrib ${SRC} | while read DATE TIME DIR FILE;do
FILEPATH=${DIR}${FILE}
rsync -az --delete --password-file=/etc/rsync.pas ${SRC} ${DEST} && echo "At ${TIME} on ${DATE}, file ${FILEPATH} was backuped via rsync" >> /var/log/changelist.log
done

利用watch命令, 在服务器上,每0.3秒执行一次ls -l /data/backup命令, 并监控结果
watch -n0.3 ls -l /data/backup

利用此脚本, 客户端上对于/data/www目录内的文件,或目录的增删改, 包括文件属性的变化都可以实时同步到rsync服务器. 100M的文件也可以瞬间同步到备份服务器

3 sersync实现数据的实时同步

3.1 sersync介绍

sersync类似于inotify, 同样用于监控, 但它客服了inotify的缺点
inotify最大的不足是会产生重复事件, 或者同一个目录下多个文件的操作会产生多个事件
例如, 当被监控目录有5个文件时, 删除整个目录会产生6个监控事件, 从而导致重复调用rsync命令
比如: vim文件时, inotify会监控到临时文件的事件, 但这写时间相对于rsync来说是不应该被监控的

sersync 优点:

sersync是使用c++编写,而且对linux系统文件系统产生的临时文件和重复的文件操作进行过滤,所以在结合rsync同步的时候,节省了运行时耗和网络资源。因此更快。
sersync配置很简单,其中提供了静态编译好的二进制文件和xml配置文件,直接使用即可
sersync使用多线程进行同步,尤其在同步较大文件时,能够保证多个服务器实时保持同步状态
sersync有出错处理机制,通过失败队列对出错的文件重新同步,如果仍旧失败,则按设定时长对同步失败的文件重新同步
sersync不仅可以实现实时同步,另外还自带crontab功能,只需在xml配置文件中开启,即也可以按要求隔一段时间整体同步一次,而无需再额外配置crontab功能
sersync 可以二次开发

3.2 基于rsync daemon实现sersync

  • 1 在数据服务器上, 下载sersync, 并拷贝到相应的目录, 设置PATH变量
https://code.google.com/archive/p/sersync/downloads
[20:41:07 root@data-server ~]#ls
sersync2.5.4_64bit_binary_stable_final.tar.gz
[20:41:12 root@data-server ~]#tar xf sersync2.5.4_64bit_binary_stable_final.tar.gz
[20:42:09 root@data-server ~]#ls
GNU-Linux-x86 sersync2.5.4_64bit_binary_stable_final.tar.gz
[20:42:11 root@data-server ~]#cp -a GNU-Linux-x86/ /usr/local/sersync
[20:42:37 root@data-server ~]#echo 'PATH=/usr/local/sersync:$PATH' > /etc/profile.d/sersync.sh
[20:43:22 root@data-server ~]#source /etc/profile.d/sersync.sh
sersync目录只有两个文件: 一个是二进制程序文件, 一个是xml格式的配置文件
[20:42:27 root@data-server ~]#ls /usr/local/sersync
confxml.xml  sersync2
sersync需要调用rsync, 因此, 数据段也要安装脏rsync客户端工具
[20:46:42 root@data-server ~]#rpm -q rsync 
rsync-3.1.2-10.el7.x86_64
  • 2 修改sersync配置文件
[20:49:41 root@data-server ~]#vim /usr/local/sersync/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="false"/>
    <filter start="false"> # 不开启文件过滤功能, 当为true时, 以下类型的文件将不同步
    <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"/>
<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
    <host hostip="localhost" port="8008"></host>
    <debug start="false"/>
    <fileSystem xfs="false"/>
    <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="true"/> # 修改此行为true, 否则文件属性的变化不会同步
    <modify start="false"/>
    </inotify>

    <sersync> # rsync命令的配置段
    <localpath watch="/data/www"> # 修改此行, 需要同步的源目录或文件, 建议同步目录
        <remote ip="10.0.0.82" name="backup"/> # 修改此行, 指定备份服务器地址和rsync daemon的模块名, 如果下面开启了ssh start, 此时name为远程shell方式运行时的目标目录
        <!--<remote ip="192.168.8.39" name="tongbu"/>-->
        <!--<remote ip="192.168.8.40" name="tongbu"/>-->
    </localpath>
    <rsync>
        <commonParams params="-artuz"/> # 指定rsync选项
        <auth start="true" users="rsyncuser" passwordfile="/etc/rsync.pas"/> # 修改此行, 为true, 指定备份服务器的rsync配置的用户和密码文件
        <userDefinedPort start="false" port="874"/><!-- port=874 --> # 指定rsync的非标准端口号
        <timeout start="false" time="100"/><!-- timeout=100 -->
        <ssh start="false"/> # 默认使用rsync daemon运行rsync命令, true为使用远程shell模式
    </rsync>
    <failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once--> # 错误重传及日志文件路径
    <crontab start="false" schedule="600"><!--600mins--> # 不开启crontab功能
        <crontabfilter start="false"> # 不开启crontab定时传输的筛选功能
        <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 准备密码文件
[21:11:00 root@data-server ~]#echo 000000 > /etc/rsync.pas
[21:11:08 root@data-server ~]#chmod 600 /etc/rsync.pas
  • 4 准备文件
[21:23:58 root@data-server ~]#mkdir /data/www
[21:24:13 root@data-server ~]#cd /data/www
[21:24:16 root@data-server /data/www]#touch file{1..10}.txt
[21:24:25 root@data-server /data/www]#ls
file10.txt  file1.txt  file2.txt  file3.txt  file4.txt  file5.txt  file6.txt  file7.txt  file8.txt  file9.txt
  • 5 执行同步(-d以后台方式)
[21:24:49 root@data-server ~]#sersync2 -dro /usr/local/sersync/confxml.xml
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
option: -d  run as a daemon
option: -r  rsync all the local files to the remote servers before the sersync work
option: -o  config xml name:  /usr/local/sersync/confxml.xml
daemon thread num: 10
parse xml config file
host ip : localhost host port: 8008
daemon start,sersync run behind the console 
use rsync password-file :
user is rsyncuser
passwordfile is     /etc/rsync.pas
config xml parse success
please set /etc/rsyncd.conf max connections=0 Manually
sersync working thread 12  = 1(primary thread) + 1(fail retry thread) + 10(daemon sub threads) 
Max threads numbers is: 22 = 12(Thread pool nums) + 10(Sub threads)
please according your cpu ,use -n param to adjust the cpu rate
------------------------------------------
rsync the directory recursivly to the remote servers once
working please wait...
execute command: cd /data/www && rsync -artuz -R --delete ./ rsyncuser@10.0.0.82::backup --password-file=/etc/rsync.pas >/dev/null 2>&1 
run the sersync: 
watch path is: /data/www
查看rsync服务器上的数据已经更新
[21:23:50 root@back-server ~]#ll /data/backup/
total 0
-rw-r--r-- 1 root root 0 Feb 12 21:24 file10.txt
-rw-r--r-- 1 root root 0 Feb 12 21:24 file1.txt
-rw-r--r-- 1 root root 0 Feb 12 21:24 file2.txt
-rw-r--r-- 1 root root 0 Feb 12 21:24 file3.txt
-rw-r--r-- 1 root root 0 Feb 12 21:24 file4.txt
-rw-r--r-- 1 root root 0 Feb 12 21:24 file5.txt
-rw-r--r-- 1 root root 0 Feb 12 21:24 file6.txt
-rw-r--r-- 1 root root 0 Feb 12 21:24 file7.txt
-rw-r--r-- 1 root root 0 Feb 12 21:24 file8.txt
-rw-r--r-- 1 root root 0 Feb 12 21:24 file9.txt
  • 5 测试实时同步
rsync服务端开启watch监控
[21:26:21 root@back-server ~]#watch -n0.3 ls -l /data/backup
在客户端的/data/www目录下创建删除文件即可
图片.png

sersync支持多实例, 即监控多个目录, 只需分别配置不同配置文件, 然后使用sersync2指定对应配置文件运行

sersync2 -rdo /etc/sersync.d/nginx.xml
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容