rsync + inotify 實現文件實時雙向自動同步


rsync + inotify 實現文件實時雙向自動同步

技術博客: https://github.com/yongxinz/tech-blog

同時,也歡迎關注我的微信公眾號 AlwaysBeta,更多精彩內容等你來。

rsync + inotify 實現文件實時雙向自動同步

簡介

隨著應用系統規模的不斷擴大,對數據的安全性和可靠性也提出更好的要求,rsync 在高端業務系統中也逐漸暴露出了很多不足。

首先,rsync 在同步數據時,需要掃描所有文件後進行比對,進行差量傳輸。如果文件數量達到了百萬甚至千萬量級,掃描所有文件將是非常耗時的,並且正在發生變化的往往是其中很少的一部分,這是非常低效的方式。

其次,rsync 不能實時的去監測、同步數據,雖然它可以通過 linux 守護進程的方式進行觸發同步,但是兩次觸發動作一定會有時間差,這樣就導致了服務端和客戶端數據可能出現不一致,無法在應用故障時完全的恢復數據。

基於以上兩種情況,可以使用 rsync+inotify 的組合來解決,可以實現數據的實時同步。

inotify 是一種強大的、細粒度的、異步的文件系統事件控制機制。linux 內核從 2.6.13 起,加入了 inotify 支持。通過 inotify 可以監控文件系統中添加、刪除、修改、移動等各種事件,利用這個內核接口,第三方軟件就可以監控文件系統下文件的各種變化情況,而 inotify-tools 正是實施監控的軟件。在使用 rsync 首次全量同步後,結合 inotify 對源目錄進行實時監控,只要有文件變動或新文件產生,就會立刻同步到目標目錄下,非常高效實用。

rsync

安裝

<code>yum-yinstallrsync/<code>

源碼方式安裝這裡不介紹了。

常用參數

<code>-v:展示詳細的同步信息-a:歸檔模式,相當於-rlptgoD-r:遞歸目錄-l:同步軟連接文件-p:保留權限-t:將源文件的"modifytime"同步到目標機器-g:保持文件屬組-o:保持文件屬主-D:和--devices--specials一樣,保持設備文件和特殊文件-z:發送數據前,先壓縮再傳輸-H:保持硬鏈接-n:進行試運行,不作任何更改-Psameas--partial--progress--partial:支持斷點續傳--progress:展示傳輸的進度--delete:如果源文件消失,目標文件也會被刪除--delete-excluded:指定要在目的端刪除的文件--delete-after:默認情況下,rsync是先清理目的端的文件再開始數據同步;如果使用此選項,則rsync會先進行數據同步,都完成後再刪除那些需要清理的文件。--exclude=PATTERN:排除匹配PATTERN的文件--exclude-from=FILE:如果要排除的文件很多,可以統一寫在某一文件中-essh:使用SSH加密隧道傳輸/<code>

部署使用

  • 服務器A: 192.168.0.1
  • 服務器B: 192.168.0.2

這裡有兩臺 linux 服務器,我們可以先假定 A 作為服務端,B 作為客戶端。

1、服務端配置:

修改服務端的配置文件:/etc/rsyncd.conf,內容如下:

<code>#rsync守護進程的用戶uid=www#運行rsync守護進程的組gid=www#允許chroot,提升安全性,客戶端連接模塊,首先chroot到模塊path參數指定的目錄下,chroot為yes時必須使用root權限,且不能備份path路徑外的鏈接文件usechroot=yes#只讀readonly=no#只寫writeonly=no#設定白名單,可以指定IP段(172.18.50.1/255.255.255.0),各個Ip段用空格分開hostsallow=192.168.0.2hostsdeny=*#允許的客戶端最大連接數maxconnections=4#歡迎文件的路徑,非必須motdfile=/etc/rsyncd.motd#pid文件路徑pidfile=/var/run/rsyncd.pid#記錄傳輸文件日誌transferlogging=yes#日誌文件格式logformat=%t%a%m%f%b#指定日誌文件logfile=/var/log/rsync.log#剔除某些文件或目錄,不同步exclude=lost+found/#設置超時時間timeout=900ignorenonreadable=yes#設置不需要壓縮的文件dontcompress=*.gz*.tgz*.zip*.z*.Z*.rpm*.deb*.bz2#模塊,可以配置多個[sync_file]#模塊的根目錄,同步目錄,要注意權限path=/home/test#是否允許列出模塊內容list=no#忽略錯誤ignoreerrors#添加註釋comment=ftpexportarea#模塊驗證的用戶名稱,可使用空格或者逗號隔開多個用戶名authusers=sync#模塊驗證密碼文件可放在全局配置裡secretsfile=/etc/rsyncd.secrets/<code>

編輯 /etc/rsyncd.secrets 文件,內容如下:

<code>###rsyncd.secrets文件的配置#用戶名:密碼sync:123456/<code>

