主机的主从备份

2021-08-15  本文已影响0人  明翼

对于数据库来说,可以通过主从同步的方式同步数据,那么如果需要普通文件的备份,那么如何进行主从同步那,一般通过rsync和inotify组合文件同步。

一 rsync和inotify 简介

rsynv 远程同步工具,可以对远程服务器进行全量和增量备份同步,同步的数据的时候,rsync采用核心算法对远程服务器的目标文件进行对比,只进行差异同步,如果服务器的文件数量很多,比对耗时很长,发生变化的往往是很少部分,所以一般结合inotify 进行文件同步。

rsynv 可以同步本地的文件夹,也可以进行本地文件夹和远程服务器的同步,类似scp命令;同步本机的不同目录的时候可以进行增量拷贝,所以优于普通的cp命令;rsynv同样可以实现rm功能,来删除目录和文件。

工作场景:
1.两台服务器之间数据同步
2.把所有客户服务器数据同步到备份服务。
3 rsync结合inotify功能做实时数据同步.

安装如下:

yum install rsync
yum install inotify-tools

二 rsync用法简介

rsync 三种用法如下:

Local:  rsync [OPTION...] SRC... [DEST]
 
Access via remote shell:
  Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]
  Push: rsync [OPTION...] SRC... [USER@]HOST:DEST
 
Access via rsync daemon:
  Pull: rsync [OPTION...] [USER@]HOST::SRC... [DEST]
        rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]
  Push: rsync [OPTION...] SRC... [USER@]HOST::DEST
        rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST

2.1. 本地模式

类似于cp命令,简单的测试下如下:

#建立如下的目录结构:
[root@VM-0-2-centos data]# tree ./
./
|-- dst
`-- src
    `-- abc.txt

执行同步命令:
#因为要同步目录所以加-r不然会忽略的.
rsync -r ./src ./dst

结果:
tree ./
./
|-- dst
|   `-- src
|       `-- abc.txt
`-- src
    `-- abc.txt
第一次执行和我预期不一样,将src目录直接同步到dst下面了,我是想把src的文件同步到dst下面,可以执行如下命令:

[root@VM-0-2-centos data]# rsync -r ./src/ ./dst
[root@VM-0-2-centos data]# tree ./
./
|-- dst
|   |-- abc.txt
|   `-- src
|       `-- abc.txt
`-- src
    `-- abc.txt
这次就ok了.

简单来说,注意同步的目录还是目录下面的内容,如果下面的内容需要再目录后面加/,如果需要同步整个目录则不需要加/

2.2 远程模式类似scp

简单的测试下:

rsync -iavz ./dst root@xx.xx.xx.xx:/data
The authenticity of host 'xx.xx.xx.xx (xx.xx.xx.xx)' can't be established.
ECDSA key fingerprint is SHA256:9PnqwKNipP7Rtab2Mmy3qXzyaVsnb9G43UtFi+HDLRk.
ECDSA key fingerprint is MD5:0f:10:0e:31:7e:ae:e1:60:98:99:5a:63:bd:7c:70:0f.
Are you sure you want to continue connecting (yes/no)? tes
Please type 'yes' or 'no': yes
Warning: Permanently added 'xx.xx.xx.xx' (ECDSA) to the list of known hosts.
root@阿里主机IP's password: 
sending incremental file list
cd+++++++++ dst/
<f+++++++++ dst/abc.txt
cd+++++++++ dst/src/
<f+++++++++ dst/src/abc.txt

sent 211 bytes  received 66 bytes  8.03 bytes/sec
total size is 0  speedup is 0.00

在远程主机上看下同步结果,选项支持的太多了,先不讲吧.

[root@iZwz90jb8mqajkli0ttrcbZ data]# tree
.
└── dst
    ├── abc.txt
    └── src
        └── abc.txt


2.3 rsync daemon 模式

此种模式是客户端和服务器端都采用的rsync应用程序进行同步的方式.此种方式不像远程的方式通过ssh协议实现,这种方式通过"rsync://协议"(端口号为873),进行数据的传输,服务器按照主机名和文件夹名采用:: 方式进行同步.

如果采用ssh结合rsync进行同步,也不是不行,只是同步文件比较多的话,一条条命令去写很麻烦,
而且还存在着排除文件的问题.rsync daemon 方式启动后,完全可以替换ftp服务器,提供url,外部系统可以通过命令查看文件和下载文件.

