zoukankan      html  css  js  c++  java
  • 三十、sersync高级同步工具实时数据同步架构

    一、项目介绍

         Sersync项目利用inotity与rsync技术实现对服务器数据实时同步的解决方案,其中inotity用于监控sersync所在服务器上的文件变化。

          Sersync项目的优点:

       1. 相比较单纯的inotity工具,sersync是使用C++编写的,对linux系统文件产生的临时文件和重复的文件操作有过滤功能,在结合rsync的时候,会减少运行时消耗的本地及网络资源,速度快。

       2.配置简单

       3.使用多线程进行同步(即可以并发同步多个不同的文件),尤其在同步较大的文件时,能够保证多个服务器实时保持同步状态。

       4.sersync自带出错处理机制,通过失败 队列对出错的文件重新同步,还出错,每10个小时再来一遍。

       5.sersync自带crontab功能,只需在xml配置中开启,就可以同步。

       6.sersync自动socket与http的协议扩展,可满足二次开发需求。

    二、基本框架

    三、 设计简析

    1.线程组线程是等待线程对立的守护线程,当事件队列中有数据产生的时候,线程组守护线程就会逐个唤醒同步线程,当队列中inotify事件较多的时候,同步线程就会被全部唤醒一起工作。这样设计的目的是能够同时处理多个inotify事件,从而提升服务器的并发同步能力。之所以称之为线程组线程,是因为每个线程在工作的时候,会根据服务器上新写入文件的数量建立子线程,子线程可以保证所有的文件与各个服务器同时同步,当要同步的文件较大的时候,这样的设计可以保证各个远程服务器可以同事获得要同步的文件。

    2.服务器线程的作用有三个(保证主服务器和从服务器数据一致且实时):

    2.1 处理同步失败的文件,将这些文件再次同步,对于再次同步失败的文件会生成rsync_fail_log.sh脚本,记录失败的事件

    2.2 同时每个10小时执行脚本一次,同时清空脚本。

    2.3 还有就是crontab功能,可以每隔一定事件,将所有路径整体同步一次。

    3.过滤队列的建立是为了过滤短时间内产生的重复的inotify信息,例如在删除文件夹的时候,inotify就会同事产生删除文件夹里的文件与删除文件夹的事件,通过过滤队列,当删除文件夹时间产生的时候,会将之前加入队列的删除文件的事件全部过滤掉,这样只产生一条删除文件夹事件,从而减轻了同步的负担。同时对于修改文件的操作的时候,会产生临时文件的重复操作。

    四、sersync安装配置

    4.1 sersync同步需求逻辑图

    当前版本的sersync依赖于rsync进行数据同步,如下图所示,在同步主服务器(Master)上开启sersync,sersync负责监控配置路径中的文件系统事件变化,然后调用rsync命令把更新的文件同步到目标服务器(Slave),因此,需要在主服务器配置sersync,在同步目标服务器配置rsync server(注意:是rsync服务器)

    如图所示,用户会实时网左边的同步主服务器(M)上写入或更新文件数据,此时需要在左边的同步服务器(M)上配置sersync服务,在右边的同步目标服务器S1和S2服务器上配置rsync守护进程,这样在主服务器M上产生的写入或更新的文件就会被sersync服务实时的同步到多个目标服务器(S1,S2等)。一般的Linux服务器一般安装了rsync软件,因此在主服务器(M)上有rsync命令即可,在目标服务器(S1、S2)上只需要进行简单的配置,并开启rsync守候进程即可。

    4.2安装环境准备

    角色服务器配置 IP机器名
    sersync服务(M) VM   192.168.0.103 djw
    rsync服务(S1) VM   192.168.0.100 djw1
    rsync服务(S2) VM   192.168.0.104 djw2

    4.3 配置同步服务器

    部署总结:
    步骤一、 配置slave上的rsync服务
    步骤二、 配置master上sersync客户端

    4.3.1 slave上部署rsync服务

              本次测试使用的服务器为djw1和djw2 server,即IP为192.168.0.100,192.168.0.104

        vim /etc/rsyncd.conf 写入如下测试内容:

    # Minimal configuration file for rsync daemon

    # See rsync(1) and rsyncd.conf(5) man pages for help

    # This line is required by the /etc/init.d/rsyncd script
    # GLOBAL OPTIONS
    uid = root                         
    gid = root                                  
    use chroot = no
    read only = false
    #limit access to private LANs
    hosts allow=192.168.0.0/24
    hosts deny=*
    ignore errors
    max connections = 2000
    pid file = /var/run/rsyncd.pid
    auth users = rsync_backup
    secrets file = /etc/rsyncd.password
    #lock file = /var/run/rsync.lock
    motd file = /etc/rsyncd/rsyncd.motd
    #This will give you a separate log file
    log file = /var/log/rsync.log
    #This will log every file transferred - up to 85,000+ per user, per sync
    transfer logging = yes
    log format = %t %a %m %f %b
    syslog facility = local3
    timeout = 300
    # MODULE OPTIONS
    [bbs]
    comment = bbs by www 2015年10月27日15:53:24 
    path = /var/www/html/bbs                       
    [blog]
    comment = blog by www 2015年10月27日15:53:24 
    path = /var/www/html/blog
    上面的rsync服务的配置文件表明允许sersync主服务器(IP为192.168.0.103)访问,rsync同步模块名为[bbs],[blog]将同步过来的文件分别放入
    对应的path指定的目录 /var/www/html/bbs,/var/www/html/blog下,如果有多台目标服务器,则每台都需要进行类似的rsync服务配置,上面的
    uid,gid要换成本服务器对应的同步用户。注意rsync服务账户(上述用了root用户)要有对被同步目录(/var/www/html)的写入更新权限。

    创建待同步的目录
    [root@li-centos6.5 /var/www]
    # mkdir -p /var/www/html/bbs /var/www/html/blog
    
    [root@li-centos6.5 /var/www]
    # tree /var/www/html
    /var/www/html
    ├── bbs
    └── blog
    # 此步骤在djw1,djw2 上都要执行,否则,rsync服务会因为没有path路径而无法启动。

    置相关权限认证

    echo "rsync_backup:123456">/etc/rsyncd.password
    chmod 600 /etc/rsyncd.password
    # order for check
    cat /etc/rsyncd.password
    ll /etc/rsyncd.password
    配置好后,使用下面的命令开启rsync守护进程
    rsync --daemon
    ps -ef|grep rsync
    netstat -tunpl|grep :873
    置开机自启动
    echo "/usr/bin/rsync --daemon">>/etc/rc.local
    grep demoan /etc/rc.local
    4.3.2  master上配置rsync客户端(Master操作)
    4.3.2.1master上配置rsync权限
    在master(192.168.0.100)上配置rsync客户端相关权限

    echo '123456' > /etc/rsync.password
    chmod 600 /etc/rsync.password 
    cat /etc/rsync.password 
    ll /etc/rsync.password

    4.3.2.2
    master上手工测试rsync同步情况(此步骤非常关键且重要,如果这里测试都不成功,后面的sersync配好也不会同步数据
    1. 分别创建待同步数据
    touch /var/www/html/bbs/bbs.log /var/www/html/blog/blog.log
    tree /var/www/html/

       2. 执行同步命令(操作之前停用防火墙)

    
    
    rsync -avz /var/www/html/bbs/ rsync_backup@192.168.0.101::bbs/ --password-file=/etc/rsync.password
    rsync -avz /var/www/html/bbs/ rsync_backup@192.168.0.104::bbs/ --password-file=/etc/rsync.password
    
    rsync -avz /var/www/html/blog/ rsync_backup@192.168.0.101::blog/ --password-file=/etc/rsync.password
    rsync -avz /var/www/html/blog/ rsync_backup@192.168.0.104::blog/ --password-file=/etc/rsync.password
    
    

    同步完后,可以到两台slave服务器上查看结果,如下:

    [root@li-centos6.5 /var/www/html]

    # tree /var/www/html  # 检查目录和文件同步情况
    ├── bbs
    │   └── bbg.log
    └── blog
        └── blog.log
    [root@li-centos6.7 /var/www/html]
    # tree /var/www/html.  # 检查目录和文件同步情况
    ├── bbs
    │   └── bbg.log
    └── blog
        └── blog.log
    4.3.3 master上配置rsync客户端
    4.3.3.1 下载sersync
    
    

    下载sersync的可执行文件版本,里面有配置文件和可执行文件,如下:
    cd /usr/local/src && http://down.whsir.com/downloads/sersync2.5.4_64bit_binary_stable_final.tar.gz

    4.3.3.2 安装sersync

    tar xf sersync2.5.4_64bit_binary_stable_final.tar.gz

    mv GNU-Linux-x86 /usr/local/sersync
    tree /usr/local/sersync/ 
    /usr/local/sersync/
    ├── confxml.xml
    └── sersync2

    4.3.3.3 规范sersync目录结构(非必须)
    
    
    cd /usr/local/sersync/ && mkdir conf bin logs
    mv confxml.xml ./conf/. && mv sersync2 ./bin/sersync
    tree /usr/local/sersync[root@djw sersync]# tree /usr/local/sersync
    /usr/local/sersync
    ├── bin
    │   └── sersync
    ├── conf
    │   └── confxml.xml
    └── logs
    4.3.3.4 配置sersync
    # /bin/cp conf/confxml.xml conf/confxml.xml.luo.$(date +%F)   # 备份配置文件
    [root@djw sersync]# tree conf/
    conf/
    ├── confxml.xml
    └── confxml.xml.luo.2019-06-20
    初始化的配置文件内容如下:
    [root@djw conf]# cat -n confxml.xml
         1  <?xml version="1.0" encoding="ISO-8859-1"?>
         2  <head version="2.5">
         3      <host hostip="localhost" port="8008"></host>
         4      <debug start="false"/>
         5      <fileSystem xfs="false"/>
         6      <filter start="false">
         7          <exclude expression="(.*).svn"></exclude>
         8          <exclude expression="(.*).gz"></exclude>
         9          <exclude expression="^info/*"></exclude>
        10          <exclude expression="^static/*"></exclude>
        11      </filter>
        12      <inotify>
        13          <delete start="true"/>
        14          <createFolder start="true"/>
        15          <createFile start="false"/>
        16          <closeWrite start="true"/>
        17          <moveFrom start="true"/>
        18          <moveTo start="true"/>
        19          <attrib start="false"/>
        20          <modify start="false"/>
        21      </inotify>
        22
        23      <sersync>
        24          <localpath watch="/opt/tongbu">
        25              <remote ip="127.0.0.1" name="tongbu1"/>
        26              <!--<remote ip="192.168.8.39" name="tongbu"/>-->
        27              <!--<remote ip="192.168.8.40" name="tongbu"/>-->
        28          </localpath>
        29          <rsync>
        30              <commonParams params="-artuz"/>
        31              <auth start="false" users="root" passwordfile="/etc/rsync.pas"/>
        32              <userDefinedPort start="false" port="874"/><!-- port=874 -->
        33              <timeout start="false" time="100"/><!-- timeout=100 -->
        34              <ssh start="false"/>
        35          </rsync>
        36          <failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
        37          <crontab start="false" schedule="600"><!--600mins-->
        38              <crontabfilter start="false">
        39                  <exclude expression="*.php"></exclude>
        40                  <exclude expression="info/*"></exclude>
        41              </crontabfilter>
        42          </crontab>
        43          <plugin start="false" name="command"/>
        44      </sersync>
        45
        46      <plugin name="command">
        47          <param prefix="/bin/sh" suffix="" ignoreError="true"/>  <!--prefix /opt/tongbu/mmm.sh suffix-->
        48          <filter start="false">
        49              <include expression="(.*).php"/>
        50              <include expression="(.*).sh"/>
        51          </filter>
        52      </plugin>
        53
        54      <plugin name="socket">
        55          <localpath watch="/opt/tongbu">
        56              <deshost ip="192.168.138.20" port="8009"/>
        57          </localpath>
        58      </plugin>
        59      <plugin name="refreshCDN">
        60          <localpath watch="/data0/htdocs/cms.xoyo.com/site/">
        61              <cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
        62              <sendurl base="http://pic.xoyo.com/cms"/>
        63              <regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/>
        64          </localpath>
        65      </plugin>
        66  </head>

    1) 修改24~28行的内容

    
    
    24         <localpath watch="/opt/tongbu"> # 定义本地要同步的目录
    25             <remote ip="127.0.0.1" name="tongbu1"/> # 定义要同步的服务器IP和模块名(例如上述的blog、bbs)
    26             <!--<remote ip="192.168.8.39" name="tongbu"/>-->
    27             <!--<remote ip="192.168.8.40" name="tongbu"/>-->
    28         </localpath>
    
    
    

    修改后如下:

    
    
    <localpath watch="/var/www/html/blog"> # 定义本地要同步的目录
    <remote ip="192.168.0.100" name="blog"/> # 定义要同步的服务器IP和模块名(例如上述的blog、bbs)
    <remote ip="192.168.0.104" name="blog"/>
    </localpath>
    <localpath watch="/var/www/html/bbs"> # 定义本地要同步的目录
    <remote ip="192.168.0.100" name="bbs"/> # 定义要同步的服务器IP和模块名(例如上述的blog、bbs)
    <remote ip="192.168.0.104" name="bbs"/>

    2) 修改31~34行(认证部分)

    31             <auth start="false" users="root" passwordfile="/etc/rsync.pas"/>
    32                 <userDefinedPort start="false" port="874"/><!-- port=874 -->
    33                 <timeout start="false" time="100"/><!-- timeout=100 -->
    34             <ssh start="false"/>
    

    修改后的内容如下:

    <auth start="true" users="rsync_backup" passwordfile="/etc/rsync.password"/> <!--slave服务器的用户名-->
    	    <userDefinedPort start="false" port="874"/><!-- port=874 -->
    	    <timeout start="true" time="100"/><!-- timeout=100 -->
    <ssh start="false"/>
    
    

    3) 修改36~37行
    36 <failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->

    
    

    修改后的内容如下:

    
    

    36 <failLog path="/usr/local/sersync/logs/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
    当同步失败后,日志记录到/usr/local/sersync/logs/rsync_fail_log.sh文件中,并且每60分钟对失败的log进行重新同步。

    4.3.3.4 开启sersync守护进程同步数据

    配置sersync环境变量

    echo 'export PATH=/usr/local/sersync/bin:$PATH'>>/etc/profile
    tail -1 /etc/profile
    source /etc/profile
    which sersync
    

    启动sersync命令:
    sersync -r -d -o /usr/local/sersync/conf/confxml.xml

    [root@djw conf]# sersync -r -d -o /usr/local/sersync/conf/confxml.xml
    set the system param
    execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches
    execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events
    parse the command param
    option: -r      rsync all the local files to the remote servers before the sersync work
    option: -d      run as a daemon
    option: -o      config xml name:  /usr/local/sersync/conf/confxml.xml
    daemon thread num: 10
    parse xml config file
    host ip : localhost     host port: 8008
    daemon start,sersync run behind the console
    config xml parse success
    please set /etc/rsyncd.conf max connections=0 Manually
    sersync working thread 12  = 1(primary thread) + 1(fail retry thread) + 10(daemon sub threads)
    Max threads numbers is: 32 = 12(Thread pool nums) + 20(Sub threads)
    please according your cpu ,use -n param to adjust the cpu rate
    ------------------------------------------
    rsync the directory recursivly to the remote servers once
    working please wait...
    execute command: cd /var/www/html/blog && rsync -artuz -R --delete ./ 192.168.0.101::blog >/dev/null 2>&1

    测试结果:发现问题,多实例的情况下仅第一个模块的路径能同步,其他模块下面的路径不能同步。
     sersync -r -d -o /usr/local/sersync/conf/confxml_bbs.xml

    配置多实例的同步情况(针对多个模块同步的情况)

    
    
    sersync –d –o /usr/local/serysnc/conf/blog_confxml.xml
    sersync –d –o /usr/local/serysnc/conf/bbs_confxml.xml
    … …
    
    

    不同的config文件是将模块分开放置,即:4.3.3.3步骤中的第一步中的代码分开在几个不同的文件中,这样启动的时候指定模块同步。

    将上述命令,写入/etc/rc.local中,随系统自启动

    /bin/cp /etc/rc.local /etc/rc.local_luo_$(date +%F)
    cat >>/etc/rc.local<<EOF
    # sersync data to 192.168.0.101,192.168.1.102
    sersync –d –o /usr/local/serysnc/conf/confxml_bbs.xml
    sersync –d –o /usr/local/serysnc/conf/confxml_blog.xml
    EOF

    tail -3 /etc/rc.local

    至此,已经完成了Master上对Slave1,Slave2上多实例(bbs,blog多模块)的同步。

    五、最后,配置文件中的 /usr/local/serysnc/conf/confxml.xml逐行了解,可以百度网络上。
    这里要说明一下:
    1)sersync可选功能是通过xml配置文件来实现的
    2)插件的定义:在现有软件上实现某个功能的时候,通过配置调用其他软件或者工具的功能,让其他软件在这个调用的时候执行其功能,这个软件在原软件上就叫做插件,表示插入的东东,嘿嘿!
    3)在xml文件中的46行开始,都是插件的功能。
    
    
    
    
     
    
    
  • 相关阅读:
    UART中RTS、CTS
    Verdi:内存不足
    SV学习之interface
    perl学习之:@_ $_
    perl学习之:package and module
    代码变成可执行程序期间,编译器做了那些事?
    perl学习之:use & require
    perl学习之:use and require
    8位二进制补码表示整数的最小值是什么,最大值是什么
    深入理解计算机系统
  • 原文地址:https://www.cnblogs.com/dangjingwei/p/11048511.html
Copyright © 2011-2022 走看看