最近接到一个需求,须要作文件同步,一个程序在某个文件夹下生成数据,其余的几台服务器须要用到这些数据,不肯意弄共享存储服务以及搞NAS什么的,就用 rsync + inotify作下实时同步好了,简单方便,这这篇文章是为了记录下,省得之后有相似需求再忘记。python
需求以下,一共7台服务器,其中一台服务器在某个目录下面生成文件,而后同步到6台服务器上去。
生成文件的服务器为:192.168.0.1
其余六台服务器为:192.168.0.2-7git
在6台被同步的服务器 192.168.0.2-7 上面安装 rsync ,做为懒人,固然不能够一台台服务器登陆去安装了,自动化工具 fabric 派上用场(我前面有讲解 fabric 用法的系列文章)。上代码github
#!/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
的配置文件以下:api
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/
目录已经建立,不能没法同步数据,其不会自动建立目录bash
其中 /etc/rsync.password
配置文件以下:服务器
test:12345
#!/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`` 进行监听,若是发现有变动,会当即进行同步。工具
脚本中相关参数的解释ui
q -- 静默模式3d
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 和主机名便可。