运维日志 数据备份同步的几个方案

最近公司有这么一个需求。某ERP并发不高,web数据不大,单台服务器就能满足需求,暂时不需要负载均衡。

但是有对于服务高可用和数据安全需求比较高。所以想搞多一台服务器做灾备,实现高可用和数据备份。

选择服务器

目前业务主要面向华南地区的店,所以服务器得选华南地区的。

主服务在阿里云,从服务器也选阿里云,方便管理,内网同步速度略优。缺点就是阿里云出问题,大家一起挂,另外使用同个账户管理的机器,账户泄露两个机子都遭殃。

选非阿里云的服务器,能更大程度避免单点故障情况发生,缺点是管理略为麻烦,同步可能会稍微慢一点点,占用出口带宽,

怎么备份

目前打算至少存在两份异地备份。一份高频近乎实时同步的备份,一份低频定时备份到运维人员机子本地。

前面高频备份是高可用的基础,否则单点故障,备份服务器不能提供完整的数据。

而低频的本地备份可以在出现恶意的攻击,删库等行为后,依然有数据。

而这次备份的重点也是在线的同步备份。

昨天尝试使用 inotify-tools + rsync 用来发现创建修改文件等动作,然后触发 rsync 进行同步。

业务需求能满足,但是不好的是,每次事件触发都进行一次全局扫描,然后坐差异备份有点耗资源。

假如一次性通过命令创建几千个命令,那可能会触发几千次同步。

我想遇到这个问题的肯定不是我一人,度娘之,果然有针对这个问题的解决方案,那就是 sersync + rsync

根据设想的备份流程做了如下图 (绘图软件 dia 不能输入中文 囧)
备份流程图

  1. ERP服务器上运行 sersync 当inotify发现文件读写相关事件的时候,就向备份服务器发起同步,进行差异备份。

  2. 运维定时主动向备份服务器发起同步请求,同步备份数据回本地。

服务器配置

备份服务器配置

  1. 新建一个账户sync_backup作为同步的专用账户,设置用户shell为/sbin/nologin,直接用root太危险了,这样就算密码泄露了,也不会直接导致系统沦陷。
1
2
3
useradd sync_backup -s /sbin/nologin
passwd sync_backup --stdin #建议用密码生成工具生成一个足够强壮的密码复制黏贴过来。

  1. 配置rsync服务

这玩意,你得指定它备份的项目名字,路径,用哪个账户验证,指定认证用户的密码文件。

并设置将密码文件权限设置为600,保证只有root用户才能获取它内容。

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
[root@yzy ~]# vim /etc/rsyncd.conf
# 2017-03-27 By YYY
uid = root
gid = root
use root = true
use chroot = no # 限制用户只能在备份目录
transfer logging = true
read only = no
max connections = 3600
slp refresh = 300
hosts allow = 1X0.X6.1X8.XXX # 源服务器IP 只允许源服务器连接
host deny = 0.0.0.0/32
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
log file = /var/log/rsyncd.log
##log format = %h %o %f %l %b
#
[web]
path = /www/web # 备份根路径
comment = Mirror to web server
list = false
read only = no # 设置非只读
auth users = sync_backup # 指定认证用户
secrets file = /etc/rsyncd.secrets # 指定密码文件
##exclude from = /etc/rsync/exclude.txt # 排除不做同步的列表 这里注释了 有需要再启用

密码文件

1
2
#vim /etc/rsyncd.secrets
sync_backup:用户密码
1
2
chmod 600 /etc/rsyncd.secrets

  1. 启动rsync的守护进程并设置开机启动

尽量用vim改 别echo 误操作一次就坑爹了,别问我为什么特别注明这个

1
2
3
4
#/usr/bin/rsync --deamon
#vim /etc/rc.local
/usr/bin/rsync --deamon

配置源服务器

为什么是先配置备份服务器的rsync,这样可以到源服务器,先尝试先同步看看备份服务器看看是否能正确同步。

这样利于一步一步排错。

1
2
sudo #rsync -avzP /测试同步的目录/ --password-file=/etc/rsyncd.secrets sync_backup@备份服务IP::web/

/etc/rsyncd.secrets 格式 密码,直接就是密码。

我这里测试没问题,就接着部署了sersync

部署sersync

  1. 下载安装 sersync

由于上Google Code要翻墙,我从GitHub下载了一份。

1
2
wget --no-check-certificate https://raw.githubusercontent.com/orangle/sersync/master/release/sersync2.5.4_64bit_binary_stable_final.tar.gz

Google Code sersync项目地址

sersync项目GitHub镜像

下载项目、解压、移动去 /usr/local/sersync/

1
2
3
4
wget --no-check-certificate https://raw.githubusercontent.com/orangle/sersync/master/release/sersync2.5.4_64bit_binary_stable_final.tar.gz
tar zxvf sersync2.5.4_64bit_binary_stable_final.tar.gz
sudo mv GNU-Linux-x86/ /usr/local/sersync/

  1. 配置sersync

关键的配置我都已经注释了。

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?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="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"/>
<modify start="false"/>
</inotify>

<sersync>
<localpath watch="/www/web/shixin_dev_sync_test"> # 需要同步的目录
<remote ip="123.184.19.202" name="web"/> # 备份服务器信息
<!--<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="sync_backup" passwordfile="/etc/rsyncd.secrets"/> # 备份服务器账户信息 记得 开启 true
<userDefinedPort start="false" port="874"/><!-- port=874 --> 备份的默认端口
<timeout start="false" time="100"/><!-- timeout=100 -->
<ssh start="false"/>
</rsync>
<failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
<crontab start="false" schedule="600"><!--600mins-->
<crontabfilter start="false">
<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>

  1. 启动并设置开机启动
1
2
3
4
sudo /usr/local/sersync/sersync2 -r -d -o /usr/local/sersync/confxml.xml # 启动守护进程
vim /etc/rc.local
/usr/local/sersync/sersync2 -r -d -o /usr/local/sersync/confxml.xml

参考资料

关注公众号 尹安灿