編輯 /etc/rsyncd.motd 文件,內容如下:

<code>###rsyncd.motd文件配置++++++++++++++++++synczhang:rsyncstart++++++++++++++++++/<code>

設置文件權限,這一步不能少:

<code>chmod600/etc/rsyncd.secrets/<code> 

啟動:

<code>rsync--daemon--config=/etc/rsyncd.conf/<code>

加入開機自啟:

<code>echo'rsync--daemon--config=/etc/rsyncd.conf'>>/etc/rc.d/rc.local/<code>

2、客戶端配置:

創建密碼文件 /etc/rsyncd.pass,直接寫密碼即可,內容如下:

<code>###rsyncd.pass文件的配置123456/<code>

設置文件權限,這一步不能少:

<code>chmod600/etc/rsyncd.pass/<code>

現在就可以在客戶端執行命令來同步文件了。

從 服務端=>客戶端 同步數據:

<code>[email protected]::sync_file/home/test--password-file=/etc/rsyncd.pass/<code>

從 客戶端=>服務端 同步數據:

<code>rsync-avzP--delete/home/[email protected]::sync_file--password-file=/etc/rsyncd.pass/<code>

到目前為止,rsync 就配置完成了,如果想實現雙向同步,只要將 B 配置成服務端,A 配置成客戶端,分別啟對應的服務即可。

接下來介紹 inotify 監控文件變動,來實現實時同步。

inotify

安裝

<code>yuminstall-yinotify-tools/<code>

常用參數

1、inotifywait 參數說明:

<code>-m,–monitor:始終保持事件監聽狀態#重要參數-r,–recursive:遞歸查詢目錄#重要參數-q,–quiet:只打印監控事件的信息#重要參數–excludei:排除文件或目錄時,不區分大小寫-t,–timeout:超時時間–timefmt:指定時間輸出格式#重要參數–format:指定時間輸出格式#重要參數-e,–event:後面指定刪、增、改等事件#重要參數/<code>

2、inotifywait events 事件說明:

<code>access:讀取文件或目錄內容modify:修改文件或目錄內容attrib:文件或目錄的屬性改變close_write:修改真實文件內容#重要參數close_nowrite:文件或目錄關閉,在只讀模式打開之後關閉的close:文件或目錄關閉,不管讀或是寫模式open:文件或目錄被打開moved_to:文件或目錄移動到moved_from:文件或目錄從移動move:移動文件或目錄移動到監視目錄#重要參數create:在監視目錄下創建文件或目錄#重要參數delete:刪除監視目錄下的文件或目錄#重要參數delete_self:文件或目錄被刪除,目錄本身被刪除unmount:卸載文件系統/<code>

常用命令

1、創建事件

<code>inotifywait-mrq/data--timefmt"%d-%m-%y%H:%M"--format"%T%w%f事件信息:%e"-ecreate/<code>

2、刪除事件

<code>inotifywait-mrq/data--timefmt"%d-%m-%y%H:%M"--format"%T%w%f事件信息:%e"-edelete/<code>

3、修改事件

<code>inotifywait-mrq/data--timefmt"%d-%m-%y%H:%M"--format"%T%w%f事件信息:%e"-eclose_write/<code>

腳本監控

<code>#!/bin/bashPath=/home/testServer=192.168.0.2User=syncmodule=sync_filemonitor(){/usr/bin/inotifywait-mrq--format'%w%f'-ecreate,close_write,delete$1|whilereadline;doif[-f$line];thenrsync-avz$line--delete${User}@${Server}::${module}--password-file=/etc/rsyncd.passelsecd$1&&rsync-avz./--delete${User}@${Server}::${module}--password-file=/etc/rsyncd.passfidone}monitor$Path;/<code>

直接將腳本在後臺啟動,就可以監控文件的變化了,從而實現服務器之間的文件同步。

那麼,如果想同步多個目錄該怎麼辦呢?我能想到的辦法就是寫多個 shell 腳本,每個腳本負責一個目錄,但總感覺這種方法不是很好,大家有何高見?

參考文章:

https://www.jianshu.com/p/bd3ae9d8069c http://www.mengzhaoxu.xyz/2018/12/24/rsync%E5%AE%89%E8%A3%85%E4%B8%8E%E4%BD%BF%E7%94%A8/ https://www.cnblogs.com/bigberg/p/7886486.html https://cloud.tencent.com/developer/article/1008061 https://blog.csdn.net/chenghuikai/article/details/50668805 https://www.devopssec.cn/2018/08/23/%E6%95%B0%E6%8D%AE%E5%90%8C%E6%AD%A5%E5%B7%A5%E5%85%B7-RSYNC%E7%BB%93%E5%90%88INOTIFY-TOOLS%E5%AE%9E%E7%8E%B0%E6%95%B0%E6%8D%AE%E5%AE%9E%E6%97%B6%E5%90%8C%E6%AD%A5/


分享到:


相關文章: