如何优雅的实现数据同步
简介
鉴于 inotify 存在一定问题,不满足 gitlab 数据同步需求,后续调研了 sersync ,sersync 克服了 inotify 的几个缺点。
-
inotify 最大的不足是会产生重复事件,或者同一个目录下多个文件的操作会产生多个事件(例如,当监控目录中有 5 个文件时,删除目录时会产生 6 个监控事件),从而导致重复调用 rsync 命令。
-
vim 文件时,inotify 会监控到临时文件的事件,但这些事件相对于 rsync 来说是不应该被监控的。
-
inotify 只能记录下被监听的目录发生了变化(增,删,改)并没有把具体是哪个文件或者哪个目录发生了变化记录下来;
-
rsync 在同步的时候,并不知道具体是哪个文件或目录发生了变化,每次都是对整个目录进行同步,当数据量很大时,整个目录同步非常耗时(rsync 要对整个目录遍历查找对比文件),因此效率很低;rsync 在同步时,只同步发生变化的文件或目录(每次发生变化的数据相对整个同步目录数据来说很小,rsync 在遍历查找对比文件时,速度很快),因此效率很高。
server 端
1 rsync 部署
关闭 SELINUX,开启防火墙 tcp 873 端口,或关掉防火墙(sersync_rsync_client、rsync_server 均配置)
yum install -y rsync1.1 创建 rsyncd.conf 配置文件
rsync_server 配置。假如需要同步多个目录,注意加多个目录;此 root 是 rsync 的认证账号,后面步骤会配置认证账号和密码
vim /etc/rsyncd.conf
# 日志存放路径log file = /var/log/rsyncd.log# pid文件存放路径pidfile = /var/run/rsyncd.pid# 支持max connections参数的锁文件lock file = /var/run/rsync.lock# 用户认证配置文件,里面保存用户名密码,手动创建文件secrets file = /etc/rsyncd.secret# rsyns启动欢迎信息页文件配置,自己创建,内容自定义motd file = /etc/rsyncd.motd# 运行rsyns的uiduid = root# 运行rsyns的pidgid = root# 权限设置incoming chmod = Du=rwx,Dog=rx,Fu=rwx,Fgo=rxport=873# 默认为true,增加对目录文件软连接备份use chroot = no# 设置rsync服务端文件为读权限read only = no# 不显示rsync服务端资源列表list = no# 最大连接数max connections = 200# 超时时间timeout = 600# 执行数据同步用户名auth users = root,test# 白名单hosts allow = 10.1.142.105,10.1.142.106# 黑名单hosts deny = *
# 自定义模块名称[gitlab-ci]# 服务端数据目录路径,即同步到目标目录后存放路径path = /gitlab-data/gitlab-ci/builds# 描述comment = gitlab-ci
[gitlab-rails-shared]path = /gitlab-data/gitlab-rails/sharedcomment = gitlab-rails-shared
[gitlab-rails-uploads]path = /gitlab-data/gitlab-rails/uploadscomment = itlab-rails-uploadschown -hR root.root /data/gitlab-data/data/gitlab-rails/shared/ \/data/gitlab-data/data/gitlab-rails/uploads/ \/data/gitlab-data/data/gitlab-ci/builds/1.2 用户认证文件(rsync_server)
vim /etc/rsyncd.secretroot:root1.3 配置目录权限
chown -hR root.root /data/gitlab-data/data/gitlab-rails/shared/ \/data/gitlab-data/data/gitlab-rails/uploads/ \/data/gitlab-data/data/gitlab-ci/builds/chmod 600 /etc/rsyncd.conf /etc/rsyncd.secret2 启动 rsync
systemctl enable rsyncdsystemctl start rsyncdclient 端
1 创建用户认证文件
vim /etc/rsyncd.passwdroot2 配置权限
chmod 600 /etc/rsyncd.passwd3 测试
从 sersync_rsync_client 手动 rsync 同步到 rsync_server 看下,只有成功后(查看日志),下面 sersync 才会成功。(sersync_rsync_client 上运行此命令测试)
rsync -avzrtopgL --progress /data/gitlab-data/data/gitlab-ci/builds/ root@10.1.142.105::gitlab-ci/ --password-file=/etc/rsyncd.passwdsending incremental file list./qwe 7 100% 0.00kB/s 0:00:00 (xfr#1, to-chk=4/6)sent 213 bytes received 50 bytes 526.00 bytes/sectotal size is 7 speedup is 0.034 sersync 部署
4.1 查看是否支持 inotify
ll /proc/sys/fs/inotify# 出现下面的内容、说明服务器内核支持inotify-rw-r--r-- 1 root root 0 Dec 25 12:03 max_queued_events-rw-r--r-- 1 root root 0 Dec 25 15:05 max_user_instances-rw-r--r-- 1 root root 0 Dec 25 12:03 max_user_watches4.2 inotify 优化
参数说明:
max_queued_events: inotify 队列最大长度,如果值太小,会出现” Event Queue Overflow “错误,导致监控文件不准确
max_user_watches: 要同步的文件包含多少目录,可以用:find /var/www/synctest -type d | wc -l 统计,必须保证 max_user_watches 值大于统计结果(这里/var/www/synctest 为同步文件目录)
max_user_instances: 每个用户创建 inotify 实例最大值
# 查看sysctl -a | grep max_queued_eventssysctl -a | grep max_user_watchessysctl -a | grep max_user_instances# 修改sysctl -w fs.inotify.max_queued_events="99999999"sysctl -w fs.inotify.max_user_watches="99999999"sysctl -w fs.inotify.max_user_instances="65535"sysctl -p4.2.1 修改最大连接数、最大文件描述符
vim /etc/pam.d/loginsession required /lib64/security/pam_limits.sovim /etc/security/limits.conf* soft nproc 65535* hard nproc 65535* soft nofile 65535* hard nofile 65535vim /etc/pam.d/common-sessionsession required pam_limits.so5 安装 sersync
wget --no-check-certificate https://raw.githubusercontent.com/orangle/sersync/master/release/sersync2.5.4_64bit_binary_stable_final.tar.gztar xf sersync2.5.4_64bit_binary_stable_final.tar.gzcp -a GNU-Linux-x86 /usr/local/sersyncecho "PATH=$PATH:/usr/local/sersync" > /etc/profile.d/sersync.shsource /etc/profile.d/sersync.sh
# sersync目录/usr/local/sersync只有两个文件:一个是二进制程序文件,一个是xml格式的配置文件。ls /usr/local/sersync/confxml.xml sersync25.1 配置 sersync
cp /usr/local/sersync/confxml.xml /usr/local/sersync/gitlab-ci.xmlvim /usr/local/sersync/gitlab-ci.xml如果需要同步多目录,就再建一个如 gitlab-rails-shared.xml。
需要修改参数说明:
- localpath watch=”/data/gitlab-data/data/gitlab-ci/builds/“ # 如果 A 服务器新建、删除目录都会触发同步到 B 服务器。但是 A 服务器删除文件,不会触发到 B 服务器。
- name=”gitlab-ci”: #目标服务器 rsync 同步目录模块名称
- users=”root”: #目标服务器 rsync 同步用户名
- auth start=“true” #开启认证
- passwordfile=”/etc/rsyncd.passwd”: #目标服务器 rsync 同步用户的密码在源服务器的存放路径
- remote ip=”10.1.142.105”: #对端服务器 ip
- failLog path=”/tmp/rsync_gitlab-ci_log.sh” #脚本运行失败日志记录
- start=”true” #设置为 true,每隔 600 分钟执行一次全盘同步
- delete start #只做增量备份,可以吧这个设置为 flase。但是如果两边要一样就设置为 true
# 只需要修改这部分内容 ...... <localpath watch="/data/gitlab-data/data/gitlab-ci/builds/"> <remote ip="10.1.142.105" name="gitlab-ci"/> <!--<remote ip="192.168.8.39" name="tongbu"/>--> </localpath> <rsync> <commonParams params="-artuz"/> <auth start="true" users="root" passwordfile="/etc/rsync.passwd"/> <userDefinedPort start="false" port="874"/><!-- port=874 --> <timeout start="false" time="100"/><!-- timeout=100 --> <ssh start="false"/> </rsync> <failLog path="/tmp/rsync_gitlab-ci_log.sh" timeToExecute="60"/><!--default every 60mins execute once--> <crontab start="false" schedule="60000"><!--600mins--> <crontabfilter start="false"> <exclude expression="*.php"></exclude> <exclude expression="info/*"></exclude> </crontabfilter> </crontab> <plugin start="false" name="command"/>.....5.2 启动 sersync
echo "/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/gitlab-ci.xml" >>/etc/rc.localecho "/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/gitlab-rails-shared.xml" >>/etc/rc.localecho "/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/gitlab-rails-uploads.xml" >>/etc/rc.localchmod +x /etc/rc.d/rc.localsystemctl status rc-local.service# 查看错误日志vim /usr/local/sersync/gitlab-ci.xml文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!