Linux下Rsync+sersync实现数据实时同步

时间:2022-12-22 07:30:23

本教程实现的是Linux服务器之间自动同步文件或目录的功能,网上有很多这方面的教程,大体有两种途径
(1)Rsync+inotify-tools
(2)Rsync+sersync
本教程采用第二种实现.下面先简单介绍几个项目中用到的软件或概念.

Rsync

  Rsync(remote synchronize)是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件。Rsync使用所谓的“Rsync算法”来使本地和远 程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部分,而不是每次都整份传送,因此速度相当快。

Rsync的基本特点如下:

  • 1.可以镜像保存整个目录树和文件系统;
  • 2.可以很容易做到保持原来文件的权限、时间、软硬链接等;
  • 3.无须特殊权限即可安装;
  • 4.优化的流程,文件传输效率高;
  • 5.可以使用rsh、ssh等方式来传输文件,当然也可以通过直接的socket连接;
  • 6.支持匿名传输。

inotify

  Inotify是一种文件变化通知机制,linux内核从2.6.13起,加入了Inotify支持,通过Inotify可以监控文件系统中添加,删除,修改,移动等各种事件,利用这个内核接口,第三方软件就可以监控文件系统下文件的各种变化情况,而inotify-tools正是实施这样监控的软件。
inotify 的实现有几款软件
注意:大前提rsync daemon 服务配置成功,可以在rsync客户端推送拉取数据,然后才能配置inotify服务。
- 1)inotify-tools,
- 2)sersync(金山周洋)
- 3)lsyncd

Rsync+inotify组合的起源

  Rsync(remote sync)远程同步工具,通过rsync可以实现对远程服务器数据的增量备份同步,但rsync自身也有瓶颈,同步数据时,rsync采用核心算法对远程服务器的目标文件进行比对,只进行差异同步。我们可以想象一下,如果服务器的文件数量达到了百万甚至千万量级,那么文件对比将是非常耗时的。而且发生变化的往往是其中很少的一部分,这是非常低效的方式。inotify的出现,可以缓解rsync不足之处,取长补短

为什么要用Rsync+sersync架构

Rsync+Inotify-tools
(1)Inotify-tools只能记录下被监听的目录发生了变化(包括增加、删除、修改),并没有把具体是哪个文件或者哪个目录发生了变化记录下来;
(2)rsync在同步的时候,并不知道具体是哪个文件或者哪个目录发生了变化,每次都是对整个目录进行同步,当数据量很大时,整个目录同步非常耗时(rsync要对整个目录遍历查找对比文件),因此,效率很低。
Rsync+sersync
(1)sersync可以记录下被监听目录中发生变化的(包括增加、删除、修改)具体某一个文件或某一个目录的名字;
(2)rsync在同步的时候,只同步发生变化的这个文件或者这个目录(每次发生变化的数据相对整个同步目录数据来说是很小的,rsync在遍历查找比对文件时,速度很快),因此,效率很高。

小结:
  当同步的目录数据量不大时,建议使用Rsync+Inotify-tools;当数据量很大(几百G甚至1T以上)、文件很多时,建议使用Rsync+sersync。
——————————————————————————————————

什么是xinetd

extended internet daemon
xinetd是新一代的网络守护进程服务程序,又叫超级Internet服务器,常用来管理多种轻量级Internet服务。
xinetd提供类似于inetd+tcp_wrapper的功能,但是更加强大和安全。
—xinetd的特色
1) 强大的存取控制功能
— 内置对恶意用户和善意用户的差别待遇设定。
— 使用libwrap支持,其效能更甚于tcpd。
— 可以限制连接的等级,基于主机的连接数和基于服务的连接数。
— 设置特定的连接时间。
— 将某个服务设置到特定的主机以提供服务。
2) 有效防止DoS攻击
— 可以限制连接的等级。
— 可以限制一个主机的最大连接数,从而防止某个主机独占某个服务。
— 可以限制日志文件的大小,防止磁盘空间被填满。
3) 强大的日志功能
— 可以为每一个服务就syslog设定日志等级。
— 如果不使用syslog,也可以为每个服务建立日志文件。
— 可以记录请求的起止时间以决定对方的访问时间。
— 可以记录试图非法访问的请求。
4) 转向功能
可以将客户端的请求转发到另一台主机去处理。
5) 支持IPv6
xinetd自xinetd 2.1.8.8pre*起的版本就支持IPv6,可以通过在./configure脚本中使用with-inet6 capability选项来完成。
注意,要使这个生效,核心和网络必须支持IPv6。IPv4仍然被支持。
6) 与客户端的交互功能
无论客户端请求是否成功,xinetd都会有提示告知连接状态。
—xinetd使用场景
原则上任何系统服务都可以使用xinetd,然而最适合的应该是那些常用的网络服务,同时,这个服务的请求数目和频繁程度不会太高。像DNS和Apache就不适合采用这种方式,而像FTP、Telnet、SSH等就适合使用xinetd模式

