1 背景
在生产环境, 有时会需要两台主机的特定目录实现实时同步. 比如, 将 NFS 共享目录的数据文件, 自动实时同步到备份的服务器特定目录中
2 实时同步技术简介
2.1 实现实时同步的方法
inotify + rsync 方式实现数据同步
sersync : 金山公司周洋在 inotify 软件基础上进行开发的, 功能更加强大
2.2 工作原理
需要利用监控服务(inotify), 监控同步数据服务器目录中信息的变化
发现目录中的数据产生变化, 就利用 rsync 服务推送到备份服务器上
2.3 inotify
异步的文件系统事件监控机制, 利用事件驱动机制, 而无须通过诸如 cron 等的轮询机制来获取事件, Linux 内核从 2.6.13 起支持 inotify, 通过 inotify 可以监控文件系统中添加, 删除, 修改, 移动等各种事件
- [[email protected] ~]#grep -i inotify /boot/config-3.10.0-1062.el7.x86_64
- CONFIG_INOTIFY_USER=y
2.4 实现 inotify 的软件
- inotify-tools
- sersync
- lrsyncd
2.5 inotify+rsync 使用方式
inotify 对同步数据目录信息的监控
rsync 完成对数据的同步
利用脚本进行结合
3 实现 inotify
3.1 前提条件, 内核版本不能小于 2.6.13, 执行下面命令查看内核是否支持 inotify
- # 列出下面的文件, 说明服务器内核支持 inotify
- [[email protected] ~]#ls -l /proc/sys/fs/inotify/
- total 0
- -rw-r--r-- 1 root root 0 Dec 20 19:42 max_queued_events
- -rw-r--r-- 1 root root 0 Dec 20 19:42 max_user_instances
- -rw-r--r-- 1 root root 0 Dec 20 19:42 max_user_watches
- # inotify 内核参数说明:
max_queued_events:inotify 事件队列最大长度, 如值太小会出现 Event Queue Overflow 错误, 默认值: 16384
max_user_instances: 每个用户创建 inotify 实例最大值, 默认值: 128
max_user_watches: 可以监视的文件数量(单进程), 默认值: 8192
- # 上面的参数可以通过修改 / etc/sysctl.conf 文件来调整大小, 如下所示
- [[email protected] ~]#VIM /etc/sysctl.conf
- fs.inotify.max_queued_events=66666
- fs.inotify.max_user_watches=100000
- [[email protected] ~]#sysctl -p
- fs.inotify.max_queued_events = 66666
- fs.inotify.max_user_watches = 100000
- [[email protected] ~]#cat /proc/sys/fs/inotify/*
- 66666
- 128
- 100000
3.2 inotify-tools 工具
- # 参考文档: https://github.com/rvoicilas/inotify-tools/wiki
- # 安装(基于 epel 源)
- [[email protected] ~]#yum -y install inotify-tools
3.2.1 inotify-tools 包主要工具
inotifywait: 在被监控的文件或目录上等待特定文件系统事件 (open ,close,delete 等) 发生, 常用于实时同步的目录监控
inotifywatch: 收集被监控的文件系统使用的统计数据, 指文件系统事件发生的次数统计
3.2.1.1 inotifywait 命令常见选项
-m,--monitor | 始终保持事件监听 |
-d, --daemon | 以守护进程方式执行,和 - m 相似,配合 - o 使用 |
-r, --recursive | 递归监控目录数据信息变化 |
-q, --quiet | 输出少量事件信息 |
--exclude | 指定排除文件或目录,使用扩展的正则表达式匹配的模式实现 |
--excludei | 和 exclude 相似,不区分大小写 |
-o, --outfile | 打印事件到文件中,相当于标准正确输出,注意:使用绝对路径 |
-s, --syslogOutput | 发送错误到 syslog 相当于标准错误输出 |
--timefmt | 指定时间输出格式 |
--format | 指定的输出格式;即实际监控输出内容 |
-e | 指定监听指定的事件,如果省略,表示所有事件都进行监听 |
3.2.1.2 inotifywait 的 --timefmt 时间格式
%Y | 年份信息,包含世纪信息 |
%y | 年份信息,不包括世纪信息 |
%m | 显示月份,范围 01-12 |
%d | 每月的第几天,范围是 01-31 |
%H | 小时信息,使用 24 小时制,范围 00-23 |
%M | 分钟,范围 00-59 |
范例
--timefmt "%Y-%m-%d %H:%M"
3.2.1.3 inotifywait 的 --format 格式定义
%T | 输出时间格式中定义的时间格式信息,通过 --timefmt option 语法格式指定时间信息 |
%w | 事件出现时,监控文件或目录的名称信息 |
%f | 事件出现时,将显示监控目录下触发事件的文件或目录信息,否则为空 |
%e | 显示发生的事件信息,不同的事件默认用逗号分隔 |
%Xe | 显示发生的事件信息,不同的事件指定用 X 进行分隔 |
范例
- --format "%T %w%f event: %;e"
- --format '%T %w %f'
3.2.1.4 inotifywait -e 选项指定的事件类型
create | 文件或目录创建 |
delete | 文件或目录被删除 |
modify | 文件或目录内容被写入 |
attrib | 文件或目录属性改变 |
close_write | 文件或目录关闭,在写入模式打开之后关闭的 |
close_nowrite | 文件或目录关闭,在只读模式打开之后关闭的 |
close | 文件或目录关闭,不管读或是写模式 |
open | 文件或目录被打开 |
moved_to | 文件或目录被移动到监控的目录中 |
moved_from | 文件或目录从监控的目录中被移动 |
move | 文件或目录不管移动到或是移出监控目录都触发事件 |
access | 文件或目录内容被读取 |
delete_self | 文件或目录被删除,目录本身被删除 |
unmount | 取消挂载 |
范例
-e create,delete,moved_to,close_write, attrib
3.2.1.5 inotify 使用范例
- # 监控一次性事件
- inotifywait /data
- # 持续前台监控
- inotifywait -mrq /data
- # 持续后台监控, 并记录日志
- inotifywait -o /root/inotify.log -drq /data --timefmt "%Y-%m-%d %H:%M" --format "%T %w%f event: %e"
- # 持续前台监控特定事件
- inotifywait -mrq /data --timefmt "%F %H:%M" --format "%T %w%f event: %;e" -e
- create,delete,moved_to,close_write,attrib
- 4 rsync
rsync 常用于做为 Linux 系统下的数据镜像备份工具, 实现实现远程同步, 支持本地复制, 或者与其他 SSH,rsync 主机同步数据, 支持增量备份, 配合任务计划, rsync 能实现定时或间隔同步, 配合 inotify 或 sersync, 可以实现触发式的实时数据同步
官方网站: http://rsync.samba.org/
软件包: rsync,rsync-daemon(CentOS 8)
服务文件:/usr/lib/systemd/system/rsyncd.service
配置文件:/etc/rsyncd.conf
端口: 873/tcp
4.1 rsync 命令
4.1.1 命令格式
- #Local:
- rsync [OPTION...] SRC... [DEST]
- #Access via remote shell:
- Pull:
- rsync [OPTION...] [[email protected]]HOST:SRC... [DEST]
- Push:
- rsync [OPTION...] SRC... [[email protected]]HOST:DEST
- #Access via rsync daemon:
- Pull:
- rsync [OPTION...] [[email protected]]HOST::SRC... [DEST]
- rsync [OPTION...] rsync://[[email protected]]HOST[:PORT]/SRC... [DEST]
- Push:
- rsync [OPTION...] SRC... [[email protected]]HOST::DEST
- rsync [OPTION...] SRC... rsync://[[email protected]]HOST[:PORT]/DEST
4.1.2 工作方式
1. 本地文件系统上实现同步. 命令行语法格式为上述 "Local" 段的格式.
2. 本地主机使用远程 shell 和远程主机通信. 命令行语法格式为上述 "Access via remote shell" 段的格式.
3. 本地主机通过网络套接字连接远程主机上的 rsync daemon. 命令行语法格式为上述 "Access via rsync daemon" 段的格式.
前两者的本质是通过本地或远程 shell, 而第 3 种方式则是让远程主机上运行 rsyncd 服务, 使其监听在一个端口上, 等待客户端的连接.
4.1.3 常见选项
-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 | 要求删除源端已经成功传输的文件 |
4.2 以独立的方式运行 rsync
- ###### 服务器端操作 ######
- # 创建 rsync 服务器的配置文件
- vi /etc/rsyncd.conf
- uid = root
- gid = root
- use chroot = no
- max connections = 0
- ignore errors
- exclude = lost+found/
- log file = /var/log/rsyncd.log
- pid file = /var/run/rsyncd.pid
- lock file = /var/run/rsyncd.lock
- reverse lookup = no
- hosts allow = 192.168.7.0/24
- [backup]
- path = /backup/
- comment = backup
- read only = no
- auth users = rsyncuser
- secrets file = /etc/rsync.pass
- # 准备目录
- mkdir /backup
- # 生成验证文件
- echo "rsyncuser:123.com"> /etc/rsync.pass
- chmod 600 /etc/rsync.pass
- # 启动 rsync 服务
- rsync --daemon #可加入 / etc/rc.d/rc.local 实现开机启动
- systemctl start rsyncd #CentOS 7 以上版本
- ###### 客户端操作 ######
- # 配置密码文件
- echo "123.com"> /etc/rsync.pass
- chmod 600 /etc/rsync.pass #此为必要项
- # 测试数据同步
rsync -avz --delete --password-file=/etc/rsync.pass /data/ [email protected]服务器 IP::backup
5 编写 inotify_rsync.sh 脚本实现实时同步
- # 在客户端执行该脚本
- #!/bin/bash
- SRC='/data/'
- DEST='[email protected]服务器 IP::backup'
- inotifywait -mrq --timefmt '%Y-%m-%d %H:%M' --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.pass $SRC $DEST && echo "At ${TIME} on ${DATE}, file $FILEPATH was backuped up via rsync">> /var/log/changelist.log
- done
来源: http://www.bubuko.com/infodetail-3342263.html