rsync+inotify資料的實時同步

hx_ky36發表於2024-07-15

一、實時同步技術介紹

1.工作原理:

  • 要利用監控服務(inotify),監控同步資料伺服器目錄中資訊的變化

  • 發現目錄中資料產生變化,就利用rsync服務推送到備份伺服器上

2.inotify

非同步的檔案系統事件監控機制,利用事件驅動機制,而無須透過諸如cron等的輪詢機制來獲取事件,linux核心從2.6.13起支援 inotify,透過inotify可以監控檔案系統中新增、刪除,修改、移動等各種事件

grep -i inotify /boot/config-4.18.0-80.el8.x86_64 
CONFIG_INOTIFY_USER=y

工作原理:

inotify 是 Linux 核心提供的一種檔案系統監控機制,能夠監控檔案系統事件(如檔案或目錄的建立、刪除、修改等)。inotify 可以被應用程式用來監視檔案或目錄的變化,並在這些事件發生時觸發相應的動作。

特點

1)適合於需要快速反應檔案變更的應用場景,如日誌監控、實時資料同步等。
2)可以被用來觸發同步動作,例如當檔案被修改時立即同步到其他位置或系統。
3)實時性高,能夠幾乎立即響應檔案系統的變更。

3.rsync

工作原理

rsync 是一個開源的工具,用於在本地或遠端系統之間同步檔案和目錄。它透過比較源和目標檔案的差異來進行同步,只傳輸需要更新的部分,因此在傳輸大檔案或者已有大量相同資料的檔案時,可以顯著減少傳輸的時間和頻寬消耗。

特點

1)可以使用多種演算法進行檔案傳輸和比較,包括 checksum 演算法,確保資料的完整性。
2)可以透過 SSH 連線進行安全的遠端同步。
3)支援增量同步,只傳輸變更的部分,效率高。

4.Rsync 和 Inotify 實現資料的實時同步具體步驟

使用 Inotify 監控檔案變化:

使用 inotify-tools 工具或者程式設計介面,監控需要同步的源目錄(或檔案)的變化。

響應檔案變化事件:

當檔案發生變化(如建立、修改、刪除)時,Inotify 會觸發相應的事件。

觸發 Rsync 同步操作:

在 Inotify 監聽到檔案變化事件後,觸發相應的指令碼或程式,呼叫 Rsync 命令進行同步操作。Rsync 將檢查源目錄和目標目錄的差異,並只傳輸發生變化的部分。

二.inotify 實時監控

inotify是一個Linux核心提供的檔案系統監控功能,通常是預設包含在大多數Linux發行版的核心中的,並不需要額外下載。它允許應用程式監視檔案系統事件,比如檔案或目錄的建立、刪除、修改等操作。

1.核心支援inotify

Linux支援inotify的核心最小版本為 2.6.13,參看man 7 inotif

[root@localhost ~]# ls -l /proc/sys/fs/inotify/
[root@localhost ~]# cat /proc/sys/fs/inotify/max_queued_events 
[root@localhost ~]# cat /proc/sys/fs/inotify/max_user_instances 
[root@localhost ~]# cat /proc/sys/fs/inotify/max_user_watches 

inotify 核心引數說明:

max_queued_events:inotify 事件佇列最大長度,如值太小會出現 Event Queue Overflow 錯誤,預設值:16384, 生產環境建議調大,比如:327679

max_user_instances:每個使用者建立inotify例項最大值,預設值:128

max_user_watches:可以監視的檔案的總數量(inotifywait 單程序),預設值:8192,建議調大

示例:

max_queued_events:inotify 事件佇列最大長度,如值太小會出現 Event Queue Overflow 錯誤,預設值:16384, 生產環境建議調大,比如:327679

max_user_instances:每個使用者建立inotify例項最大值,預設值:128

max_user_watches:可以監視的檔案的總數量(inotifywait 單程序),預設值:8192,建議調大

[root@localhost ~]# vim /etc/sysctl.conf

fs.inotify.max_queued_events = 66666
fs.inotify.max_user_instances = 128
fs.inotify.max_user_watches = 100000
[root@localhost ~]# sysctl -p
[root@localhost ~]# cat /proc/sys/fs/inotify/*

2.inotify-tools工具

inotify-tools參考文件:Home · inotify-tools/inotify-tools Wiki · GitHub

安裝inotify-tools:基於epel源

[root@data-centos7 ~]# yum -y install inotify-tools

inotify-tools包主要工具:

  • inotifywait: 在被監控的檔案或目錄上等待特定檔案系統事件(open ,close,delete等)發生,常用於實時同步的目錄監控

  • inotifywatch:收集被監控的檔案系統使用的統計資料,指檔案系統事件發生的次數統計

inotifywait命令

inotifywait命令用於監視檔案系統事件,並在事件發生時執行指定的命令。它是Linux系統中的一個工具,特別適用於需要實時響應檔案系統變化的場景。

格式:

inotifywait [ options ] file1 [ file2 ] [ file3 ] [ ... ]

常用選項:

選項解釋
-m, --monitor 始終保持事件監聽
-d, --daemon 以守護程序方式執行,和-m相似,配合-o使用
-r, --recursive 遞迴監控目錄資料資訊變化
-q, --quiet 輸出少量事件資訊
--exclude <pattern> 指定排除檔案或目錄,使用擴充套件的正規表示式匹配的模式實現
--excludei <pattern> 和exclude相似,不區分大小寫
-o, --outfile <file> 列印事件到檔案中,相當於標準正確輸出,注意:使用絕對路徑
-s, --syslogOutput 傳送錯誤到syslog相當於標準錯誤輸出
--timefmt <fmt> 指定時間輸出格式
--format <fmt> 指定的輸出格式;即實際監控輸出內容
-e 指定監聽指定的事件,如果省略,表示所有事件都進行監聽

inotifywait的 --timefmt 時間格式

參考 man 3 strftime

%Y#年份資訊,包含世紀資訊
%y #年份資訊,不包括世紀資訊
%m #顯示月份,範圍 01-12
%d #每月的第幾天,範圍是 01-31
%H #小時資訊,使用 24小時制,範圍 00-23
%M #分鐘,範圍 00-59
%S #秒,範例 0-60

示例:

--timefmt "%Y-%m-%d %H:%M:%S"

inotifywait的 --format 格式定義

%T #輸出時間格式中定義的時間格式資訊,透過 --timefmt option 語法格式指定時間資訊
%w #事件出現時,監控檔案或目錄的名稱資訊,相當於dirname
%f #事件出現時,將顯示監控目錄下觸發事件的檔案或目錄資訊,否則為空,相當於basename
%e #顯示發生的事件資訊,不同的事件預設用逗號分隔
%Xe #顯示發生的事件資訊,不同的事件指定用X進行分隔 x表示分隔符

示例:

--format "%T %w%f event: %;e"
--format '%T %w %f'

inotifywait -e 選項指定的事件型別

create                 #檔案或目錄建立
delete                 #檔案或目錄被刪除
modify                 #檔案或目錄內容被寫入
attrib                 #檔案或目錄屬性改變
close_write         #檔案或目錄關閉,在寫入模式開啟之後關閉的
close_nowrite         #檔案或目錄關閉,在只讀模式開啟之後關閉的
close                #檔案或目錄關閉,不管讀或是寫模式
open                 #檔案或目錄被開啟
lsdir                 #瀏覽目錄內容
moved_to             #檔案或目錄被移動到監控的目錄中
moved_from             #檔案或目錄從監控的目錄中被移動
move                 #檔案或目錄不管移動到或是移出監控目錄都觸發事件
access                 #檔案或目錄內容被讀取
delete_self         #檔案或目錄被刪除,目錄本身被刪除
unmount             #取消掛載

範例:

-e create,delete,moved_to,close_write,attrib

3.實際演示

基礎監聽目錄/data (一次操作監聽)

[root@localhost ~]#inotifywait /data/
#使用  inotifywait  命令監控 
 
開啟另一個終端,新建刪除檔案可以看到變化 ,有操作就會退出
[root@localhost ~]# touch 123

持續監聽 -m

持續監聽/data目錄,執行完一次操作不會主動退出

當在/data目錄下建立一個新的目錄,在新的目錄內進行操作並不會監聽到

遞迴監聽 -r

使用 -r 選項可以遞迴監聽到/data目錄下的子目錄內的操作

持續後臺監控,並記錄日誌

inotifywait -mr /data/ --timefmt "%Y-%m-%d %H:%M:%S" --format "%T %w%f event: %;e" -e create,delete,moved_to,close_write,attrib

三.rsync

rsync 常用於做為 linux系統下的資料映象備份工具,實現遠端同步,支援本地複製,或者與其他SSH、rsync主機同步資料,支援增量備份,配合任務計劃,rsync能實現定時或間隔同步,配合inotify或sersync,可以實現觸發式的實時資料同步

官方網站: rsync

軟體包:rsync,rsync-daemon(CentOS 8)

服務檔案:/usr/lib/systemd/system/rsyncd.service