项目实战

服务器 系统版本 处理器位数 IP
源服务器 Ubuntu 17.04 64位 192.168.4.35
目标服务器 CentOS Linux 7 (Core) 64位 192.168.0.151

目标服务器配置

目标服务器配置

(1)关闭SELINUX

[root@localhost ~]# vi /etc/sysconfig/selinux

#SELINUX=enforcing  #注释掉
SELINUX=disabled   #增加
重启系统

或者

[root@localhost ~]# setenforce 0 #临时关闭(不用重启机器)立即生效

注意:ubuntu下selinux路径与上述的centos7不同,需执行如下命令
vi /etc/selinux/config ,将SELINUX=enforcing改为SELINUX=disabled 后重启机器即可

(2)开启防火墙tcp 873端口(Rsync默认端口)

[root@localhost ~]# vi /etc/sysconfig/iptables #编辑防火墙配置文件

-A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 873 -j ACCEPT #添加到默认的22端口这条规则的下面,如下所示:

\######################################
\# Firewall configuration written by system-config-firewall
\# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 22 -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 3306 -j ACCEPT
-A INPUT -j REJECT –reject-with icmp-host-prohibited
-A FORWARD -j REJECT –reject-with icmp-host-prohibited
COMMIT
\#####################################
/etc/init.d/iptables restart #最后重启防火墙使配置生效

注意:
我在centos 7下的/etc/sysconfig未找到iptables 只有ip6tables-config ,iptables-config .这是因为centos 7中iptables已不再是默认的防火墙了.可通过
systemctl stop firewalld
systemctl disable firewalld
关闭centos7的防火墙.至于centos 7如何配置端口过滤,请自行百度.本案例是虚拟机装的centos7,用于学习练手,不存在安全的考虑.所以,直接关闭了防火墙,不做配置.

(3)检查目标机是否安装rsync

[root@localhost sysconfig]# whereis rsync

rsync: /usr/bin/rsync /usr/share/man/man1/rsync.1.gz #说明已经安装了
若未安装执行一下命令安装:

yum install rsync

(4)编辑rsync配置文件

[root@localhost sysconfig]# vi /etc/rsyncd.conf #创建配置文件,添加以下代码
port=873
uid=root
gid=root
max connections=36000
use chroot=no
log file=/var/log/rsyncd.log
log format =  %t %a %m %f %b
pid file=/var/run/rsyncd.pid
lock file=/var/run/rsyncd.lock
motd file = /etc/rsyncd.motd
timeout = 600

[sync_sms]
path=/usr/local/tomcat-app/webapps/
list=yes
comment =sms sync 
ignore errors = yes
read only = no
hosts allow = *
#hosts deny = *
auth users  = root
secrets file = /etc/rsyncd.secrets
用户组最好设置为root,不然文件权限同步过去的时候会变化
  • secrets file这个是配置同步的密码文件的。
  • path是配置同步的目录,
  • hosts allow是允许同步的主机,
  • hosts deny:拒绝同步的主机

(4)创建rsync传输过程中的认证文件 ,即在secrets file指定的用户密码文件

vim /etc/rsyncd.secrets  内容格式:用户名:密码

添加如下内容:
root:coolgirl
或者执行

echo “user:password” >> /etc/rsync.passwd

