最近接到一個需求,須要作文件同步,一個程序在某個文件夾下生成數據,其餘的幾臺服務器須要用到這些數據,不肯意弄共享存儲服務以及搞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 和主機名便可。