数据实时同步:inotify + rsync 实现数据实时同步

1 数据实时同步

在生产环境中,某些场景下,要将数据或文件进行实时同步,保证数据更新后其它节点能立即获得最新的数据。

数据同步的两种方式

PULL:拉,使用定时任务的方式配合同步命令或脚本等,从指定服务器上将数据同步到本地,一般是周期性定时同步

PUSH:推,如果当前机器上的数据或文件发生更新了,立即推送到指定的节点上,可以做到实时同步

1.1 实时同步的实现方式

  • inotify + rsync
  • sersync

1.2 inotify + rsync 实现数据实时同步

实现原理

利用内核中的 inotify 监控指定目录,当目录中的文件或数据发生变化时,立即调用 rsync 服务将数据推送到远程主机上。

1.2.1 inotify 服务

inotify 是一个内核用于通知用户空间程序文件系统变化的机制,在监听到文件系统发生变化后,会向相应的应用程序发送事件,如文件增加,修改,删除等事件发生后可以立即让用户空间知道。

复制代码
https://github.com/rvoicilas/inotify-tools #项目地址

inotify 是内核中的功能,在2.6.13版本的内核开始都默认存在。

复制代码
[root@ubuntu ~]# grep -i inotify /boot/config-5.15.0-76-genericCONFIG_INOTIFY_USER=y
[root@rocky ~]# grep -i inotify /boot/config-4.18.0-372.9.1.el8.x86_64CONFIG_INOTIFY_USER=y

inotify 内核参数​​​​​​​

复制代码
[root@ubuntu ~]# ls -l /proc/sys/fs/inotifytotal 0-rw-r--r-- 1 root root 0 Jul 11 09:46 max_queued_events-rw-r--r-- 1 root root 0 Jul 11 09:46 max_user_instances-rw-r--r-- 1 root root 0 Jul 11 09:46 max_user_watches
#inotify 事件队列最大长度,如值太小会出现 Event Queue Overflow 错误,默认 16384,生产环境建议调大,比如 327679[root@ubuntu ~]# cat /proc/sys/fs/inotify/max_queued_events16384
#每个用户创建inotify实例最大值,默认值 128[root@ubuntu ~]# cat /proc/sys/fs/inotify/max_user_instances128
#每个inotify实例可以监视的文件的总数量[root@ubuntu ~]# cat /proc/sys/fs/inotify/max_user_watches14165
#一个用户可以最多开128个inotify实例,每个实例最多可以监控14165个文件

内核参数如果需要修改,可以配置文件​​​​​​​

复制代码
[root@ubuntu ~]# cat /etc/sysctl.conffs.inotify.max_queued_events=66666fs.inotify.max_user_instances=256fs.inotify.max_user_watches=100000
[root@ubuntu ~]# sysctl -pfs.inotify.max_queued_events = 66666fs.inotify.max_user_instances = 256fs.inotify.max_user_watches = 100000

安装软件

inotify 是内核中的功能模块,只能通过调用API接口的形式使用其功能,我们可以通过相关软件来对其进行操作,能实现内核中 inotify 调用的软件主要有以下几个:

inotify-tools,sersync,lrsyncd​​​​​​​

复制代码
#centos系列中该软件来自于 epel 源[root@ubuntu ~]# apt install inotify-tools
#主要工具/usr/bin/fsnotifywait #fsnotify监控工具,fsnotify 是 inotify 的新版本/usr/bin/fsnotifywatch #fsnotify统计工具/usr/bin/inotifywait #实时监控指定目录的所有事件,在被监控的文件或目录上等待特定事件发生(open,close,write...)/usr/bin/inotifywatch #收集被监控的文件系统使用的统计数据,指文件系统事件发生的次数统计

命令格式​​​​​​​