把内容追加到rsync.passwd末尾
然后,更改文件的读写权限为600

chmod 600 /etc/rsync.passwd

(5)创建同步目录,即上述rsyncd.conf中[sync_sms]模块下path指定的路径

mkdir -p /usr/local/tomcat-app/webapps/

(6)检查并安装xinetd(关于xinetd的介绍,请参照上文)

检查系统是否已经安装xinetd

[root@localhost webapps]# whereis xinetd

xinetd: /usr/sbin/xinetd /etc/xinetd.d /etc/xinetd.conf /usr/share/man/man8/xinetd.8.gz #说明已经安装

否则执行安装

yum -y install xinetd

(9)配置rsync以xinetd方式运行 

[root@localhost webapps]# vi /etc/xinetd.d/rsync

添加如下内容:

service rsync
{
       disable         =no //使其随xinetd启动而启动
       wait            =no
       socket_type     =stream
       user            =root
       server          =/usr/bin/rsync
       server_args     = --daemon #设置成守护进程
       log_on_failure += USERID
}

注意:有的系统rsync是不存在的,可以执行上述命令创建并添加.xinetd的配置/etc/xinetd.conf 已配置包含了 /etc/xinetd.d/下的所有配置信息

(9)启动rsync与xinetd服务 

systemctl start xinetd  #启动xinetd服务
systemctl enable xinetd #将xinetd服务加入开机项
rsync –daemon –config=/etc/rsyncd.conf  #加载配置文件rsyncd.conf启动rsync服务

说明:–daemon 参数表示 启动rsync守护进程

(7)配置rsync开机自启动

echo “rsync –daemon –config=/etc/rsyncd.conf” >> /etc/rc.d/rc.local

———–截止目前,目标服务器已经配置完成了—————–

源服务器配置

(1)先到sersync官网下载sersync:http://sersync.sourceforge.net/

wget http://sersync.googlecode.com/files/sersync2.5.4_64bit_binary_stable_final.tar.gz

(2)安装sersync
1>解压

 tar -zxvf sersync2.5.4_64bit_binary_stable_final.tar.gz

 GNU-Linux-x86 #解压后的内容
 sersync2.5.4_64bit_binary_stable_final.tar.gz
2>创建sersync的家目录如下:

  mkdir /usr/local/sersync
  mkdir /usr/local/sersync/conf
  mkdir /usr/local/sersync/bin
  mkdir /usr/local/sersync/log

3>进入sersync解压目录,将内容拷贝到新建的sersync家目录中如下:

  cd GNU-Linux-x86/
  cp confxml.xml /usr/local/sersync/conf
  cp sersync2 /usr/local/sersync/bin

4>创建密码文件
密码需和目标服务器配置的一致,且不需要用户名.将该文件的权限也更改为600

 echo “coolgirl” >> /etc/rsync.passwd
 chmod 600 /etc/rsync.passwd

5>配置刚刚拷贝过来的config.xml ,路径/usr/local/sersync/conf/config.xml

 cp config.xml config.xml.bak #配置前提前备份一下

配置详情介绍,可参照以下示例.