rsync 启动时候,需要读取配置文件,默认为:/etc/rsyncd.conf, 端口为873.
默认配置如下:


# uid = nobody
# gid = nobody
# use chroot = yes
# max connections = 4
# pid file = /var/run/rsyncd.pid
# exclude = lost+found/
# transfer logging = yes
# timeout = 900
# ignore nonreadable = yes
# dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2

# [ftp]
#        path = /home/ftp
#        comment = ftp export area

有点类似ini文件格式,除了全局变量,还定义了[ftp],在rsync中称为模块,
想要请求模块,客户端使用"rsync user@host::ftp,表示访问user@host
上的/home/ftp目录.

三 rsync常用选项

rsync选项实在太多,看到眼花缭乱的,用的最多的几个选项说明下:

-a  除了同步文件外,还同步权限属性信息.
-r  递归同步目录
-z 传输过程中进行压缩
-v 显示详细操作过程
 --delete 是同步的时候保持两个文件夹完全相同,删除目标文件夹中,在源端文件夹没有的文件,保持两个文件夹完全同步.
--exclude 排除文件夹下的特定文件不进行同步,比如--exclude="a/*.txt" 不同步啊目录下的txt类型文件.
-i 输出要传输文件的路径
-n 不实际进行同步,仅仅进行测试.

五 inotifywait 说明

inotify 是细粒度,异步的文件按照系统时间监控机制,Linux内核从2.6.13起加入inotify支持,通过inotify 可以监控文件系统添加,修改,删除,移动等各种事件,利用这个内核接口,将监控到的变化文件同步出来。

在同步的时候,如果仅仅利用rsync会进行大量文件的比较,同步操作不够实时,我们通过inotify将需要同步的文件监听到,再进行同步,将同步算法中的比较时间减少了,提升同步的速度.

#监听 /data/目录中的modify,create,delete,attrib  四种事件
inotifywait -mrq --format '%Xe %w%f' -e modify,create,delete,attrib /data/

CREATE /data/1
ATTRIB /data/1
CREATE /data/5
ATTRIB /data/5
DELETE /data/1
DELETE /data/5

# 操作文件
[root@VM-0-2-centos ~]# touch /data/{1,5}
[root@VM-0-2-centos data]#cd /data rm -rf 1 5

inotifywait 参数说明:

-m,–monitor 始终保持事件监听状态
-r,–recursive   递归查询目录
-q,–quiet   只打印监控事件的信息
–excludei   排除文件或目录时,不区分大小写
-t,–timeout 超时时间
–timefmt    指定时间输出格式
–format 指定时间输出格式
-e,–event   后面指定删、增、改等事件

inotifywait events事件说明:

事件名称    事件说明
access  读取文件或目录内容
modify  修改文件或目录内容
attrib  文件或目录的属性改变
close_write 修改真实文件内容
open    文件或目录被打开
moved_to    文件或目录移动到
moved_from  文件或目录从移动
move    移动文件或目录移动到监视目录
create  在监视目录下创建文件或目录
delete  删除监视目录下的文件或目录
delete_self 
unmount 卸载文件系统

如果文件太多,还需要对inotify进一步优化:

ll /proc/sys/fs/inotify/
total 0
-rw-r--r-- 1 root root 0 Aug 15 16:53 max_queued_events
-rw-r--r-- 1 root root 0 Aug 15 16:53 max_user_instances
-rw-r--r-- 1 root root 0 Aug 15 16:53 max_user_watches

max_user_watches # 设置inotifywait或inotifywatch命令可以监视的文件数量(单进程)
max_user_instances #设置每个用户可以运行的inotifywait或inotifywatch命令的进程数
max_queued_events #设置inotify实例事件(event)队列可容纳的事件数量

优化参数:

 vim /etc/sysctl.conf

fs.inotify.max_queued_events = 32768
fs.inotify.max_user_instances = 1024
fs.inotify.max_user_watches = 90000000
:q
# 执行生效
 sysctl -p

六 实际同步操作

实际工作中,如何利用rsync进行数据同步那,一般分为两种:

  1. 利用rsync daemon 模式进行数据的同步:(也可以结合inotify)
    优点 : 1) 支持多个目录复杂的同步(比如排除特定文件)
    缺点: 1) 配置比较繁琐 2) 大量文件需要同步的话无法保证实时

  2. 利用rsync 和inotify
    优点: 1)大量文件下可以进行快速实时同步;
    缺点: 1) 多个文件夹同步写的脚本也挺麻烦