复制代码
inotifywait [ options ] file1 [ file2 ] [ file3 ] [ ... ]
#常用选项-h|--help #显示帮助@<file> #排除指定文件--exclude <pattern> #不监控指定的文件或目录,正则匹配--excludei <pattern> #不监控指定的文件或目录,正则匹配,不区分大小写--include <pattern> #仅监控指定的文件或目录,正则匹配--includei <pattern> #仅监控指定的文件或目录,正则匹配,不区分大小写-m|--monitor #始终保持监听,直到超时-d|--daemon #以守护进程方式执行,配合-o使用-P|--no-dereference #不跟随软链接-r|--recursive #对目录递归监控,即监控目录内所有内容--fromfile <file> #从文件中读取要监控的内容-o|--outfile <file> #将执行结果输出到指定文件-s|--syslog #错误输出到syslog,而不是标准错误输出-q|--quiet #简短输出,仅输出事件信息-qq #禁用输出--format <fmt> #指定输出格式--no-newline #不换行输出,配合--format字段--timefmt <fmt> #指定时间输出格式-c|--csv #以CSV格式输出-t|--timeout <seconds> #指定超时时长,值为0则永远不超时-e|--event <event1> #只监听指定事件,默认监听所有事件
# --format 选项可用字段%T #输出时间格式中定义的时间格式信息,通过 --timefmt option 语法格式指定时间信息%w #事件出现时,监控文件或目录的名称信息,相当于dirname%f #事件出现时,将显示监控目录下触发事件的文件或目录信息,否则为空,相当于basename%e #显示发生的事件信息,不同的事件默认用逗号分隔%Xe #显示发生的事件信息,不同的事件指定用X进行分隔
# --timefmt 选项可用字段%Y #年份信息,包含世纪信息%y #年份信息,不包括世纪信息%m #显示月份,范围 01-12%d #每月的第几天,范围是 01-31%H #小时信息,使用 24小时制,范围 00-23%M #分钟,范围 00-59%S #秒,范例 0-60
# -e 选项可以指定的事件access #文件或目录内容被读取modify #内容发生变化attrib #属性发生变化close_write #写入模式打开后关闭close_nowrite #只读打开后关闭close #关闭事件,无关模式open #打开事件,无关模式moved_to #文件或目录被移动到监控的目录中moved_from #文件或目录从监控的目录中被移动move #文件或目录不管移动到或是移出监控目录都触发事件move_self #被移动之后同名文件不再被监控create #创建文件或目录delete #文件或目录被删除delete_self #被删除之后同名文件不再被监控unmount #取消挂载

只监控一个事件​​​​​​​

复制代码
[root@ubuntu ~]# tree /data//data/├── dir1└── dir22 directories, 0 files
#开始监控[root@ubuntu ~]# inotifywait /data/Setting up watches.Watches established.
#在另一个终端中执行[root@ubuntu ~]# ls /data/dir1 dir2
#提示 open事件并退出[root@ubuntu ~]# inotifywait /data/Setting up watches.Watches established./data/ OPEN,ISDIR

持续监控​​​​​​​

复制代码
[root@ubuntu ~]# inotifywait -m /data/Setting up watches.Watches established.
#另一个终端操作[root@ubuntu ~]# ls /datadir1 dir2[root@ubuntu ~]# ls /data/dir1[root@ubuntu ~]# touch /data/test.txt
#查看监控,一条命令可能有多个事件[root@ubuntu ~]# inotifywait -m /data/Setting up watches.Watches established./data/ OPEN,ISDIR/data/ ACCESS,ISDIR/data/ ACCESS,ISDIR/data/ CLOSE_NOWRITE,CLOSE,ISDIR/data/ OPEN,ISDIR dir1/data/ ACCESS,ISDIR dir1/data/ ACCESS,ISDIR dir1/data/ CLOSE_NOWRITE,CLOSE,ISDIR dir1/data/ CREATE test.txt/data/ OPEN test.txt/data/ ATTRIB test.txt/data/ CLOSE_WRITE,CLOSE test.txt

递归监控​​​​​​​

