最近接到一个需求,需要做文件同步,一个程序在某个文件夹下生成数据,其他的几台服务器需要用到这些数据,不愿意弄共享存储服务以及搞NAS什么的,就用 rsync + inotify做下实时同步好了,简单方便,这这篇文章是为了记录下,免得以后有类似需求再忘记。

需求如下,一共7台服务器,其中一台服务器在某个目录下面生成文件,然后同步到6台服务器上去。
生成文件的服务器为:192.168.0.1
其他六台服务器为:192.168.0.2-7

服务器端 rsync 的安装和配置

在6台被同步的服务器 192.168.0.2-7 上面安装 rsync ,作为懒人,当然不可以一台台服务器登录去安装了,自动化工具 fabric 派上用场(我前面有讲解 fabric 用法的系列文章)。上代码

#!/usr/bin/python env
# -*- coding: UTF-8 -*-

from fabric.api import env
from fabric.api import run
from fabric.api import put
from fabric.api import execute
from fabric.api import roles
from fabric.api import parallel
from fabric.api import cd

env.user = 'username'
env.password = 'password'
env.roledefs = {
    'rsync-server': ['192.168.0.2', '192.168.0.3','192.168.0.4','192.168.0.5','192.168.0.6','192.168.0.7'],
}

@roles('rsync-server')
def install_rsync():
    run('sudo yum -y install rsync')

@roles('rsync-server')
def put_rsync_conf():
   put('rsyncd.conf','/tmp/rsyncd.conf')

@roles('rsync-server')
def put_rsync_pass_conf():
    put('rsync.password','/tmp/rsync.password')

@roles('rsync-server')
def copy_rsync_conf():
    run('sudo cp -av /tmp/rsyncd.conf /etc/rsyncd.conf')

@roles('rsync-server')
def copy_rsync_pass_conf():
    run('sudo cp -av /tmp/rsync.password /etc/rsync.password') 

@roles('rsync-server')
def change_auth_rsync_pass():
    run('sudo chmod 600 /etc/rsync.password') # 这个必须修改权限为600,不然无法认证

@roles('rsync-server')
def start_rsync_deamon():
    run('sudo /usr/bin/rsync --daemon --config=/etc/rsyncd.conf')



@parallel    
def execute_all():
    execute(install_rsync)
    execute(put_rsync_conf)
    execute(put_rsync_pass_conf)
    execute(copy_rsync_conf)
    execute(copy_rsync_pass_conf)
    execute(change_auth_rsync_pass)
    execute(start_rsync_deamon)

其中 /etc/rsyncd.conf 的配置文件如下:

uid = root                              #全局配置开始,运行rsync的用户
gid = root                              #运行rsync的用户组
usechroot = no                          #是否让进程离开工作目录  
max connections = 20                    #最大进程并发数
timeout = 600                           #连接超时时间  
pid file = /var/run/rsyncd.pid          #指定运行的rsync进程的pid存放路径
lock file = /var/run/rsync.lock         #指定运行的rsync进程的锁文件存放路径
log file = /var/log/rsyncd.log          #指定运行的rsync进程的日志文件路径
hosts allow = 192.168.0.1               #运行访问的主机地址,如果要放开所有的权限可以用 * 号表示,也可以用网段表示,比如 192.168.0.1/24,同时这个还可以放在模块 rank 那
hosts deny = 192.168.1.1/24             #禁止访问的主机,同时这个还可以放在模块 rank 那   
[rank]                                  #表示一个模块,待会客户端同步的脚本会用到这个
use chroot = yes                         # 当同步的目录中有软连接的时候需要用这个选项忽略软连接,不然会报错。即 use chroot = yes。而不能等于 no
path = /tmp/data/ #同步的路径
ignore errors = yes                                  #忽略一些无关的I/O错误 
read only = false                               #false为关闭,true表示开启。表示只读,不允许上传文件
write only = false                               #不允许下载
list = false                                    #客户请求可以使用模块列表时是否被列出
hosts allow = *
auth users = test                               #自定义连接该模块的用户名,多个用户用逗号分隔
secrets file = /etc/rsync.password              #指定一个包含“用户名:密码”格式的文件

注:一定要确保该服务器的 /tmp/data/ 目录已经创建,不能无法同步数据,其不会自动创建目录

其中 /etc/rsync.password 配置文件如下:

test:12345

客户端 inotify 的安装以及同步脚本

  1. 安装 inotify 软件,好吧,一台我也用 fabric
#!/usr/bin/python env
# -*- coding: UTF-8 -*-

from fabric.api import env
from fabric.api import run
from fabric.api import put
from fabric.api import execute
from fabric.api import roles
from fabric.api import parallel
from fabric.api import cd

