linux服務器之間的文件同步;rsync+inotifywait;同步多個目錄


1、雙向同步:unison+inotify

2、單向同步:rsync+inotify

 

 

python版的pyinotify

本文介紹第二種方法:

1、Inotify 是一個 Linux特性,它監控文件系統操作,比如讀取、寫入和創建。Inotify 反應靈敏,用法非常簡單,並且比 cron 任務的繁忙輪詢高效得多。學習如何將 inotify 集成到您的應用程序中,並發現一組可用來進一步自動化系統治理的命令行工具。inotify是一種強大的,細粒度的,異步文件系統時間監控機制,它可以替代crond實現與rsync的觸發式文件同步,從而監控文件系統中添加,刪除,修改,移動等細粒事件,從LINUX 2.6.13起,就已加入了對inotify的支持,所以我們只需要安裝一個第三方軟件inotify-tools即可管理此服務

2、inotify安裝:

官網:http://inotify.aiken.cz/?section=inotify&page=download&lang=en

里面就兩個C語言的頭文件inotify.h和inotify-syscalls.h

linux內核2.6.13以后開始支持這個特性,查看支持情況:[admin@19-56 ~]$ ls -lsart /proc/sys/fs/inotify/

上圖表示是支持的

3、inotify-tools安裝:其實就是inotify的命令行工具包,這樣你就可以通過命令行使用inotify特性

官網:https://github.com/rvoicilas/inotify-tools

https://github.com/rvoicilas/inotify-tools/wiki

inotify-tools is a C library and a set of command-line programs for Linux providing a simple interface to inotify. These programs can be used to monitor and act upon filesystem events.

inotify-tools安裝完成之后會有兩個命令,inotifywait 和 inotifywatch。inotifywait用於等待文件或者文件集上的一個特定事件,可以監控任何文件或者目錄位置,並且可以遞歸地監控整個目錄樹;inotifywatch 用於收集被監控的文件系統統計數據,包括每個inotify事件發生多少次等信息。

源碼安裝:./configure --prefix=/usr && make && su -c 'make install'

yum安裝:yum install -y inotify-tools

4、inotifywait -h查看inotifywait的幫助信息,常用選項(options)

    -r|--recursive     Watch directories recursively. 遞歸查詢目錄

    -m|--monitor      Keep listening for events forever.  Without
                         this option, inotifywait will exit after one
                         event is received. 始終監控

    -q|--quiet         Print less (only print events). 打印較少信息,僅打印監控相關信息

常用事件(Events):

    modify        file or directory contents were written

    create        file or directory created within watched directory

    delete        file or directory deleted within watched directory

 5、rsync -h查看rsync的幫助信息

 -v, --verbose               increase verbosity

 -a, --archive               archive mode; equals -rlptgoD (no -H,-A,-X)

     --delete                delete extraneous files from destination dirs  意思是刪除目的目錄多余源目錄的內容。這樣源目錄和目的目錄的內容才能一致,否則,目的目錄的內容不斷增加。保持兩個目錄同步增加和刪除

 

6、重點來了,配置文件

host ip status kernel bit file
A
192.168.10.220
master x86_64 64 /tmp
B
192.168.10.221
slave x86_64 64 /tmp

注意,不要把容易變化又不是監控目標的東西放到監控目錄里,這樣的話,就不會頻繁產生同步操作。更加需要注意的是,不要把下文的日志記錄放到監控目錄里,這樣就產生了死循環:開始同步,產生日志,日志文件發生變化,繼續同步,再次產生日志,日志文件再次發生變化,再次同步……

一、主服務器A:

建立密碼認證文件

[root@nginx rsync-3.0.9]# cd /usr/local/rsync/
[root@nginx rsync]# echo "rsync-pwd" >/usr/local/rsync/rsync.pwd

其中rsync-pwd可以自己設置密碼,rsync.passwd名字也可以自己設置
[root@nginx rsync]# chmod 600 rsync.passwd

無論是為了安全,還是為了避免出現以下錯誤,密碼文件都需要給600權限

創建rsync復制腳本 此項功能主要是將master端的目錄/tmp里的內容,如果修改了(無論是添加、修改、刪除文件)能夠通過inotify監控到,並通過rsync實時的同步給client的/tmp里,下面是通過shell腳本實現的。