复制代码
[root@ubuntu ~]# ls /data/dir1/[root@ubuntu ~]# touch /data/dir1/test.txt[root@ubuntu ~]# rm -f /data/dir1/test.txt
#无法监控 touch 和 rm[root@ubuntu ~]# inotifywait -m /data/Setting up watches.Watches established./data/ OPEN,ISDIR dir1/data/ ACCESS,ISDIR dir1/data/ CLOSE_NOWRITE,CLOSE,ISDIR dir1
[root@ubuntu ~]# ls /data/dir1/[root@ubuntu ~]# touch /data/dir1/test.txt[root@ubuntu ~]# rm -f /data/dir1/test.txt
#递归监控[root@ubuntu ~]# inotifywait -m -r /data/Setting up watches. Beware: since -r was given, this may take a while!Watches established./data/ OPEN,ISDIR dir1/data/dir1/ OPEN,ISDIR/data/ ACCESS,ISDIR dir1/data/dir1/ ACCESS,ISDIR/data/ ACCESS,ISDIR dir1/data/dir1/ ACCESS,ISDIR/data/ CLOSE_NOWRITE,CLOSE,ISDIR dir1/data/dir1/ CLOSE_NOWRITE,CLOSE,ISDIR/data/dir1/ CREATE test.txt/data/dir1/ OPEN test.txt/data/dir1/ ATTRIB test.txt/data/dir1/ CLOSE_WRITE,CLOSE test.txt/data/dir1/ DELETE test.txt

将结果输出到文件​​​​​​​

复制代码
[root@ubuntu ~]# inotifywait -m -r /data/ -o inotify.txtSetting up watches. Beware: since -r was given, this may take a while!Watches established.
[root@ubuntu ~]# ls /data/dir1 dir2 test.txt
#查看结果文件[root@ubuntu ~]# cat inotify.txt/data/ OPEN,ISDIR/data/ ACCESS,ISDIR/data/ CLOSE_NOWRITE,CLOSE,ISDIR

从文件中读取要监控的内容​​​​​​​

复制代码
[root@ubuntu ~]# cat a.txt/data/
[root@ubuntu ~]# inotifywait -rm --fromfile a.txtSetting up watches. Beware: since -r was given, this may take a while!Watches established.

后台守护执行,并指定输出格式​​​​​​​

复制代码
[root@ubuntu ~]# inotifywait -drq /data/ -o inotify.log --timefmt "%Y-%m-%d %H:%M:%S" --format "%T %w %f event: %e"
[root@ubuntu ~]# cat inotify.log2025-01-12 14:45:53 /data/ event: OPEN,ISDIR2025-01-12 14:45:53 /data/ event: ACCESS,ISDIR2025-01-12 14:45:53 /data/ event: CLOSE_NOWRITE,CLOSE,ISDIR

指定输出格式,且只记录特定事件​​​​​​​

复制代码
[root@ubuntu ~]# ls /data/dir1 dir2 test.txt
[root@ubuntu ~]# touch /data/test.log[root@ubuntu ~]# touch /data/test.log[root@ubuntu ~]# rm -f /data/test.log
[root@ubuntu ~]# inotifywait -mrq /data/ --timefmt "%F %H:%M:%S" --format "%T%w%f event:%;e" -e create,delete,moved_to,close_write,attrib2025-01-12 14:58:03 /data/test.log event:CREATE2025-01-12 14:58:03 /data/test.log event:ATTRIB2025-01-12 14:58:03 /data/test.log event:CLOSE_WRITE;CLOSE2025-01-12 14:58:06 /data/test.log event:ATTRIB2025-01-12 14:58:06 /data/test.log event:CLOSE_WRITE;CLOSE2025-01-12 14:58:09 /data/test.log event:DELETE

1.2.2 rsync 服务

rsync 常用于作为 linux系统下的数据镜像备份工具,实现远程同步,支持本地复制,或者与其他SSH、rsync主机同步数据,支持增量备份,配合任务计划,rsync能实现定时或间隔同步,配合 inotify 或 sersync,可以实现触发式的实时数据同步。

复制代码
http://rsync.samba.org/ #官方网站

安装软件

复制代码
[root@ubuntu ~]# apt install rsync

命令格式​​​​​​​