配置檔案:/etc/rsyncd.conf

埠:873/tcp

格式:

 rsync [OPTION...] SRC... [DEST]

rsync安裝

yum install rsync  -y

1.rsync三種工作方式

  1. 本地檔案系統上實現同步。命令列語法格式為上述"Local"段的格式。
  2. 本地主機使用遠端shell和遠端主機通訊。命令列語法格式為上述"Access via remote shell"段的格式。
  3. 本地主機透過網路套接字連線遠端主機上的rsync daemon。命令列語法格式為上述"Access via rsync daemon"段的格式。

前兩者的本質是透過本地或遠端shell,而第3種方式則是讓遠端主機上執行rsyncd服務,使其監聽在一個埠上,等待客戶端的連線。

2.常用選項

-v:顯示rsync過程中詳細資訊。可以使用"-vvvv"獲取更詳細資訊。
-P:顯示檔案傳輸的進度資訊。(實際上"-P"="--partial --progress",其中的"--progress"才是顯示進度資訊的)。
-n --dry-run :僅測試傳輸,而不實際傳輸。常和"-vvvv"配合使用來檢視rsync是如何工作的。
-a --archive :歸檔模式,表示遞迴傳輸並保持檔案屬性。等同於"-rtopgDl"-r --recursive:遞迴到目錄中去。
-t --times:保持mtime屬性。強烈建議任何時候都加上"-t",否則目標檔案mtime會設定為系統時間,導致下次更新
         :檢查出mtime不同從而導致增量傳輸無效。
-o --owner:保持owner屬性(屬主)。
-g --group:保持group屬性(屬組)。
-p --perms:保持perms屬性(許可權,不包括特殊許可權)。
-D       :是"--device --specials"選項的組合,即也複製裝置檔案和特殊檔案。
-l --links:如果檔案是軟連結檔案,則複製軟連結本身而非軟連結所指向的物件
-z       :傳輸時進行壓縮提高效率
-R --relative:使用相對路徑。意味著將命令列中指定的全路徑而非路徑最尾部的檔名傳送給服務端,包括它們的屬性。用法見下文示例。
--size-only :預設演算法是檢查檔案大小和mtime不同的檔案,使用此選項將只檢查檔案大小。
-u --update :僅在源mtime比目標已存在檔案的mtime新時才複製。注意,該選項是接收端判斷的,不會影響刪除行為。
-d --dirs   :以不遞迴的方式複製目錄本身。預設遞迴時,如果源為"dir1/file1",則不會複製dir1目錄,使用該選項將複製dir1但不複製file1。
--max-size :限制rsync傳輸的最大檔案大小。可以使用單位字尾,還可以是一個小數值(例如:"--max-size=1.5m")
--min-size :限制rsync傳輸的最小檔案大小。這可以用於禁止傳輸小檔案或那些垃圾檔案。
--exclude   :指定排除規則來排除不需要傳輸的檔案。
--delete   :以SRC為主,對DEST進行同步。多則刪之,少則補之。注意"--delete"是在接收端執行的,所以它是在
           :exclude/include規則生效之後才執行的。
-b --backup :對目標上已存在的檔案做一個備份,備份的檔名後預設使用"~"做字尾。
--backup-dir:指定備份檔案的儲存路徑。不指定時預設和待備份檔案儲存在同一目錄下。
-e         :指定所要使用的遠端shell程式,預設為ssh。
--port     :連線daemon時使用的埠號,預設為873埠。
--password-file:daemon模式時的密碼檔案,可以從中讀取密碼實現非互動式。注意,這不是遠端
shell認證的密碼,而是rsync模組認證的密碼。
-W --whole-file:rsync將不再使用增量傳輸,而是全量傳輸。在網路頻寬高於磁碟頻寬時,該選項比增量傳輸更高效。
--existing :要求只更新目標端已存在的檔案,目標端還不存在的檔案不傳輸。注意,使用相對路徑時如果上層目錄不存在也不會傳輸。
--ignore-existing:要求只更新目標端不存在的檔案。和"--existing"結合使用有特殊功能,見下文
示例。
--remove-source-files:要求刪除源端已經成功傳輸的檔案

3.實際演示

開啟rsync同步服務

rsync --daemon
#  開啟rsync 服務  監聽在   873 口上
vim /etc/rsyncd.conf 
ss  -natp |grep rsync

設定配置檔案

192.168.100.155 :客戶端

192.168..100.150 :服務端

# 我們需要在 服務端 設定一個 共享模組  , 並且設定真實路徑 /data/backup/
[backup] path = /data/
#設定好檔案後 可以看到共享目錄

