rsync+inotify实现远程实时同步

  • 时间:
  • 来源:互联网
  • 文章标签:

目录

    • 前言
    • 一、rsync介绍
    • 二、rsync工作原理
      • 2.1 rsync同步原理
      • 2.2 rsync-daemon认证
      • 2.3 ssh认证
    • 三、rsync特点
    • 四、rsync实现远程同步
      • 4.1 测试环境
      • 4.2 配置目标服务器(同步端)
      • 4.3 配置源服务器(被同步端)
      • 4.4 数据同步测试
    • 五、rsync+inotify实现远程实时同步
      • 5.1 配置目标服务器(同步端)
      • 5.2 数据同步测试
    • 总结

前言

在我们实际应用中,常常会对服务器的数据做相关的备份,比如我们最常见的tar打包备份、cp备份、scp远程拷贝以及mysql数据库的相关备份,甚至我们的drbd远程存储实时同步(不过这个方案已经很老了)等等。实际上从另一方面来说,这些备份操作保证了我们的数据的安全性,防止我们误操作带来的损失。而随着数据量的不断增加,很多数据显得是越来越重要,备份数据依然是我们运维工程师的首要任务。本次主要讲述了rsync+inotify实现远程实时同步。我们都知道 rsync 是一个很好的备份同步数据的工具,但是它不能够自动当目录中的文件发生变化时就进行同步,所以inotify的作用就是触发rsync实现同步备份操作。

一、rsync介绍

rsync(remote synchronize)是Liunx/Unix下的一个远程数据同步工具。它可通过LAN/WAN快速同步多台主机间的文件和目录,并适当利用rsync算法(差分编码)以减少数据的传输。

rsync第一次会全量传输,后续会对比两个文件的不同,只传输文件更新的部分,传输速度比一般工具快。rsync还可以拷贝、显示目录属性及拷贝文件,并可选择性的压缩及递归拷贝。

二、rsync工作原理

2.1 rsync同步原理

  1. 命令或者脚本运行之后,同步端开始构造FileList,FileList就是被同步端需要同步的文件索引,name–>id

    每个文件都有一个id值,如MD5。

  2. 同步端构造完成之后,将FileList发送到被同步端,被同步端rsync处理发送的FileList,然后开始同步。

  3. 第二次同步时,因为两边的都有文件,同步端构造发送这边的FileList,被同步端rsync处理同步端发送的FileList,根据MD5值比较,删除同步端已经相同的文件信息,保留不存在和更新的文件,来构建新的FileList。

  4. 同步端收到被同步端新的FileList,然后开始同步文件到同步端。

    注意:在使用rsync时,源服务器和目标服务器都必须安装rsync程序。

2.2 rsync-daemon认证

  • 在rsync-daemon认证方式下,默认监听tcp的873端口;

  • 在rsync-daemon认证下,rsync可以把密码写入到一个文件中。

    注意:被同步端的rsync必须启动和配置文件。同步端可以不起动服务,但必须有这个应用。

2.3 ssh认证

通过ssh隧道进行传输,类似于scp工具,同步操作不在局限于rsync中定义的同步文件夹,并且双方只要安装rsync,也不要双方启动rsync。例如:

# rsync -avz /root/test root@10.20.151.36:/root/

若rsync服务端ssh为非标准端口,可通过rsync的-e参数进行端口指定。使用方式如下:

# rsync -avz /root/test -e ‘ssh -p1234’ root@10.20.151.36:/root/

三、rsync特点

(1)优点:

1.安全性高;
2.备份迅速,使用同步算法,只比较变化;
3.支持增量备份;
4.保存源目录整个目录树和文件系统;
5.保持源文件的权限、时间、软硬连接等;
6.无需特使权限即可安装;
7.优化流程和比较高的文件传输效率;
8.多样方式来传输文件;
9.支持匿名运行,方便网站镜像;
10.与scp相比,rsync传输速度远在scp之上。'局域网测试,rsync是scp的20倍'
11.解决对实时性要求不高的数据备份需求。

(2)不足:

