更多技術文章,請關注:github.com/yongxinz/te…html
隨着應用系統規模的不斷擴大,對數據的安全性和可靠性也提出更好的要求,rsync 在高端業務系統中也逐漸暴露出了不少不足。python
首先,rsync 在同步數據時,須要掃描全部文件後進行比對,進行差量傳輸。若是文件數量達到了百萬甚至千萬量級,掃描全部文件將是很是耗時的,而且正在發生變化的每每是其中不多的一部分,這是很是低效的方式。linux
其次,rsync 不能實時的去監測、同步數據,雖然它能夠經過 linux 守護進程的方式進行觸發同步,可是兩次觸發動做必定會有時間差,這樣就致使了服務端和客戶端數據可能出現不一致,沒法在應用故障時徹底的恢復數據。git
基於以上兩種狀況,可使用 rsync+inotify 的組合來解決,能夠實現數據的實時同步。github
inotify 是一種強大的、細粒度的、異步的文件系統事件控制機制。linux 內核從 2.6.13 起,加入了 inotify 支持。經過 inotify 能夠監控文件系統中添加、刪除、修改、移動等各類事件,利用這個內核接口,第三方軟件就能夠監控文件系統下文件的各類變化狀況,而 inotify-tools 正是實施監控的軟件。在使用 rsync 首次全量同步後,結合 inotify 對源目錄進行實時監控,只要有文件變更或新文件產生,就會馬上同步到目標目錄下,很是高效實用。shell
yum -y install rsync
複製代碼
源碼方式安裝這裏不介紹了。安全
-v :展現詳細的同步信息
-a :歸檔模式,至關於 -rlptgoD
-r :遞歸目錄
-l :同步軟鏈接文件
-p :保留權限
-t :將源文件的"modify time"同步到目標機器
-g :保持文件屬組
-o :保持文件屬主
-D :和--devices --specials同樣,保持設備文件和特殊文件
-z :發送數據前,先壓縮再傳輸
-H :保持硬連接
-n :進行試運行,不做任何更改
-P same as --partial --progress
--partial :支持斷點續傳
--progress :展現傳輸的進度
--delete :若是源文件消失,目標文件也會被刪除
--delete-excluded :指定要在目的端刪除的文件
--delete-after :默認狀況下,rsync是先清理目的端的文件再開始數據同步;若是使用此選項,則rsync會先進行數據同步,都完成後再刪除那些須要清理的文件。
--exclude=PATTERN :排除匹配PATTERN的文件
--exclude-from=FILE :若是要排除的文件不少,能夠統一寫在某一文件中
-e ssh :使用SSH加密隧道傳輸
複製代碼
這裏有兩臺 linux 服務器,咱們能夠先假定 A 做爲服務端,B 做爲客戶端。bash
一、服務端配置:服務器
修改服務端的配置文件:/etc/rsyncd.conf
,內容以下:ssh
# rsync 守護進程的用戶
uid = www
# 運行 rsync 守護進程的組
gid = www
# 容許 chroot,提高安全性,客戶端鏈接模塊,首先 chroot 到模塊 path 參數指定的目錄下,chroot 爲 yes 時必須使用 root 權限,且不能備份 path 路徑外的連接文件
use chroot = yes
# 只讀
read only = no
# 只寫
write only = no
# 設定白名單,能夠指定IP段(172.18.50.1/255.255.255.0),各個Ip段用空格分開
hosts allow = 192.168.0.2
hosts deny = *
# 容許的客戶端最大鏈接數
max connections = 4
# 歡迎文件的路徑,非必須
motd file = /etc/rsyncd.motd
# pid文件路徑
pid file = /var/run/rsyncd.pid
# 記錄傳輸文件日誌
transfer logging = yes
# 日誌文件格式
log format = %t %a %m %f %b
# 指定日誌文件
log file = /var/log/rsync.log
# 剔除某些文件或目錄,不一樣步
exclude = lost+found/
# 設置超時時間
timeout = 900
ignore nonreadable = yes
# 設置不須要壓縮的文件
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
# 模塊,能夠配置多個
[sync_file]
# 模塊的根目錄,同步目錄,要注意權限
path = /home/test
# 是否容許列出模塊內容
list = no
# 忽略錯誤
ignore errors
# 添加註釋
comment = ftp export area
# 模塊驗證的用戶名稱,可以使用空格或者逗號隔開多個用戶名
auth users = sync
# 模塊驗證密碼文件 可放在全局配置裏
secrets file = /etc/rsyncd.secrets
複製代碼
編輯 /etc/rsyncd.secrets
文件,內容以下:
### rsyncd.secrets 文件的配置
# 用戶名:密碼
sync:123456
複製代碼
編輯 /etc/rsyncd.motd
文件,內容以下:
### rsyncd.motd 文件配置
++++++++++++++++++
sync zhang : rsync start
++++++++++++++++++
複製代碼
設置文件權限,這一步不能少:
chmod 600 /etc/rsyncd.secrets
複製代碼
啓動:
rsync --daemon --config=/etc/rsyncd.conf
複製代碼
加入開機自啓:
echo 'rsync --daemon --config=/etc/rsyncd.conf' >> /etc/rc.d/rc.local
複製代碼
二、客戶端配置:
建立密碼文件 /etc/rsyncd.pass
,直接寫密碼便可,內容以下:
### rsyncd.pass 文件的配置
123456
複製代碼
設置文件權限,這一步不能少:
chmod 600 /etc/rsyncd.pass
複製代碼
如今就能夠在客戶端執行命令來同步文件了。
從 服務端=>客戶端 同步數據:
rsync -avzP --delete sync@192.168.0.1::sync_file /home/test --password-file=/etc/rsyncd.pass
複製代碼
從 客戶端=>服務端 同步數據:
rsync -avzP --delete /home/test sync@192.168.0.1::sync_file --password-file=/etc/rsyncd.pass
複製代碼
到目前爲止,rsync 就配置完成了,若是想實現雙向同步,只要將 B 配置成服務端,A 配置成客戶端,分別啓對應的服務便可。
接下來介紹 inotify 監控文件變更,來實現實時同步。
yum install -y inotify-tools
複製代碼
一、inotifywait 參數說明:
-m,–monitor:始終保持事件監聽狀態 # 重要參數
-r,–recursive:遞歸查詢目錄 # 重要參數
-q,–quiet:只打印監控事件的信息 # 重要參數
–excludei:排除文件或目錄時,不區分大小寫
-t,–timeout:超時時間
–timefmt:指定時間輸出格式 # 重要參數
–format:指定時間輸出格式 # 重要參數
-e,–event:後面指定刪、增、改等事件 # 重要參數
複製代碼
二、inotifywait events 事件說明:
access:讀取文件或目錄內容
modify:修改文件或目錄內容
attrib:文件或目錄的屬性改變
close_write:修改真實文件內容 # 重要參數
close_nowrite:文件或目錄關閉,在只讀模式打開以後關閉的
close:文件或目錄關閉,無論讀或是寫模式
open:文件或目錄被打開
moved_to:文件或目錄移動到
moved_from:文件或目錄從移動
move:移動文件或目錄移動到監視目錄 # 重要參數
create:在監視目錄下建立文件或目錄 # 重要參數
delete:刪除監視目錄下的文件或目錄 # 重要參數
delete_self:文件或目錄被刪除,目錄自己被刪除
unmount:卸載文件系統
複製代碼
一、建立事件
inotifywait -mrq /data --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e create
複製代碼
二、刪除事件
inotifywait -mrq /data --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e delete
複製代碼
三、修改事件
inotifywait -mrq /data --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e close_write
複製代碼
#!/bin/bash
Path=/home/test
Server=192.168.0.2
User=sync
module=sync_file
monitor() {
/usr/bin/inotifywait -mrq --format '%w%f' -e create,close_write,delete $1 | while read line; do
if [ -f $line ]; then
rsync -avz $line --delete ${User}@${Server}::${module} --password-file=/etc/rsyncd.pass
else
cd $1 &&
rsync -avz ./ --delete ${User}@${Server}::${module} --password-file=/etc/rsyncd.pass
fi
done
}
monitor $Path;
複製代碼
直接將腳本在後臺啓動,就能夠監控文件的變化了,從而實現服務器之間的文件同步。
那麼,若是想同步多個目錄該怎麼辦呢?我能想到的辦法就是寫多個 shell 腳本,每一個腳本負責一個目錄,但總感受這種方法不是很好,你們有何高見?
參考文章:
www.jianshu.com/p/bd3ae9d80…
www.mengzhaoxu.xyz/2018/12/24/…
www.cnblogs.com/bigberg/p/7…
cloud.tencent.com/developer/a…
blog.csdn.net/chenghuikai…
www.devopssec.cn/2018/08/23/…