复制代码
#Local
rsync [OPTION]... SRC [SRC]... DEST #本地文件同步
#Access via remote shellrsync [OPTION]... [USER@]HOST:SRC [DEST] #PULL 拉,将远程主机上的文件拉到本地rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST #PUSH 推,将本地文件推送到远程主机上
#Access via rsync daemon:rsync [OPTION]... [USER@]HOST::SRC [DEST] #PULL 拉,将远程主机上的文件拉到本地rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST] #PULL 拉,将远程主机上的文件拉到本地rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST #PUSH 推,将本地文件推送到远程主机上rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST #PUSH 推,将本地文件推送到远程主机上

rsync 有三种工作方式

  • 本地文件系统上实现同步。命令行语法格式为上述 "Local" 段的格式
  • 本地主机使用远程shell和远程主机通信。命令行语法格式为上述 "Access via remote shell" 段的格式,使用的用户名和密码是 Linux系统的用户名和密码
  • 本地主机通过网络套接字连接远程主机上的 rsync daemon。命令行语法格式为上述 "Access via rsync daemon" 段的格式,使用的用户名和密码是 rsync 服务中配置的用户名和密码

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

常用选项​​​​​​​

复制代码
--verbose|-v #显示详细过程,最多可以 -vvvv--quiet|-q #不输出错误信息--archive|-a #归档模式,保留文件属性--recursive|-r #递归--backup|-b #如果目标文件存在,先做备份,默认备份后缀是 ~--backup-dir=DIR #指定备份目录--suffix=SUFFIX #指定备份后缀--update|-u #仅在源mtime比目标已存在文件的mtime新时才拷贝,该选项是接收端判断的,不会影响删除行为--links|-l #传输软链接文件,而不是传输其指向的文件--copy-links|-L #跟随软链接,传输其指向的目标文件或目录--perms|-p #保留权限(不包括特殊权限)--owner|-o #保持owner属性--group|-g #保持group属性-D #传输设备文件和特殊文件,同 --devices --specials--times|-t #保留mtime属性--dry-run|-n #测试模式,不实际传输,常合 -vvvv 配合查看细节--whole-file|-W #不使用增量传输,而使用全量传输,在网络带宽高于磁盘带宽时,该选项比增量传输更高效--rsh=COMMAND|-e #指定所要使用的远程shell程序,默认为ssh--existing #只更新远端已存在的文件,远端不存在的文件不传输。使用相对路径时如果上层目录不存在也不会传输--ignore-existing #只传输远程主机不存在的文件--remove-source-files #删除己传输成功的源文件--del #在传输中删除,同 --delete-during--delete #文件传输时,删除DEST中在SRC 中不存在的文件--delete-before #传输开始前先删除--delete-during #在传输过程中删除--delete-delay #在传输中确定要删除的文件,传输结束后删除--delete-after #传输结束后再删除--delete-excluded #删除远程主机上在此项中指定的文件--force #强制删除目录,哪怕不为空--max-delete=NUM #最多删除NUM个文件--max-size=SIZE #限制rsync传输的最大文件大小,可以使用单位后缀,可以写小数值--min-size=SIZE #限制rsync传输的最小文件大小。可用于禁止传输小文件或垃圾文件,可以写小数值--size-only #默认传输有变化的文件,默认检查文件大小变化和 mtime,此项表示只检查文件大小变化--compress|-z #压缩传输--exclude=PATTERN #用正则来指定排除规则来排除不需要传输的文件--exclude-from=FILE #从文件中读取不需要被传送的文件--include=PATTERN #用正则来指定要传输的文件--include-from=FILE #从文件中读取要传输的文件--port=PORT #连接daemon时使用的端口号,默认为873端口--human-readable|-h #以人类友好的格式显示相关信息--progress #显示进度条-P #显示进度条,同 --partial --progress--password-file=FILE #daemon模式时密码文件,读取密码非交互式操作 这不是远程shell认证的密码,而是rsync模块认证的密码--version|-V #显示版本信息--help|-h (*) #显示帮助信息

实现 rsync daemon 服务

主机清单