1.同步数据,需要扫描所有文件进行对比,才进行差量传输。如果文件数量达到百万甚至千万级,扫描文件对比文件将非常耗时,降低了rsync效率。
2.rsync不能实时地区监测、同步数据。虽然可以通过守护进程方式触发同步,但两次动作间有时间差,导致数据不一致,无法应对出现故障时完全恢复数据。

解决:rsync+inotify来弥补不足。

四、rsync实现远程同步

4.1 测试环境

测试环境为centos7.8
关闭selinux和防火墙
源服务器地址:10.20.151.74
目标服务器地址: 10.20.151.36
目的:将原来的服务器的/data/test目录实时同步到目标服务器的/opt/www目录下。

4.2 配置目标服务器(同步端)

这里的目标服务器就是我们要实现远程同步的机器

目标服务器地址: 10.20.151.36

(1)安装rsync

[root@rsync-target ~]# rpm -qa | grep rsync
[root@rsync-target ~]# yum provides rsync
Loaded plugins: fastestmirror
Determining fastest mirrors
 * base: mirrors.aliyun.com
 * epel: fedora.cs.nctu.edu.tw
 * extras: mirrors.aliyun.com
 * updates: mirrors.aliyun.com
rsync-3.1.2-10.el7.x86_64 : A program for synchronizing files over a network
Repo        : base

[root@rsync-target ~]# yum install -y rsync-3.1.2-10.el7.x86_64

(2)修改rsync配置文件

[root@rsync-target ~]# mv /etc/rsyncd.conf /etc/rsyncd.conf.bak
[root@rsync-target ~]# vim /etc/rsyncd.conf
log file = /var/log/rsyncd.log
pidfile = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
secrets file = /etc/rsync.pass   # 用户认证配置文件,里面保存用户名称和密码(后面会创建这个文件)
motd file = /etc/rsyncd.Motd     # rsync启动时欢迎信息页面文件位置(文件内容自定义)可有可无
[www]             # 同步模块名称(这个模块就是待会儿对端写脚本的里面一个参数的名称)
path = /opt/www   # 需要同步的目录(准确的说是同步过来后放到哪里的目录路径)
auth users = tom  # 执行数据同步的用户名,可以设置多个,用英文状态下逗号隔开(认证用户)
uid = root  # 工作中指定用户(可以不指定为0)
gid = root  # 工作中指定用户(可以不指定为0)
port = 873
ignore errors    # 表示出现错误忽略错误
use chroot = no  # 相当于黑洞,出错定位
read only = no   # 表示网络权限可写(本地控制真正可写)(亲测这里写false报错)
list = no        # 这里设置IP或让不让同步
max connections = 200   # 有多少个客户端同时传文件
timeout = 300           # 超时时间
hosts allow = 10.20.151.74   # 允许进行数据同步的客户端IP地址,可以设置多个,用英文状态下逗号隔开
hosts deny = 0.0.0.0/32      # 拒绝传输的ip(这样写表示都不禁止)

(3)创建用户并设置密码

[root@rsync-target ~]# useradd tom
[root@rsync-target ~]# echo '015210' | passwd --stdin tom
Changing password for user tom.
passwd: all authentication tokens updated successfully.

(4)创建同步目录

[root@rsync-target ~]# mkdir /opt/www 

(5)创建用户认证文件

[root@rsync-target ~]# vim /etc/rsync.pass
tom:015210   # 用户名:密码

(6)设置文件权限

[root@rsync-target ~]# chmod 600 /etc/rsyncd.conf
[root@rsync-target ~]# chmod 600 /etc/rsync.pass 

(7)启动rsync服务

[root@rsync-target ~]# systemctl start rsyncd
[root@rsync-target ~]# systemctl enable rsyncd

在这里插入图片描述

(8)设置同步目录的权限

[root@rsync-target ~]# chmod 765 /opt/www/  # 同步目录设置765权限

4.3 配置源服务器(被同步端)

这里的源服务器就是我们要将数据同步到其他机器上的机器。

源服务器地址:10.20.151.74

(1)安装rsync

[root@rsync-source ~]# rpm -qa | grep rsync
[root@rsync-source ~]# yum provides rsync
Loaded plugins: fastestmirror
Repodata is over 2 weeks old. Install yum-cron? Or run: yum makecache fast
Determining fastest mirrors
 * base: mirrors.cn99.com
 * extras: mirrors.cn99.com
 * updates: mirrors.cn99.com