#!/bin/bash 
host=192.168.10.221 #slave地址
src=/tmp/    #被監控目錄
des=web 
user=webuser 
/usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e modify,delete,create,attrib $src \ 
| while read files 
do
/usr/bin/rsync -va --delete --progress --password-file=/usr/local/rsync/rsync.passwd $src $user@$host::$des 
echo "${files} was rsynced" >>/tmp/rsync.log 2>&1 
done

read的用法

如果把rsync.log的放到tmp(備份的目錄)就會發送一直復制的問題,所以建議各位吧rsync的日志放到其他的目錄下(非備份目錄)。
其中host是slave的ip,src是master端要實時監控的目錄,des是認證的模塊名,需要與slave一致,user是建立密碼文件里的認證用戶。
把這個腳本命名為rsync.sh,放到監控的目錄里,比如我的就放到/tmp下面,並給予764權限

[root@nginx tmp]# chmod 764 rsync.sh

然后運行這個腳本

[root@nginx tmp]# sh /tmp/rsync.sh &

請記住,只有在備份服務器client端的rsync安裝並啟動rsync之后,在啟動rsync.sh腳本,否則有時候會滿屏出現:

rsync: failed to connect to 192.168.10.221: Connection refused (111) 
rsync error: error in socket IO (code 10) at clientserver.c(107) [sender=2.6.8] 

我們還可以把rsync.sh腳本加入到開機啟動項里

[root@nginx tmp]# echo "/tmp/rsync.sh" >> /etc/rc.local

二、備份服務器(slave)

建立用戶與密碼認證文件

[root@nginx-backup rsync-3.0.9]# echo "webuser:rsync-pwd" > /usr/local/rsync/rsync.passwd

請記住,在master端建立的密碼文件,只有密碼,沒有用戶名;而在備份服務端slave里建立的密碼文件,用戶名與密碼都有。

[root@nginx-backup rsync]# chmod 600 rsync.passwd 需要給密碼文件600權限

建立rsync配置文件

uid = root 
gid = root 
use chroot = no 
max connections = 10 
strict modes = yes
pid file = /var/run/rsyncd.pid 
lock file = /var/run/rsync.lock 
log file = /var/log/rsyncd.log 
[web] 
path = /tmp/   #同步的目的目錄
comment = web file
ignore errors 
read only = no 
write only = no 
hosts allow = 192.168.10.220 
hosts deny = * 
list = false
uid = root 
gid = root 
auth users = webuser 
secrets file = /usr/local/rsync/rsync.pwd

其中web是master服務端里的認證模塊名稱,需要與主服務器里的一致,以上的配置我的自己服務器里的配置,以供參考。

把配置文件命名為rsync.conf,放到/usr/local/rsync/目錄里

啟動rsync
[root@nginx-backup rsync]# /usr/local/rsync/bin/rsync --daemon --config=/usr/local/rsync/rsync.conf

我們可以把rsync腳本加入到開機啟動項里

[root@nginx-backup rsync]# echo "/usr/local/rsync/bin/rsync --daemon --config=/usr/local/rsync/rsync.conf" >> /etc/rc.local

現在rsync與inotify在master端安裝完成,rsync在備份服務器slave端也安裝完成

 

參考:http://www.showerlee.com/archives/678

http://www.jb51.net/article/57011.htm

 

20181117更新:

注意點:

1、rsync+inotifywait的同步模式是阻塞模式,一定放到后台執行,不要影響其他任務執行

2、rc.local啟動的任務賬號都是root賬號,所以注意對文件的讀寫和執行權限

3、啟動日志:/var/log/boot.log,可以通過這個日志查看rc.local里的開機啟動任務啟動情況,是否有異常

4、只可以同步目錄和目錄下的文件,但是不可以直接同步文件

目的:把服務器A的兩個目錄的所有變化同步到服務器B

先上服務器配置A

rc.local配置:

#!/bin/sh -x
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.
exec 1>/tmp/rc.local.log 2>&1  # send stdout and stderr from rc.local to a log file rc.local的日志默認是在/var/log/boot.log里的,這里把它的日志寫到/tmp/rc.local.log中
set -x  # tell sh to display commands before execution
touch /var/lock/subsys/local          # 作用是確保rc.local不會被執行兩次
/bin/sh /usr/local/rsync/rsyncJobs.sh &    # 這里一定要加 & 符號,因為這個同步任務是個阻塞的任務,讓它在后台執行,這樣可以繼續執行其他開機啟動項
/bin/sh /usr/local/rsync/rsyncNodes.sh &   # 上面加了后台執行符號 &,這個任務才會執行