|------------|--------------|
| IP | 角色 |
| 10.0.0.208 | rsync-server |
| 10.0.0.206 | rsync-client |

复制代码
#服务端以守护进程运行[root@ubuntu ~]# systemctl enable --now rsync.service
#启动失败,因为 /etc/rsyncd.conf 配置文件不存在[root@ubuntu ~]# systemctl status rsync.service
#创建空配置文件[root@ubuntu ~]# touch /etc/rsyncd.conf
#启动服务[root@ubuntu ~]# systemctl start rsync.service
#查看服务状态,运行中[root@ubuntu ~]# systemctl status rsync
#监听 873 端口[root@ubuntu ~]# ss -tunlp | grep rsync
#客户端连接测试[root@ubuntu ~]# rsync rsync://10.0.0.208[root@ubuntu ~]# echo $?0​​​​​​

#修改服务端配置,指定共享目录[root@ubuntu ~]# cat /etc/rsyncd.conf[dir1]path=/data/dir1/read only=no
#重启服务[root@ubuntu ~]# systemctl restart rsync.service
#查看服务端目录[root@ubuntu ~]# tree /data//data/└── dir11 directory, 0 files
#客户端再次测试,可以看到内容[root@ubuntu ~]# rsync rsync://10.0.0.208dir1
#两种写法都可以, :: 表示走rsync协议[root@ubuntu ~]# rsync 10.0.0.208::dir1
#传输文件到远程失败,此处的 root 是指rsync服务的用户,当前服务端并没有配置此信息,默认会被映射成 nobody[root@ubuntu ~]# rsync /etc/fstab [email protected]::dir1rsync: [receiver] mkstemp "/.fstab.tBlxU2" (in dir1) failed: Permission denied (13)rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1338) [sender=3.2.7]
#在服务端配置权限[root@ubuntu ~]# setfacl -m u:nobody:rwx /data/dir1/
#客户端再次测试,上传成功,现在使用的是匿名连接[root@ubuntu ~]# rsync /etc/fstab [email protected]::dir1[root@ubuntu ~]# rsync /etc/issue [email protected]::dir1 #tom 用户在服务端并不存在 
#服务端查看,属主属组都是 nobody[root@ubuntu ~]# ls -l /data/dir1/total 8-rw-r--r-- 1 nobody nogroup 771 Jul 12 00:02 fstab-rw-r--r-- 1 nobody nogroup 24 Jul 12 00:04 issue
#指定映射账号,指定日志文件,指定远程连接用户名和密码,禁用匿名连接[root@ubuntu ~]# cat /etc/rsyncd.confuid=rootgid=rootmax connections=0log file=/var/log/rsyncd.logpid file=/var/run/rsyncd.pidlock file=/var/run/rsyncd.lock[dir1]path=/data/dir1/comment=rsync dir1read only=noauth users=rsyncersecrets file=/etc/rsyncd.pwd
#密码文件[root@ubuntu ~]# cat /etc/rsyncd.pwd123456
#重启服务[root@ubuntu ~]# systemctl restart rsync.service
#客户端再次测试,匿名非匿名都报错[root@ubuntu ~]# rsync 10.0.0.208::dir1Password:@ERROR: auth failed on module dir1rsync error: error starting client-server protocol (code 5) at main.c(1863) [Receiver=3.2.7]
[root@ubuntu ~]# rsync [email protected]::dir1Password:@ERROR: auth failed on module dir1rsync error: error starting client-server protocol (code 5) at main.c(1863) [Receiver=3.2.7]
#查看服务端日志,密码文件不能被所有人可读[root@ubuntu ~]# cat /var/log/rsyncd.log
#修改密码文件权限[root@ubuntu ~]# chmod 600 /etc/rsyncd.pwd[root@ubuntu ~]# ll /etc/rsyncd.pwd-rw------- 1 root root 15 Jul 13 08:58 /etc/rsyncd.pwd
#客户端再次测试[root@ubuntu ~]# rsync /etc/hosts [email protected]::dir1Password:
[root@ubuntu ~]# rsync [email protected]::dir1Password:drwxrwxr-x 4,096 2023/07/13 09:23:12 .-rw-r--r-- 771 2023/07/12 00:02:15 fstab-rw-r--r-- 270 2023/07/13 09:23:12 hosts-rw-r--r-- 24 2023/07/12 00:04:37 issue
#服务端查看,新文件属主属组发生了变化[root@ubuntu ~]# ls -lh /data/dir1/total 12K-rw-r--r-- 1 nobody nogroup 771 Jul 12 00:02 fstab-rw-r--r-- 1 root root 270 Jul 13 09:23 hosts-rw-r--r-- 1 nobody nogroup 24 Jul 12 00:04 issue​​​​​​

