資料的實時同步
在生産環境,有時會需要兩台主機的特定目錄實作實時同步。比如,将NFS共享目錄的資料檔案,自動實時同步到備份的伺服器特定目錄中。
資料的實時同步有兩種方式:
1. 實時同步的技術
1.1 實作方法:
- inotify + rsync 方式實作資料同步
- sersync :金山公司周洋在 inotify 軟體基礎上進行開發的,功能更加強大
1.2 工作原理
- 要利用監控服務(inotify),監控同步資料伺服器目錄中資訊的變化
- 發現目錄中資料産生變化,就利用rsync服務推送到備份伺服器上
1.3 inotify
異步的檔案系統事件監控機制,利用事件驅動機制,而無須通過諸如cron等的輪詢機制來擷取事件,linux核心從2.6.13起支援 inotify,通過inotify可以監控檔案系統中添加、删除,修改、移動等各種事件
2. 實作 inotify
2.1 核心支援
Linux支援inotify的核心最小版本為 2.6.13,參看man 7 inotify
檢視目前核心是否加載inotify:
[[email protected] ~]# grep -i inotify /boot/config-4.18.0-80.el8.x86_64
CONFIG_INOTIFY_USER=y
檢視是否支援:
[[email protected] ~]# ll /proc/sys/fs/inotify/
total 0
-rw-r--r-- 1 root root 0 Dec 23 10:06 max_queued_events
-rw-r--r-- 1 root root 0 Dec 23 10:06 max_user_instances
-rw-r--r-- 1 root root 0 Dec 23 10:06 max_user_watches
2.1.1 inotify核心參數說明:
- max_queued_events:inotify事件隊列最大長度,如值太小會出現 Event Queue Overflow 錯誤,預設值:16384
- max_user_instances:每個使用者建立inotify執行個體最大值,預設值:128
- max_user_watches:可以監視的檔案數量(單程序),預設值:8192
2.2 inotify-tools工具
安裝inotify-tools:基于epel源
2.2.1 inotify-tools包主要工具:
- inotifywait: 在被監控的檔案或目錄上等待特定檔案系統事件(open ,close,delete等)發生,常用于實時同步的目錄監控
- inotifywatch:收集被監控的檔案系統使用的統計資料,指檔案系統事件發生的次數統計
2.2.2 inotifywait 指令常見選項
- -m, --monitor 始終保持事件監聽
- -d, --daemon 以守護程序方式執行,和-m相似,配合-o使用
- -r, --recursive 遞歸監控目錄資料資訊變化
- -q, --quiet 輸出少量事件資訊
- –exclude 指定排除檔案或目錄,使用擴充的正規表達式比對的模式實作
- –excludei 和exclude相似,不區分大小寫
- -o, --outfile 列印事件到檔案中,相當于标準正确輸出,注意:使用絕對路徑
- -s, --syslogOutput 發送錯誤到syslog相當于标準錯誤輸出
- –timefmt 指定時間輸出格式
- –format 指定的輸出格式;即實際監控輸出内容
- -e 指定監聽指定的事件,如果省略,表示所有事件都進行監聽
2.2.3 --timefmt 時間格式
- %Y 年份資訊,包含世紀資訊
- %y 年份資訊,不包括世紀資訊
- %m 顯示月份,範圍 01-12
- %d 每月的第幾天,範圍是 01-31
- %H 小時資訊,使用 24小時制,範圍 00-23
- %M 分鐘,範圍 00-59
範例:
--timefmt "%Y-%m-%d %H:%M"
2.2.4 --format 格式定義
- %T 輸出時間格式中定義的時間格式資訊,通過 --timefmt option 文法格式指定時間資訊
- %w 事件出現時,監控檔案或目錄的名稱資訊
- %f 事件出現時,将顯示監控目錄下觸發事件的檔案或目錄資訊,否則為空
- %e 顯示發生的事件資訊,不同的事件預設用逗号分隔
- %Xe顯示發生的事件資訊,不同的事件指定用X進行分隔
2.2.5 inotifywait -e 選項指定的事件類型
- create 檔案或目錄建立
- delete 檔案或目錄被删除
- modify 檔案或目錄内容被寫入
- attrib 檔案或目錄屬性改變
- close_write 檔案或目錄關閉,在寫入模式打開之後關閉的
- close_nowrite 檔案或目錄關閉,在隻讀模式打開之後關閉的
- close 檔案或目錄關閉,不管讀或是寫模式
- open 檔案或目錄被打開
- moved_to 檔案或目錄被移動到監控的目錄中
- moved_from 檔案或目錄從監控的目錄中被移動
- move 檔案或目錄不管移動到或是移出監控目錄都觸發事件
- access 檔案或目錄内容被讀取
- delete_self 檔案或目錄被删除,目錄本身被删除
- unmount 取消挂載
範例:使用inotifywait
#監控一次性事件
inotifywait /data
#持續前台監控
inotifywait -mrq /data
#持續背景監控,并記錄日志
inotifywait -o /root/inotify.log -drq /data --timefmt "%Y-%m-%d %H:%M" --format "%T %w%f event: %e"
#持續前台監控特定事件
inotifywait -mrq /data --timefmt "%F %H:%M" --format "%T %w%f event: %;e" -e
create,delete,moved_to,close_write,attrib
3. rsync
rsync 常用于做為 linux系統下的資料鏡像備份工具,實作實作遠端同步,支援本地複制,或者與其他SSH、rsync主機同步資料,支援增量備份,配合任務計劃,rsync能實作定時或間隔同步,配合inotify或sersync,可以實作觸發式的實時資料同步
3.1 rsync介紹
- 軟體包:rsync,rsync-daemon(CentOS 8)
- 服務檔案:/usr/lib/systemd/system/rsyncd.service
- 配置檔案:/etc/rsyncd.conf
- 端口:873/tcp
3.2 rsync指令
3.2.1 rsync的三種工作模式
- 本地檔案系統上實作同步。指令行文法格式為上述"Local"段的格式。
- 本地主機使用遠端shell和遠端主機通信。指令行文法格式為上述"Access via remote shell"段的格式。
- 本地主機通過網絡套接字連接配接遠端主機上的rsync daemon。指令行文法格式為上述"Access via rsync daemon"段的格式。
前兩者的本質是通過本地或遠端shell,而第3種方式則是讓遠端主機上運作rsyncd服務,使其監聽在一個端口上,等待用戶端的連接配接。
3.2.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.3 以獨立服務方式運作rsync
#建立rsync伺服器的配置檔案
[[email protected] ~]# vim /etc/rsyncd.conf
uid = root
gid = root
use chroot = no
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
hosts allow = 192.168.38.0/24 #要修改允許通路的ip,不然會報錯
[backup]
path = /backup/
comment = backup
read only = no
auth users = rsyncuser
secrets file = /etc/rsync.pass
#伺服器端準備目錄
[[email protected] ~]# mkdir /backup
#伺服器端生成驗證檔案
[[email protected] ~]# echo "rsyncuser:magedu" > /etc/rsync.pass
[[email protected] ~]# chmod 600 /etc/rsync.pass
#伺服器端啟動rsync服務
[[email protected] ~]# rsync --daemon #可加入/etc/rc.d/rc.local實作開機啟動
[[email protected] ~]# systemctl start rsyncd #CentOS 7 以上版本
#用戶端配置密碼檔案
[[email protected] ~]# echo "magedu" > /etc/rsync.pass
[[email protected] ~]# chmod 600 /etc/rsync.pass
#用戶端測試同步資料
[[email protected] ~]# rsync -avz --delete --password-file=/etc/rsync.pass rsyncus[email protected]::backup
receiving incremental file list
drwxr-xr-x 4,096 2019/12/23 10:46:08 .
-rw-r--r-- 5 2019/12/23 10:46:37 test.txt
sent 20 bytes received 66 bytes 172.00 bytes/sec
total size is 5 speedup is 0.06
3.4 建立inotify_rsync.sh腳本
#!/bin/bash
SRC='/data/'
DEST='[email protected]伺服器IP::backup'
inotifywait -mrq --timefmt '%Y-%m-%d %H:%M' --format '%T %w %f' -e
create,delete,moved_to,close_write,attrib ${SRC} |while read DATE TIME DIR FILE;do
FILEPATH=${DIR}${FILE}
rsync -az --delete --password-file=/etc/rsync.pass $SRC $DEST && echo "At ${TIME} on ${DATE}, file $FILEPATH was backuped up via rsync" >> /var/log/changelist.log
done
3.5 實戰案例:實作基于分布式的LAMP架構,并将NFS實時同步到備份伺服器
上次已經實作基于nfs的lamp架構,現在要增加rsync伺服器,實作nfs伺服器的自動備份
伺服器端是centos7伺服器,用戶端是nfs伺服器
在nfs伺服器(用戶端)上:
#安裝rsync包
[[email protected] ~]# yum install rsync-daemon.noarch -y
[[email protected] ~]# yum install inotify-tools -y
#修改rsync配置檔案
[[email protected] ~]# vim /etc/rsyncd.conf
uid = root
gid = root
use chroot = no
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
hosts allow = 192.168.38.0/24
[backup]
path = /backup/
comment = backup
read only = no
auth users = rsyncuser
secrets file = /etc/rsync.pass
#在伺服器端生成驗證檔案
[[email protected] ~]# echo "rsyncuser:magedu" > /etc/rsync.pass
[[email protected] ~]# chmod 600 /etc/rsync.pass
#啟動用戶端服務
[[email protected] ~]# systemctl enable --now rsyncd
#用戶端配置密碼檔案
[[email protected] data]# echo "magedu" > /etc/rsync.pass
[[email protected] data]# chmod 600 /etc/rsync.pass #此為必要項
#編寫inotify_rsync.sh腳本
[[email protected] ~]# vim inotify_raync.sh
#!/bin/bash
SRC='/data/wordpress'
DEST='[email protected]::backup'
inotifywait -mrq --timefmt '%Y-%m-%d %H:%M' --format '%T %w %f' -e create,delete,moved_to,close_write,attrib ${SRC} | while read DATW TIME DIR FTLE;do
FILEPATH=${DIR}${FILE}
rsync -az --delete --password-file=/etc/rsync.pass $SRC $DEST && echo "At ${TIME} on ${DATE}, file $FILEPATH was backupde up via rsync" >> /var/log/changlist.log
sleep 1m
done
#運作腳本
[[email protected] ~]# chmod +x inotify_raync.sh
[[email protected] ~]# nohup ./inotify_raync.sh &
測試
通路
http://wordpress伺服器ip
,上傳圖檔,檢視是否會自動同步到備份伺服器
未上傳前備份伺服器目錄結構:
[[email protected] ~]# tree /backup/wordpress/
/backup/wordpress/
└── 2019
└── 12
├── e3dc45e4c3110dd6-1.jpg
├── e3dc45e4c3110dd6.jpg
└── timg.jpg
2 directories, 3 files
上傳後目錄結構:
[[email protected] ~]# tree /backup/wordpress/
/backup/wordpress/
└── 2019
└── 12
├── e3dc45e4c3110dd6-1.jpg
├── e3dc45e4c3110dd6.jpg
├── timg.jpg
└── u19673307884292725140fm26gp0.jpg
2 directories, 4 files
檢視nfsinot腳本日志:
[[email protected] ~]# cat /var/log/changlist.log
At 23:14 on , file /data/wordpress/2019/12/ was backupde up via rsync
At 23:14 on , file /data/wordpress/2019/12/ was backupde up via rsync
At 23:14 on , file /data/wordpress/2019/12/ was backupde up via rsync
自動備份成功