目錄一的rsyncJobs.sh配置

#!/bin/bash
host=服務器B的IP
srcJobs=/var/lib/jenkins/jobs/  # 被監控的目錄以及遞歸的目錄和文件,但是不可以直接寫某個具體的文件
desJobs=jobs  # 目的
user=webuser  # 下面配置的作用是監控目錄/var/lib/jenkins/jobs/的任何變化,然后同步到目的地
inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e modify,delete,create,attrib $srcJobs \
| while read files
do
sleep 5
rsync -va --delete --progress --password-file=/usr/local/rsync/rsync.pwd $srcJobs $user@$host::$desJobs
echo "${files} was rsynced" >> /tmp/rsyncJobs.log 2>&1  # 把同步文件的簡要信息放在這里,大部分相信信息存在/tmp/rc.local.log里
done

目錄二的rsyncNodes.sh配置:

#!/bin/bash
host=服務器B的IP
srcNodes=/var/lib/jenkins/nodes/
desNodes=nodes
user=webuser
# inotifwait的作用是監控文件的變化,然后通知rsync進行同步工作 inotifywait
-mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e modify,delete,create,attrib $srcNodes \ | while read files do sleep 5 rsync -va --delete --progress --password-file=/usr/local/rsync/rsync.pwd $srcNodes $user@$host::$desNodes # --delete刪除目標文件比源文件多的文件 echo "${files} was rsynced" >> /tmp/rsyncNodes.log 2>&1 done

密碼的rsync.pwd配置:

rsync-pwd  # 只有密碼

 

服務器B配置:

rc.local

#!/bin/sh -x
#
# This script will be executed *after* all the other init scripts.
# You can put your own initialization stuff in here if you don't
# want to do the full Sys V style init stuff.
# 放在rc.local多次執行
touch /var/lock/subsys/local
# 開啟rsync服務進程,等待服務器A發起的同步任務 rsync
--daemon --config=/usr/local/rsync/rsync.conf

rsync.conf配置

uid=admin  # 決定被同步的文件到服務器A上的用戶
gid=admin  # 決定被同步的文件到服務器A上的用戶組
use chroot=no
max connections=10
strict modes=yes
pid file=/usr/local/rsync/rsyncd.pid  # 有的時候啟動不了,是因為kill -9后,pid文件還存在。自動生成
lock file=/usr/local/rsync/rsyncd.lock  # 有的時候新增加的目錄或者修改的配置不生效,是因為這個配置文件沒有更新,可以刪除下,它會自動生成
log file=/usr/local/rsync/rsyncd.log  # 服務器B的rsync服務日志;自動生成
[jobs]  # 目錄一的配置
path=/var/lib/jenkins/jobs/ # 服務器A的目錄一的位置,可以是任意目錄,不需要和服務器A的目錄保持一致
comment=web file
ignore errors
read only=no
write only=no
hosts allow= 服務器A的IP  # 允許連接的IP
hosts deny=*
list=false
uid=admin
gid=admin
auth users=webuser
secrets file=/usr/local/rsync/rsync.pwd
[nodes]  # 目錄二的配置
path=/var/lib/jenkins/nodes/  # 目錄二在服務器B上的位置
comment=web file
ignore errors
read only=no
write only=no
hosts allow=服務器A的IP
hosts deny=*
list=false
uid=admin
gid=admin
auth users=webuser
secrets file=/usr/local/rsync/rsync.pwd

密碼的rsync.pwd的配置

webuser:rsync-pwd  # 用戶名:密碼

 

啟動日志:/var/log/boot.log


rsync -azv --delete --exclude .svn --exclude "compile" --exclude "session_cache" --exclude "web"
/cygdrive/c/www/test/trunk/ username@IP:/home/test/
這里要說的是,同步的時候排除多個文件/文件夾的做法是:
--exclude "文件夾名字(1.唯一的時候,可以直接用文件/文件夾名 2.用絕對路徑)"
以下示例,排除3個文件夾:
--exclude .svn --exclude "compile" --exclude "session_cache"
rsync常用參數:

--delete 刪除目標文件比源文件多余的文件

--exclude 排除文件(文件不會被同步)

下面使用nload -u M觀察到的同步效果圖。使用左右方向鍵可以切換觀察的接口

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM