简介

鉴于 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 均配置)

1
yum install -y rsync

1.1 创建 rsyncd.conf 配置文件

rsync_server 配置。假如需要同步多个目录,注意加多个目录;此 root 是 rsync 的认证账号,后面步骤会配置认证账号和密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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的uid
uid = root
# 运行rsyns的pid
gid = root
# 权限设置
incoming chmod = Du=rwx,Dog=rx,Fu=rwx,Fgo=rx
port=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/shared
comment = gitlab-rails-shared

[gitlab-rails-uploads]
path = /gitlab-data/gitlab-rails/uploads
comment = itlab-rails-uploads
1
2
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/

1.2 用户认证文件(rsync_server)

1
2
vim /etc/rsyncd.secret
root:root

1.3 配置目录权限

1
2
3
4
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.secret

2 启动 rsync

1
2
systemctl enable rsyncd
systemctl start rsyncd

client 端

1 创建用户认证文件

1
2
vim /etc/rsyncd.passwd
root

2 配置权限

1
chmod 600 /etc/rsyncd.passwd

3 测试

从 sersync_rsync_client 手动 rsync 同步到 rsync_server 看下,只有成功后(查看日志),下面 sersync 才会成功。(sersync_rsync_client 上运行此命令测试)

1
2
3
4
5
6
7
rsync -avzrtopgL --progress /data/gitlab-data/data/gitlab-ci/builds/ root@10.1.142.105::gitlab-ci/ --password-file=/etc/rsyncd.passwd
sending 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/sec
total size is 7 speedup is 0.03

4 sersync 部署

4.1 查看是否支持 inotify

1
2
3
4
5
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_watches

4.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 实例最大值

1
2
3
4
5
6
7
8
9
# 查看
sysctl -a | grep max_queued_events
sysctl -a | grep max_user_watches
sysctl -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 -p

4.2.1 修改最大连接数、最大文件描述符

1
2
3
4
5
6
7
8
9
vim /etc/pam.d/login
session required /lib64/security/pam_limits.so
vim /etc/security/limits.conf
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
vim /etc/pam.d/common-session
session required pam_limits.so

5 安装 sersync

1
2
3
4
5
6
7
8
9
wget --no-check-certificate https://raw.githubusercontent.com/orangle/sersync/master/release/sersync2.5.4_64bit_binary_stable_final.tar.gz
tar xf sersync2.5.4_64bit_binary_stable_final.tar.gz
cp -a GNU-Linux-x86 /usr/local/sersync
echo "PATH=$PATH:/usr/local/sersync" > /etc/profile.d/sersync.sh
source /etc/profile.d/sersync.sh

# sersync目录/usr/local/sersync只有两个文件:一个是二进制程序文件,一个是xml格式的配置文件。
ls /usr/local/sersync/
confxml.xml sersync2

5.1 配置 sersync

1
2
cp /usr/local/sersync/confxml.xml /usr/local/sersync/gitlab-ci.xml
vim /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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 只需要修改这部分内容
......
<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

1
2
3
4
5
6
7
echo "/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/gitlab-ci.xml" >>/etc/rc.local
echo "/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/gitlab-rails-shared.xml" >>/etc/rc.local
echo "/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/gitlab-rails-uploads.xml" >>/etc/rc.local
chmod +x /etc/rc.d/rc.local
systemctl status rc-local.service
# 查看错误日志
vim /usr/local/sersync/gitlab-ci.xml