env.user = 'username'
env.password = 'password'
env.roledefs = {
    'rsync-client': ['192.168.0.1'],
}

@roles('rsync-client')
def install_rsync():
    run('sudo yum -y install rsync')

@roles('rsync-client')
def down_inotify():
    #run('wget http://cloud.github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz')
     run('wget http://pkgs.fedoraproject.org/repo/pkgs/inotify-tools/inotify-tools-3.14.tar.gz/b43d95a0fa8c45f8bab3aec9672cf30c/')
roles('rsync-client')
def make_install_inotify():
    with cd('inotify-tools-3.14'):
        run('./configure && make')
        run('sudo make install')

@roles('rsync-client')
def tar_inotify():
    run('tar -zxvf inotify-tools-3.14.tar.gz')

@roles('rsync-client')
def copy_rsync_pass_conf():
    run('sudo cp -av /tmp/rsync.password_client /etc/rsync.password') #这个密码文件和服务器端的不一样,该文件中只需要配置一个密码 ‘12345’

@roles('rsync-client')
def change_auth_rsync_pass():
    run('sudo chmod 600 /etc/rsync.password') # 这个必须修改权限为600,不能无法认证





@parallel    
def execute_all():
    execute(install_rsync)
    execute(down_inotify)
    execute(tar_inotify)
    execute(make_install_inotify)
    execute(copy_rsync_pass_conf)
    execute(change_auth_rsync_pass)

以上执行完成后,进行后面的同步脚本编写了,同步脚本的名字为 rsync_inotify.sh

#!/bin/bash
SRC='/tmp/data/'
USER=test
host1=192.168.0.2
host2=192.168.0.3
host3=192.168.0.4
host4=192.168.0.5
host5=192.168.0.6
host6=192.168.0.7
DES_MODEL=rank
/usr/local/bin/inotifywait -mr --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' -e modify,delete,create,attrib ${SRC} |while read DATE TIME DIR FILE
do
        FILECHAGE=${DIR}${FILE}
        /usr/bin/rsync -av --progress --delete  --password-file=/etc/rsync.password $SRC $USER@$host1::$DES_MODEL && echo "At ${TIME} on ${DATE}, file $FILECHAGE was backed up via rsync" >> /var/logs/rsyncd.log
        /usr/bin/rsync -av --progress --delete  --password-file=/etc/rsync.password $SRC $USER@$host2::$DES_MODEL && echo "At ${TIME} on ${DATE}, file $FILECHAGE was backed up via rsync" >> /var/logs/rsyncd.log
        /usr/bin/rsync -av --progress --delete  --password-file=/etc/rsync.password $SRC $USER@$host3::$DES_MODEL && echo "At ${TIME} on ${DATE}, file $FILECHAGE was backed up via rsync" >> /var/logs/rsyncd.log
        /usr/bin/rsync -av --progress --delete  --password-file=/etc/rsync.password $SRC $USER@$host4::$DES_MODEL && echo "At ${TIME} on ${DATE}, file $FILECHAGE was backed up via rsync" >> /var/logs/rsyncd.log
        /usr/bin/rsync -av --progress --delete  --password-file=/etc/rsync.password $SRC $USER@$host5::$DES_MODEL && echo "At ${TIME} on ${DATE}, file $FILECHAGE was backed up via rsync" >> /var/logs/rsyncd.log
        /usr/bin/rsync -av --progress --delete  --password-file=/etc/rsync.password $SRC $USER@$host6::$DES_MODEL && echo "At ${TIME} on ${DATE}, file $FILECHAGE was backed up via rsync" >> /var/logs/rsyncd.log
done

以上脚本对 /tmp/data/ 目录下面的所有数据的 ```mdca`` 进行监听,如果发现有变更,会立即进行同步。

inotify相关参数介绍

脚本中相关参数的解释

  • timefmt -- 指定时间的输出格式。
  • format -- 指定变化文件的详细信息。
  • m -- 监控
  • r -- 递归
  • q -- 静默模式

  • e -- 指定你要同步的事件
    modify 修改
    delete 删除
    create 创建
    attrib 属性

注: 该需求实现参考了 liangxiaowei66 的博客 rsync+inotify实时同步,关于rsync 的参数的详细解释,就不在本文讲了,各位有兴趣可以看 man 手册,或者是该作者的这篇博客

注:如果出现如下错误 name lookup failed for XX.XX.XX.XX: Name or service not known ,这是因为没有在服务器端的 /etc/hosts 文件中配置客户端的 IP 和 主机名,只要配置了 IP 和主机名即可。


yexiaobai
4.8k 声望875 粉丝

就是不告诉你 O(∩_∩)O哈哈~。


引用和评论

0 条评论