#查看客户端文件[root@ubuntu ~]# tree /data/www//data/www/├── dira│   └── os-release├── f1├── f2├── fstab└── issue1 directory, 5 files
#查看服务端文件[root@ubuntu ~]# tree /data/dir1//data/dir1/├── fstab├── hosts└── issue0 directories, 3 files
#将客户端密码保存在单独文件,实现非交互式连接[root@ubuntu ~]# echo "123456" > /etc/rsyncd.pwd[root@ubuntu ~]# chmod 600 /etc/rsyncd.pwd
#客户端测试,保证服务端与客户端同步#--delete 选项,此次同步完成后,删除服务端不在此次同步中的文件#-a 保留属性#-v 显示过程#-z 压缩传输
[root@ubuntu ~]# rsync -avz --delete --password-file=/etc/rsyncd.pwd /data/www/ [email protected]::dir1sending incremental file listdeleting hosts #删除了远程的 hosts 文件./f1f2fstabissuedira/dira/os-releasesent 1,169 bytes received 147 bytes 2,632.00 bytes/sec total size is 1,182 speedup is 0.90
#再次查看服务端,与客户端保持一致了[root@ubuntu ~]# tree /data/dir1//data/dir1/├── dira│?? └── os-release├── f1├── f2├── fstab└── issue1 directory, 5 files

rsync 服务常用配置项​​​​​​​

复制代码
#查看配置示例[root@ubuntu ~]# cat /usr/share/doc/rsync/examples/rsyncd.conf
# GLOBAL OPTIONS #全局配置部份motd file=/etc/motd #motd 文件路径log file=/var/log/rsyncd #日志文件pid file=/var/run/rsyncd.pid #PID 文件syslog facility=daemon #rsyslog 日志服务中的日志归类socket options= #socket 选项,具体见 man setsockopt[ftp] #客户端显示的名称comment = public archive #客户端列出该共享目录时的说明信息path = /var/www/pub #服务端具体目录use chroot = yes #更改映射目录的根目录max connections=10 #最大连接数,同时有多少客户端可以连接lock file = /var/lock/rsyncd #锁文件read only = yes #默认客户端只读访问list = yes #客户端是否可以列出服务端内容uid = nobody #默认将客户端上传的文件属主映射成 nobodygid = nogroup #默认将客户端上传的文件属组映射成 nobodyexclude = #指定排除项,在此处指定的内容在客户端无法显示exclude from = #从指定文件中读取排除项include = #指定显示项,配合 exclude,exclude from 使用include from = #同上auth users = #客户端用户名,启用此项表示禁用匿名连接secrets file = /etc/rsyncd.secrets #客户端用户名和密码对应文件strict modes = yes #严格检查权限,此选项用于 windows 系统上的 rsynchosts 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 #不压缩指定文件
#查看配置帮助[root@ubuntu ~]# man rsyncd.conf

1.2.3 inotify + rsync 实现数据实时同步​​​​​​​

复制代码
#客户端同步脚本[root@ubuntu data]# cat ./www_rsync.sh#!/bin/bashSRC='/data/www/'DEST='[email protected]::dir1'dpkg -V inotify-tools &>/dev/null || apt install inotify-tools -ydpkg -V rsync &>/dev/null || apt install rsync -y
#不间断监控指定目录中的特定事件,当目录中有事件发生变化时,调用 rsync 命令进行同步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=./www_rsync.pwd $SRC $DEST && echo "At ${TIME} on ${DATE}, file ${FILEPATH} was backup via rsync" >> ./www_rsync.logdone
#查看客户端[root@ubuntu ~]# tree /data//data/├── www├── www_rsync.pwd└── www_rsync.sh1 directory, 2 files
#测试,客户端运行脚本[root@ubuntu data]# ./www_rsync.sh
#在另一个终端中创建文件[root@ubuntu ~]# touch /data/www/f1[root@ubuntu ~]# cp /etc/fstab /data/www/[root@ubuntu ~]# dd if=/dev/zero of=/data/www/test.img bs=1M count=1010+0 records in10+0 records out10485760 bytes (10 MB, 10 MiB) copied, 0.00923138 s, 1.1 GB/s
[root@ubuntu ~]# mkdir -pv /data/www/dira/dirb/dircmkdir: created directory '/data/www/dira'mkdir: created directory '/data/www/dira/dirb'mkdir: created directory '/data/www/dira/dirb/dirc'
#在服务湍查看[root@ubuntu ~]# tree /data/dir1//data/dir1/├── dira│   └── dirb│       └── dirc├── f1├── fstab└── test.img3 directories, 3 files
#查看客户端日志,由于某些行为会触发多个事件,导致多次调用脚本,效率不高[root@ubuntu ~]# cat /data/www_rsync.logAt 03:14:53 on 2025-01-13, file /data/www/f1 was backup via rsyncAt 03:14:53 on 2025-01-13, file /data/www/f1 was backup via rsyncAt 03:14:53 on 2025-01-13, file /data/www/f1 was backup via rsyncAt 03:15:05 on 2025-01-13, file /data/www/fstab was backup via rsyncAt 03:15:05 on 2025-01-13, file /data/www/fstab was backup via rsyncAt 03:15:45 on 2025-01-13, file /data/www/test.img was backup via rsyncAt 03:15:45 on 2025-01-13, file /data/www/test.img was backup via rsyncAt 03:16:05 on 2025-01-13, file /data/www/dira was backup via rsync

1.3 sersync 实现数据实时同步

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

sersync 特点

  • sersync是使用c++编写,而且对linux系统文件系统产生的临时文件和重复的文件操作进行过滤,所以在结合rsync同步的时候,节省了运行时耗和网络资源。因此更快。
  • sersync 配置很简单,其中提供了静态编译好的二进制文件和 xml 配置文件,直接使用即可
  • sersync 使用多线程进行同步,尤其在同步较大文件时,能够保证多个服务器实时保持同步状态
  • sersync 有出错处理机制,通过失败队列对出错的文件重新同步,如果仍旧失败,则按设定时长对同步失败的文件重新同步
  • sersync 不仅可以实现实时同步,另外还自带 crontab 功能,只需在 xml 配置文件中开启,即也可以 按要求隔一段时间整体同步一次,而无需再额外配置 crontab 功能
复制代码
#下载[root@ubuntu ~]# wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/sersync/sersync2.5.4_64bit_binary_stable_final.tar.gz
#解压[root@ubuntu ~]# tar xf sersync2.5.4_64bit_binary_stable_final.tar.gz[root@ubuntu ~]# lsGNU-Linux-x86 sersync2.5.4_64bit_binary_stable_final.tar.gz snap[root@ubuntu ~]# ls GNU-Linux-x86/confxml.xml sersync2
#移动[root@ubuntu ~]# mv GNU-Linux-x86/ /usr/local/sersync[root@ubuntu ~]# ls /usr/local/sersync/confxml.xml sersync2

配置文件说明​​​​​​​