<?xml version="1.0" encoding="UTF-8"?>
<head version="2.5">
     <!--设置本地IP和端口-->
    <host hostip="localhost" port="8008"></host>
     <!--开启DUBUG模式-->
    <debug start="false"/>
     <!--开启xfs文件系统 -->
    <fileSystem xfs="false"/>
     <!--同步时忽略推送的文件(正则表达式),默认关闭 -->
    <filter start="false">
    <exclude expression="(.*)\.svn"></exclude>
    <exclude expression="(.*)\.gz"></exclude>
    <exclude expression="^info/*"></exclude>
    <exclude expression="^static/*"></exclude>
    </filter>
    <!--设置要监控的事件-->
    <inotify>
    <delete start="false"/>
    <createFolder start="true"/>
    <createFile start="false"/>
    <closeWrite start="true"/>
    <moveFrom start="true"/>
    <moveTo start="true"/>
    <attrib start="false"/>
    <modify start="true"/>
    </inotify>
    <!--本地同步的目录路径-->
    <sersync>
    <localpath watch="/home/jing/projects/svn">
        <!--远程IP和rsync模块名 -->
        <remote ip="192.168.0.151" name="sync_sms"/>
        <!--<remote ip="192.168.8.39" name="tongbu"/>-->
        <!--<remote ip="192.168.8.40" name="tongbu"/>-->
    </localpath>
    <rsync>
        <!--rsync指令参数-->
        <commonParams params="-auvzP"/>
        <!-- rsync同步认证-->
        <auth start="true" users="root" passwordfile="/etc/rsync.passwd"/>
            <!--设置rsync远程服务端口,远程非默认端口则需打开自定义-->
        <userDefinedPort start="false" port="874"/><!-- port=874 -->
            <!--设置超时时间-->
        <timeout start="true" time="100"/><!-- timeout=100 -->
        <!--设置rsync+ssh加密传输模式,默认关闭,开启需设置SSH加密证书-->
        <ssh start="false"/>
    </rsync>
    <!--sersync传输失败日志脚本路径,每隔60会重新执行该脚本,执行完毕会自动清空。-->
    <failLog path="/usr/local/sersync/log/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
    <!--设置rsync+crontab定时传输,默认关闭-->
    <crontab start="false" schedule="600"><!--600mins-->
        <crontabfilter start="false">
        <exclude expression="*.php"></exclude>
        <exclude expression="info/*"></exclude>
        </crontabfilter>
    </crontab>
    <!-- 设置sersync传输后调用name指定的插件脚本,默认关闭-->
    <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>

6>创建同步目录:

mkdir /home/jing/projects/svn

7>设置环境变量

echo “export PATH=$PATH:/usr/local/sersync/bin/” >> /etc/profile
source /etc/profil

8>启动sersync

sersync2 -r -d -o /usr/local/sersync/conf/confxml.xml
注:

 选项-d 表示开启serync并守护进程,-o表示指定配置文件。

 重启操作:

 killall sersync2 && sersync2 -r -d -o /usr/local/sersync/conf/confxml.xml

9>设置开机启动

echo “sersync2 -r -d -o /usr/local/sersync/conf/confxml.xml” >> /etc/rc.local

源服务器的配置再啰嗦几句.
本人常用登录账号是非root账户,按照上述配置后,启动sersync2要么说是没有这个命令,要么就是日志报错

set the system param
execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches
sh: 1: cannot create /proc/sys/fs/inotify/max_user_watches: Permission denied
execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events
sh: 1: cannot create /proc/sys/fs/inotify/max_queued_events: Permission denied

提示Permission denied.纠结了很久终于找到了原因.因为我是按照root权限配置,非root账号没有权限访问600权限的配置文件或者密码文件,故报错.解决方案如下:
用sudo给非root赋予超管权限,并将sersync2带全路径启动.
sudo /usr/local/sersync/bin/sersync2 -r -d -o /usr/local/sersync/conf/conf.xml
以此命令启动后,发现日志文件不在提示Permission denied错误,在同步目录下,创建目录
cd /home/jing/projects/svn && sudo mkdir -p data0/www #注意这里创建时也必须用sudo获取超管身份来创建.
发现目标主机实时的创建了相同结构的目录.
此外,为了保险起见,将开机启动设置为如下:

echo “sudo /usr/local/sersync/bin/sersync2 -r -d -o /usr/local/sersync/conf/conf.xml” >> /etc/rc.local #超管权限全路径启动

———–好,源服务器已经配置完成了—————–

大家可以在刚才源服务器的同步目录 /home/jing/projects/svn下创建文件或目录,看看是否在目标服务器上已做同步.至于,同步的规则,即config.xml的配置详情,是增加,删除,还是定时,这里不做介绍,请自行百度学习,我觉的只要服务器搭好了,这些都是点小问题.
以下提供些参考学习的网站链接
sersyncXML配置:http://www.linuxidc.com/Linux/2012-02/53572p3.htm
http://www.cnblogs.com/sellsa/p/5345092.html
常见错误:http://blog.chinaunix.net/uid-13954085-id-158637.html