rsync-3.1.2-10.el7.x86_64 : A program for synchronizing files over a network
Repo        : base

[root@rsync-source ~]# yum install -y rsync-3.1.2-10.el7.x86_64

(2)创建被同步目录

[root@rsync-source ~]# mkdir -p /data/test

(3)创建密码认证文件

[root@rsync-source ~]# vim /etc/rsync.password
015210      # 整个文件需要600的权限和服务端rsync同步用户的密码,这里是服务器端jack用户的密码  

(4)设置密码认证文件权限

[root@rsync-source ~]# chmod 600  /etc/rsync.password

(5)启动rsync服务

[root@rsync-source ~]# systemctl start rsyncd
[root@rsync-source ~]# systemctl enable rsyncd

在这里插入图片描述

4.4 数据同步测试

(1)在源服务器创建测试文件

[root@rsync-source ~]# cd /data/test/       # 进入共享目录
[root@rsync-source test]# touch hello.txt   # 创建测试文件

(2)手动将测试文件同步到目标服务器

通过下面的命令可以将创建的hello.txt同步到目标服务器。

[root@rsync-source test]# rsync -avH --port=873 --delete --progress /data/test/ tom@10.20.151.36::www --password-file=/etc/rsync.password 

sending incremental file list
./
hello.txt
              0 100%    0.00kB/s    0:00:00 (xfr#1, to-chk=0/2)

sent 118 bytes  received 46 bytes  328.00 bytes/sec
total size is 0  speedup is 0.00

(3)查看目标服务器的同步目录是否有文件

[root@rsync-target ~]# cd /opt/www/
[root@rsync-target www]# ls
hello.txt    # 该文件是源服务器同步过来的文件,测试成功

五、rsync+inotify实现远程实时同步

安装Inotify-tools工具,实时触发rsync进行同步。

在这里插入图片描述

5.1 配置目标服务器(同步端)

(1)查看服务器内核是否支持inotify

[root@rsync-source ~]# ll /proc/sys/fs/inotify/
total 0
-rw-r--r--. 1 root root 0 Oct 24 10:13 max_queued_events
-rw-r--r--. 1 root root 0 Oct 24 10:13 max_user_instances
-rw-r--r--. 1 root root 0 Oct 24 10:13 max_user_watches

列出文件目录,出现下面的内容,说明服务器内核支持inotify。

注:Linux下支持inotify的内核最小为2.6.13。

inotify安装方式:yum安装、编译安装。

(2)安装inotify(yum方式安装)

[root@rsync-source ~]# rpm -qa inotify-tools
[root@rsync-source ~]# yum install -y wget
[root@rsync-source ~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo           # 更换为阿里源
[root@rsync-source ~]# yum install -y inotify-tools  # 安装inotify

inotify安装上的两个主要命令:inotifywait、inotifywatch

inotifywait和inotifywatch的作用:

  • inotifywait:在被监控的文件或目录上等待特定文件系统事件(open close delete等)发生,
    执行后处于阻塞状态,适合在shell脚本中使用。
  • inotifywatch:收集被监控的文件系统使用的统计数据,指文件系统事件发生的次数统计。

(3)修改inotify默认参数(inotify默认内核参数值太小)

  • 查看系统默认参数值

    [root@rsync-source ~]# sysctl -a | grep max_queued_events
    [root@rsync-source ~]# sysctl -a | grep max_user_watches
    [root@rsync-source ~]# sysctl -a | grep max_user_instances
    

    在这里插入图片描述

  • 修改默认参数

    [root@rsync-source ~]# vim /etc/sysctl.conf
    

    在这里插入图片描述

    参数说明:

    • max_queued_events:
      inotify队列最大长度,如果值太小,会出现 Event Queue Overflow 错误,导致监控文件不准确。

    • max_user_watches:
      要同步的文件包含多少目录,可以用:find /data/test -type d | wc -l 统计,必须保证max_user_watches值大于统计结果(这里/data/test为同步文件目录)

    • max_user_instances:
      每个用户创建inotify实例最大值

(4)编写脚本

[root@rsync-source ~]# vim inotify.sh
#!/bin/bash
Path="/data/test"                 # 文件同步目录(被同步端)
backup_Server="10.20.151.36"      # 目标服服务器IP(同步端) 
excludedir="/root/exclude.list"   # 不需要同步的目录
# 如果有多个,每一行写一个目录,使用相对于同步模块的路径;
# 例如:不需要同步/home_test目录下的a目录和b目录下面的b1目录,exclude.list文件可以这样写
# a/
# b/c/
user="tom"
pass_file="/etc/rsync.password"
module="www"
/usr/bin/inotifywait -mrq --format '%w%f' -e create,close_write,delete $Path | while read line   # 把'|'前面的标准输出输出到line作为参数列表进行while语句操作
do
        if [ -f $line ];then
                rsync -azH $line --delete --progress --exclude-from=$excludedir $user@$backup_Server::$module --password-file=$pass_file
        else
                cd $Path && rsync -azH ./ --delete --progress --exclude-from=$excludedir $user@$backup_Server::$module --password-file=$pass_file
        fi
done
[root@rsync-source ~]# chmod +x inotify.sh    # 添加x执行权限

inotify参数说明:
-m:是保持一直监听
-r:是递归查看目录
-q:是打印出事件
-e:create,move,delete,modify,attrib 是指 “监听 创建 移动 删除 写入 权限” 事件

5.2 数据同步测试

(1)设置脚本运行方式

1.不重启服务器的情况通过计划任务实现。
2.通过vim /etc/rc.d/rc.local 实现开机自动执行。

这里选择第一种方式执行脚本

[root@rsync-source ~]# crontab -e
* * * * * /bin/bash /root/inotify.sh >/dev/null 2>&1 &

(2)创建测试数据(被同步端)

这里实现除了a目录外的其他文件均进行实时同步操作。这时根据shell脚本定义的不需要实时同步的目录路径进行添加不需要同步的目录的相对路径(对于同步模块的路径)即可。

[root@rsync-source test]# vim /root/exclude.list
a/   # 如果有多个文件不需要进行实时同步,往exclude.list文件中添加即可(每写一行就表示一个目录或多级目录)
[root@rsync-source ~]# cd /data/test/   # 进入被同步目录
[root@rsync-source test]# mkdir a       # 创建目录a,用来证明a目录是不能被同步的
[root@rsync-source test]# touch hello{1..5}.txt
[root@rsync-source test]# ls
a  hello1.txt  hello2.txt  hello3.txt  hello4.txt  hello5.txt

(3)查看实时同步数据(同步端)

从同步的结果来看:a目录没有被实时同步,说明/root/exclude.list限制的文件生效。同时除了a目录的其他所有文件均被实时同步(当然,当删除源服务器,即被同步端的被同步文件时,同步端对应的实时同步目录的数据也随之被删除),其实这就类似于我们的mysql主从同。

[root@rsync-target ~]# cd /opt/www/
[root@rsync-target www]# ls
hello1.txt  hello2.txt  hello3.txt  hello4.txt  hello5.txt

总结

本次主要介绍了rsync服务的工作原理(同步),以及通过rsync+inotify实现的数据远程实时同步。相对于我们的scp方式来说速度更快,可实现大量数据的实时同步。只要你从头到尾看一遍,实际上bin不复杂,原理也很简单,当然你需要具备良好的shell基础和编程能力。在实时同步中,我采用的是计划任务的方式实时执行脚本文件,当然你也可以通过vim /etc/rc.d/rc.local实现开机自动执行的操作(两种操作效果实际上都一样,先其一即可)。需要注意的是:在进行实时同步时,我们需要修改inotify的默认参数,因为inotify的默认参数都都比较小,这可能会导致在实时同步过程中出现同步错误,导致数据无法同步。inotify除了yum方式安装,还可以使用编译安装(上文使用的是yum安装)。编译安装也很简单,进入解压目录后直接./configure --prefix=/usr/local/inotify && make && make install即可(编译安装的优点就是可以自定义相关安装路径)。以上就是对rsync+inotify实现远程实时同步的工作原理介绍和数据同步的简单测试。

本文链接http://www.taodudu.cc/news/show-1781960.html