[root@localhost ~]# rsync rsync://192.168.100.150

 #設定可寫(可以上傳)
cat /etc/rsyncd.conf |grep -vE "^#|^$" [backup] path = /data/backup/
read only = no   #可寫

#給服務端資料夾許可權
# 資料夾的許可權沒開 #指定目錄給nobody許可權,預設使用者以nobody訪問此目錄 setfacl
-m u:nobody:rwx /data/backup/ # 給nobody 使用者加許可權 setfacl -b /data/backup/ #清空

#測試:
客戶端 rsync
/etc/passwd rsync://192.168.100.150/backup 或者 rsync /etc/passwd 192.168.100.150::backup

4.實現驗證功能

上述實驗沒有驗證功能不安全

修改配置檔案新增驗證功能等

配置解釋
uid = root 提定以哪個使用者來訪問共享目錄,將之指定為生成的檔案所有者,預設為nobody
gid = root 預設為nobody
port = 874 可指定非標準埠,預設873/tcp
use chroot = no 限制在指定的模組路徑來增強安全性,限制目錄
max connections = 0 最大連線數
ignore errors 忽略錯誤
exclude = lost+found/ 不同步的檔案
log file = /var/log/rsyncd.log 日誌檔案位置
pid file = /var/run/rsyncd.pid pid 檔案位置
lock file = /var/run/rsyncd.lock 鎖檔案如果 max connections 設定為 4,則 rsync 將使用鎖檔案來確保同時只有 4 個連線。
reverse lookup = no 不使用反向解析
hosts allow = 10.0.0.0/24 允許同步的網段
[backup] 每個模組名對應一個不同的path目錄,如果同名後面模組生效
path = /data/backup/ 指明檔案的真實存放路徑
comment = backup dir 備註描述
read only = no 預設是yes,即只讀 no表示可寫
auth users = rsyncuser 驗證預設anonymous可以訪問rsync伺服器 ,修改成rsyncuser 使用者 只有 rsyncuser 可以訪問
secrets file = /etc/rsync.pas 密碼檔案位置

修改配置檔案

服務端
vim /etc/rsyncd.conf
uid
=root gid=root max connections = 0 ignore errors exclude = lost+found/ log file = /var/log/rsyncd.log pid file = /var/run/rsyncd.pid lock file = /var/run/rsyncd.lock reverse lookup = no [backup] path = /data/ read only = no auth users = rsyncuser secrets file = /etc/pass
[root@localhost data]#
echo "rsyncuser:123456" > /etc/pass [root@localhost data]# chmod 600 /etc/pass #必須修改 [root@localhost data]# cat /etc/rsyncd.conf |grep -vE "^#|^$" 客戶端 #客戶端配置密碼檔案 #也可將密碼賦值給環境變數RSYNC_PASSWORD變數,但不安全 [root@localhost ~]# echo "123456" > /etc/pass [root@localhost ~]# chmod 600 /etc/pass

rsync /etc/passwd rsync://rsyncuser@192.168.100.150/backup

#非互動式檢視共享目錄
rsync --password-file=/etc/pass rsync://rsyncuser@192.168.100.150/backup

四.rsync結合inotify +shell指令碼實現實時資料同步

搭建好 rsyncd的備份伺服器,在資料伺服器上建立inotify_rsync.sh指令碼

注意: 此指令碼執行前先確保兩主機初始資料處於同步狀態,此指令碼實現後續的資料同步

vim inotify_rsync.sh

#!/bin/bash SRC='/data/' DEST='rsyncuser@192.168.100.150::backup' inotifywait -mrq --timefmt '%Y-%m-%d %H:%M' --format '%T %w %f' -e attrib,create,delete,moved_to,close_write ${SRC} |while read DATE TIME DIR FILE;do FILEPATH=${DIR}${FILE} rsync -az --delete --password-file=/etc/pass $SRC $DEST && echo "At ${TIME} on ${DATE}, file $FILEPATH was backuped up via rsync" >> /var/log/changelist.log done #檢視檔案傳輸日誌 tail -f /var/log/changelist.log

在資料端上執行指令碼後,在端資料上/data目錄下執行操作

[root@localhost data]# touch 123
[root@localhost data]# mkdir test
[root@localhost data]# cp -r /etc/ .

在備份伺服器上檢視(同步端)

watch  -n0.5  ls /data
#每隔0.5秒執行一次ls /data 命令

#在發起資料伺服器上(發起端)檢視檔案傳輸日誌

tail -f /var/log/changelist.log

相關文章