复制代码
<?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"/><closeWrite start="true"/><moveFrom start="true"/><moveTo start="true"/><attrib start="false"/> #此处改为true,则文件属性发生变化,也会同步<modify start="false"/></inotify><sersync> #rsync命令的配置段<localpath watch="/opt/tongbu"> #需要同步的目录<remote ip="127.0.0.1" name="tongbu1"/> #远程主机地址和目录<!--<remote ip="192.168.8.39" name="tongbu"/>--><!--<remote ip="192.168.8.40" name="tongbu"/>--></localpath><rsync><commonParams params="-artuz"/> #指定rsync选项<auth start="false" users="root" passwordfile="/etc/rsync.pas"/>#修改为true,指定rsync用户名和密码文件<userDefinedPort start="false" port="874"/> #指定非标准端口<!-- port=874 --><timeout start="false" time="100"/><!-- timeout=100 --><ssh start="false"/> #默认远程rsync daemon运行,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>

sersync2 命令用法和参数​​​​​​​

复制代码
[root@ubuntu sersync]# ./sersync2 -hset the system paramexecute:echo 50000000 > /proc/sys/fs/inotify/max_user_watchesexecute:echo 327679 > /proc/sys/fs/inotify/max_queued_eventsparse the command param_______________________________________________________参数-d:启用守护进程模式参数-r:在监控前,将监控目录与远程主机用rsync命令推送一遍参数-n:指定开启守护线程的数量,默认为10个参数-o:指定配置文件,默认使用confxml.xml文件参数-m:单独启用其他模块,使用 -m refreshCDN 开启刷新CDN模块参数-m:单独启用其他模块,使用 -m socket 开启socket模块参数-m:单独启用其他模块,使用 -m http 开启http模块不加-m参数,则默认执行同步程序_________________________________________________

客户端测试​​​​​​​

复制代码
#服务端文件[root@ubuntu ~]# tree /data/dir1//data/dir1/└── f20 directories, 1 file
#客户端文件[root@ubuntu ~]# tree /data/www/data/www└── f10 directories, 1 file
[root@ubuntu ~]# cd /usr/local/sersync/[root@ubuntu sersync]# ./sersync2 -dro ./confxml.xml
#查看服务端,己经和客户端保持一致了[root@ubuntu ~]# tree /data/dir1//data/dir1/└── f10 directories, 1 file
#客户端测试[root@ubuntu ~]# mkdir -pv /data/www/dira/dirb/dircmkdir: created directory '/data/www/dira'mkdir: created directory '/data/www/dira/dirb'mkdir: created directory '/data/www/dira/dirb/dirc'
[root@ubuntu ~]# cp /etc/fstab /data/www/[root@ubuntu ~]# dd if=/dev/zero of=/data/www/test.img bs=1M count=1010+0 records in10+0 records out10485760 bytes (10 MB, 10 MiB) copied, 0.00870068 s, 1.2 GB/s
#服务端查看[root@ubuntu ~]# tree /data/dir1//data/dir1/├── dira│   └── dirb│       └── dirc├── f1├── fstab└── test.img3 directories, 3 files
#客户端查看后台进程[root@ubuntu ~]# ps aux | grep rsyncroot 5249 0.0 0.0 116928 1624 ? Ssl 07:02 0:00 ./sersync2 -dro ./confxml.xmlroot 5307 0.0 0.1 6476 2324 pts/0 S+ 07:04 0:00 grep --color=auto rsync
相关推荐
不剪发的Tony老师16 小时前
DBSyncer:一款开源的数据同步工具
数据同步
RestCloud3 天前
如何通过ETLCloud实现跨系统数据同步?
数据库·数据仓库·mysql·etl·数据处理·数据同步·集成平台
遇见火星6 天前
【运维实战】Rsync将一台主Web服务器上的文件和目录同步到另一台备份服务器!
运维·服务器·github·rsync
czhc114007566310 天前
LINUX530 rsync定时同步 环境配置
rsync
庄小焱1 个月前
数据治理域——数据同步设计
大数据·数据治理·数据同步·系统架构设计·大数据治理
csdn5659738502 个月前
企业数据孤岛如何破
数据分析·flink cdc·数据同步
依旧风轻2 个月前
深入理解 rsync daemon 模式(守护进程)
linux·ios·rsync·daemon·sqi
啾啾Fun3 个月前
[分布式系统]2_分布式数据共享方式_P1
分布式·数据同步
红豆和绿豆4 个月前
数据同步的中间件
数据同步