假如我们有如下图的同步要求,要求尽可能实时同步,机器重启后仍然可以同步 :


同步要求

6.1 采用rsync和inotify方式进行文件夹数据同步

本次例子采用方式用rsync进行每2个小时进行一次全量同步,平时通过一个shell脚本进行实时同步.

  1. 首先如图在B主机上建好目录结构和要同步的测试文件信息等:
[root@iZwz90jb8mqajkli0ttrcbZ /]# tree ./testsync/
./testsync/
├── a.txt
├── b.txt
└── c
    └── d.txt

在A主机上建好同步目录:
testsync_bak

  1. 在A主机上拉取命令
    一般情况下pull比push要好一些,
[root@VM-0-2-centos /]# rsync -avzP root@B阿里云IP:/testsync/   /testsync_bak
root@B阿里云IP's password: 
receiving incremental file list
./
a.txt
              0 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=3/5)
b.txt
              0 100%    0.00kB/s    0:00:00 (xfr#2, to-chk=2/5)
c/
c/d.txt
              0 100%    0.00kB/s    0:00:00 (xfr#3, to-chk=0/5)

sent 92 bytes  received 256 bytes  27.84 bytes/sec
total size is 0  speedup is 0.00

看下同步效果:

[root@VM-0-2-centos /]# tree testsync_bak/
testsync_bak/
|-- a.txt
|-- b.txt
`-- c
    `-- d.txt

如果要删除testsync_bak 中可能多余的文件,添加--delete即可.

  1. 做成crontab
    由于每次变化都要重新同步文件,比较麻烦,所以需要做成crontab定时去同步文件,定时同步文件,就不能输入密码, 可以通过一个文件来指定密码.

这种通过ssh同步方式,只能做成ssh免密码登录才可以,步骤如下:

  1. 生成公钥
ssh-keygen -t rsa 

一路回车即可.

  1. 将公钥拷贝到服务器上
ssh-copy-id -i ~/.ssh/id_rsa.pub   root@B阿里云IP

如果ssh 登录端口不是22
需要再/root/.ssh下新建config文件,内容为:

Port 20222 
  1. 在测试的同步的时候就不需要密码了

crontab -e
输入同步命令:

* */2 * * *  rsync -avz root@B阿里云IP:/testsync/   /testsync_bak

如果只做简单的文件同步,到此就结束了,这是最简单的方式了.

  1. 支持实时同步
    我们上面做rsync进行同步的时候,如果文件多了不够实时,如果做到实时,可以对文件修改,新建等操作进行监控,然后我们根据监控命令触发部分文件的同步,这样我们再结合2个小时的实时文件同步,就可以完美支持大批量文件的实时同步了,找到网上一个脚本改下:
  1. 首先脚本应该在阿里B主机上建立,因为要监听的是B机器上的文件夹的变化.
  2. 监控脚本如下,名为:test.sh
#!/bin/bash
SRC=/testsync/
DST=root@阿里B的IP:/testsync_bak


inotifywait -mrq -e create,move,delete,modify,attrib $SRC | while read a b c
do
      echo "$c change's so start to rsync"
        rsync -azP --delete $(dirname ${c})   $DST
done
  1. 按照上面方法,设置B主机到A主机的免登陆功能
  2. 执行程序,后台实时监控:
sh test.sh

我们通过日志方便看到了文件的同步情况.

总结: 通过这种基于ssh的rsync操作完成了数据的同步,对于简单的场景,是适合的,如果需要同时同步多个目录,不是特别合适,不过我仍然喜欢这种方式,简单.

6.2 rsync daemon结合inotify同步

  1. 在腾讯A主机上配置
    vim /etc/rsyncd.conf
port=873
address =0.0.0.0
uid = root
gid = root
use chroot = yes
max connections = 5
pid file =/var/run/rsync.pid
lock file  =/var/run/rsync.lock
log file =/var/log/rsyncd.log
motd file =/etc/rsyncd.motd
use chroot = no
timeout = 300
dont compress = *.gz *.tgz *.zip *.bz2

[testsync_bak]
path =/testsync_bak
comment = xxxxx
read only = false
list = yes
hosts allows = 腾讯A机器IP/32
hosts deny = 0.0.0.0/32
auth users = rsync_user # 同步的用户
secrets file= /root/rsync.passwd  # 同步的用户密码文件

  1. 设置密码文件
vim  /root/rsync.passwd 
rsync_user:123@345 #用户名:密码

更改权限:

chmod 600 /etc/rsync.passwd
  1. 启动服务加入到启动项中
rsync --daemon --config=/etc/rsyncd.conf

报错:

2021/08/15 20:39:02 [4005270] rsyncd version 3.1.3 starting, listening on port 873
2021/08/15 20:39:02 [4005270] bind() failed: Cannot assign requested address (address-family 2)
2021/08/15 20:39:02 [4005270] unable to bind any inbound sockets on port 873

绑定地址改成address =0.0.0.0就好。

  1. 在阿里B机器上进行同步
 rsync -avz /testsync     rsync_user@腾讯云AIP::testsync_bak --password-file=/root/rsync.passwd

报错:

rsync: failed to connect to  腾讯A主机 ( 腾讯A主机): No route to host (113)
rsync error: error in socket IO (code 10) at clientserver.c(127) [sender=3.1.3

关闭防火墙就是:

systemctl stop firewalld

报错:

@ERROR: auth failed on module testsync_bak

注意要检查字段名配置是否正确,chmod 600 /etc/rsync.passwd 通过命令要更改权限,不然还是会校验失败。

报错:

for rsync_user: password mismatch

原因:

 rsync -avz /testsync     rsync_user@腾讯云AIP::testsync_bak --password-file=/root/rsync.passwd

/root/rsync.passwd 里面只要包含密码就行了。

把这个命令放在crontab里面即可,或写个sh放在crontab中。

inotify结合
网上找个脚本稍微更改了下:

#!/bin/bash
src=/testsync/                              # 需要同步的源路径
des=testsync_bak                             # 目标服务器上 rsync --daemon 发布的名称,rsync --daemon这里就不做介绍了,网上搜一下,比较简单。
rsync_passwd_file=/root/rsync.passwd            # rsync验证的密码文件
ip1=腾讯A机器IP                               # 目标服务器1
user=rsync_user                              # rsync --daemon定义的验证用户名
cd ${src}                            
# 此方法中,由于rsync同步的特性,这里必须要先cd到源目录,inotify再监听 ./ 才能rsync同步后目录结构一致,有兴趣的同学可以进行各种尝试观看其效果
inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ./ | while read file
# 把监控到有发生更改的"文件路径列表"循环
do
        INO_EVENT=$(echo $file | awk '{print $1}')      # 把inotify输出切割 把事件类型部分赋值给INO_EVENT
        INO_FILE=$(echo $file | awk '{print $2}')       # 把inotify输出切割 把文件路径部分赋值给INO_FILE
        echo "-------------------------------$(date)------------------------------------"
        echo $file
        #增加、修改、写入完成、移动进事件
        #增、改放在同一个判断,因为他们都肯定是针对文件的操作,即使是新建目录,要同步的也只是一个空目录,不会影响速度。
        if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'MODIFY' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]] ||[[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]  
        then
                echo 'CREATE or MODIFY or CLOSE_WRITE or MOVED_TO'
                rsync -avzcR  --delete  --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des} 
                # INO_FILE变量代表路径哦  -c校验文件内容   
        fi
        #修改属性事件 指 touch chgrp chmod chown等操作
        if [[ $INO_EVENT =~ 'ATTRIB' ]]
        then
                echo 'ATTRIB'
                if [ ! -d "$INO_FILE" ]
                # 如果修改属性的是目录 则不同步,因为同步目录会发生递归扫描,等此目录下的文件发生同步时,rsync会顺带更新此目录。
                then
                        rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des} 
                fi
        fi
done

运行:


测试运行

总结: 用配置文件的方式还是挺费劲的,好处是不用设置ssh免登录。

七 参考链接

[rsync 用法教程](http://www.ruanyifeng.com/blog/2020/08/rsync.html)
[rsync(一):基本命令和用法](https://blog.csdn.net/qq_32706349/article/details/91451053)
[真正的inotify+rsync实时同步 彻底告别同步慢](http://www.ttlsa.com/web/let-infotify-rsync-fast/)

上一篇下一篇

猜你喜欢

热点阅读