是透過監測
文件狀態變化 再 更新被動地更動
監測
可以使用inotify-tools
命令
inotify 是kernal function之一
以下軟體可以呼叫inotify功能
inotify-tools 內建
sersync 第三方
lrsyncd 第三方
inotify 監控 rsync 同步 再使用腳本自動化操作
安裝inotify-tools在機器1(被備份端)
sudo yum install inotify-tools -y
安裝完後可以使用rpm -ql inotify-tools查看相關工具
Image Not Showing Possible ReasonsLearn More →
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
inotifywait : 監測檔案或資料夾發生的事件的次數(包括 開啟 關閉 刪除等)
inotifywatch : 統計發生的事件的次數
進階設置
inotify kernal參數 主要有 max_queued_events、max_user_instances、max_user_watches,分別的作用是:
max_queued_events:
作用:這個參數定義了 inotify 事件隊列中可以排隊的最大事件數量。當事件數量達到這個限制時,新的事件會被丟棄並且內核會發出一個溢出(overflow)事件來通知用戶空間程序。
用途:限制事件隊列的大小以防止過多的事件佔用內存,從而保護系統穩定性。
max_user_instances:
作用:這個參數定義了每個用戶可以創建的 inotify 實例的最大數量。一個 inotify 實例是由調用 inotify_init() 系統調用創建的。
用途:限制每個用戶創建的 inotify 實例數量,以防止資源耗盡攻擊(resource exhaustion attacks)。
max_user_watches:
作用:這個參數定義了每個用戶可以監視的文件或目錄的最大數量。每個 inotify 實例可以監視多個文件或目錄,每個監視都佔用一個 watch descriptor。
用途:限制每個用戶能監視的文件或目錄數量,防止單個用戶佔用過多資源,從而影響系統的其他部分或其他用戶。
基本上只需要確保max_queued_events(預設值16384 較小)足夠大以應付同時發生的大量事件和max_user_instances(預設值8192 較小)
可以透過
cat /proc/sys/fs/inotify/參數名稱
查看 設定值
並使用 vim /etc/sysctl.fonf
加上fs.inotify.參數名稱=數值
即可設定
例如fs.inotify.max_user_instances=10000
用法 inotifywait 檔案或資料夾
ex:
inotify /data/www/
Image Not Showing Possible ReasonsLearn More →
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
可以監控到 操作touch a.txt
,但是命令執行完畢後便結束任務 不會持續監控
可以透過 -m 設置成持續監控
圖中呈現了幾種基本操作監控到的事件
inotifywait
常用參數的介紹:
-m
(monitor): 監控目標路徑的變化,持續運行,直到手動終止。-d
(daemonize): 以守護進程方式運行,適合於長期運行的監控任務。-r
(recursive): 遞歸監控目標路徑下的所有子目錄。-q
(quiet): 靜默模式,只輸出變化事件,不顯示啟動和結束信息。--exclude
: 使用正則表達式排除特定文件或目錄(大小寫敏感)。--excludei
: 使用正則表達式排除特定文件或目錄(大小寫不敏感)。-o
(outfile): 將輸出寫入指定文件,而不是標準輸出。-s
(syslog): 將輸出寫入系統日誌,而不是標準輸出。--timefmt
: 指定時間戳格式,配合 --format
使用。--format
: 自定義輸出格式,可以包括時間、事件類型、文件名等。-e
(event): 指定監控的事件類型(如 create、delete、modify 等)。其中 –timefmt 的時間格式 與 –format 的格式如下
–timefmt (時間格式使用 strftime 標準):
–format :
範例:
inotifywait -mr --timefmt "%Y-%m-%d %H:%M:%S" --format "%T%w%f event: %;e" /data/www
但是,並不是所有的事件觸發都需要同步,例如:查看文件 會觸發OPEN但這種事件不需要執行同步(或是說 不需要做任何對應的處理)
所以我們只需要關注以下這些事件即可:
create
:當一個文件或目錄被創建時觸發。delete
:當一個文件或目錄被刪除時觸發。moved_to
:當一個文件或目錄被移動到監控的目錄中時觸發。close_write
:當一個打開用於寫入的文件被關閉時觸發。attrib
:當一個文件或目錄的屬性被修改時觸發。屬性包括權限、擁有者、時間戳等。範例: inotifywait -mrq /data/www --timefmt "%F %H:%M:%S" --format "%T %W%f event: %;e" -e create,delete,moved_to,close_write,attrib
Image Not Showing Possible ReasonsLearn More →
- The image was uploaded to a note which you don't have access to
- The note which the image was originally uploaded to has been deleted
如果想要機器上的資料備份到另一台機器 可以使用rsync
因為 rsync可以進行 增量複製
機器1(左) 機器名稱 data (資料伺服器)
機器2(右) 機器名稱 backup (備份伺服器)
皆已使用ssh無密碼登入
目的是將 機器1 /data/www 的內容 備份到 機器2 /data/backup
[user@backup backup]$ rsync -ac data:/data/www/ .
但是目前存在一些問題
需要備份時都需要執行一次rsync命令 (使用contab)
但是刪除檔案
的動作不會同步 需要加上--delete
參數
可以使用crontab週期性更新 那要如何做到實時同步?
[優化]* * * * * rsync -ac --delete data:/data/www/ /data/backup &> /dev/null
使用排程(crond)設置每分鐘執行一次rsync命令
crontab -e
輸入`* * * * * rsync -ac data:/data/www/ /data/backup
### 排程(crond)
yum install cronie
*: don’t care
分 時 日 月 周
1 * * * * 每小時的第1分鐘
*/1 * * * * 每1分鐘執行一次
*/2 * * * * 每2分鐘執行一次
1 * * * 每小時的第0分鐘
*/1 * * * 每1小時執行一次
/2: 代表每2時間(分、時、日…)執行一次
29 9 15 8 * (8/15 09:29 執行一次)
0 17 10 * * (每個月10日 下午5點整)
0 4 * * 6 (每個星期六 零晨4點整)
1,31 17 10 * * (每個17號 17點 1分、31分都執行一次)
1-10 17 10 * * (每個17號 17點 1分、2分…、10分都執行一次)
0 * * * * (每小時第0分鐘)
0 23-1/2,8 * * * 23,4,3,5,7,8
*/20 6-12 * 12 * 在12月時,6~12小時間 每20分鐘 執行一次
crontab -l: 列出当前用户的定时任务
crontab -r: 删除当前用户的所有定时任务。
使用ssh存取
用法類似 scp
scp [參數] [來源] [目的]
rsync [參數] [來源] [目的]
ex:
push:rsync /home/user/a.txt user@10.0.0.1:/home/user/a.txt
pull: rsync user@10.0.0.1:/home/user/a.txt /home/user/a.txt
使用rsync獨立服務rsync-daemon(port 873/TCP)存取
rsync [參數] [來源] [目的]
ex:
push:
rsync /home/user/a.txt user@10.0.0.1::/home/user/a.txt
rsync /home/user/a.txt rsync://user@10.0.0.1:873 //home/user/a.txt
rsync /home/user/a.txt rsync://user@10.0.0.1 //home/user/a.txt
pull:
rsync user@10.0.0.1::/home/user/a.txt /home/user/a.txt
rsync rsync://user@10.0.0.1:873//home/user/a.txt /home/user/a.txt
pull:
rsync [OPTION] [USER@]HOST::SRC… [DST]
rsync [OPTION] rsync://[USER@]HOST[:POST]/SRC… [DST]
push:
rsync [OPTION] SRC… [USER@]HOST::DST
rsync [OPTION] SRC… rsync://[USER@]HOST[:POST]/DST
rsync獨立服務
情境:
備份伺服器做rsync伺服器端
資料伺服器做rsync客戶端
設置rsync伺服器之前
只需要執行rsync --daemon
就可以成為rsync伺服器端
但需要確保配置檔/etc/rsyncd.conf存在
[共享名稱-自訂]
path=共享位置
範例
[backup]
path=/data/backup
配置檔寫好後 rsync客戶端 可以透過rsync rsync://HOST
查看共享的位置
在配置檔設定後便會出現共享名稱
也可以使用另一種格式 或設置/etc/hosts
為了方便操作(使用systemctl)可以安裝rsync-daemon
yum install rsync-daemon
安裝套件同時也會建立配置檔/etc/rsyncd.conf與service文件
也可以設置成開機啟動systemctl enable --now rsyncd
但內部其其實也是使用rsync –daemon
cat /usr/lib/systemd/system/rsyncd.service
但目前仍然無法存取,因為rsync需要設置共享系統的權限 與 文件系統的權限
前面的backup是HOST 後面的是共享名稱
需要在配置檔中加入read only = no
,才能寫入
預設 read only是 yes
修改完要 重啟服務 systemctl restart rsyncd
接著需要設置文件系統的權限,否則報錯如下圖:
rsync預設是透過nobody用戶進行存取 所以需要讓rsync伺服器端設置對應權限
setfacl -m u:nobody:rwx /data/backup/
測試
rsync client(左): rsync /etc/passwd backup:backup
可以正常存取並且擁有者為nobody
如果以user的身分傳檔案rsync /etc/passed user@192.169.245.149::backup
擁有者也會是nobody
但使用rsync-daemod傳輸資料時預設不需要驗證會有安全性的問題
使用ssh時會需要密碼或預先設置免密碼登入
所以需要啟用驗證功能 (在配置檔新增以下內容)
uid = root # 指定身份驗證通過時共享目錄,將之指定為生成的文件所有者,默認為nobody
gid = root # 提示身份驗證通過時,生成文件的group,默認為nobody
port = 873 # 指定啟動rsync服務時,監聽從哪個端口,默認為873/tcp
#use chroot = no # 默認為yes
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 = 10.0.0.0/24
[backup] # 每個模塊名對應一個不同的path目錄,如果同名後面模塊生效
path = /data/backup/
comment = backup dir
read only = no # 默認為yes,即只讀
auth users = rsyncuser # 默認為匿名用戶可以訪問rsync服務器
secrets file = /etc/rsync.pas
移除註解
uid = root
gid = root
port = 873
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/backup/
comment = backup dir
read only = no
auth users = rsyncuser
secrets file = /etc/rsync.pas
接著,將使用者與密碼user:password
寫入到 /etc/rsync.pas
echo "rsyncuser:0000" > /etc/rsync.pas
為了提高安全性 可將存放密碼的檔案權限設置為600
chmod 600 /etc/rsync.pas
如此一來 登入時就會要求輸入密碼
但為了方便撰寫腳本,可以在client端設定一個密碼檔並以--password-file=密碼檔
避免交互
[root@data-centos8 ~]# vim inotify_rsync.sh
#!/bin/bash
SRC='/data/www/' # 注意最後的/
DEST='rsyncuser@rsync服務器IP::backup'
rpm -q rsync &> /dev/null || yum -y install rsync
inotifywait -mrq --exclude=".*\.swp" --timefmt '%Y-%m-%d %H:%M:%S' --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.pas $SRC $DEST && echo "At ${TIME} on ${DATE}, file ${FILEPATH} was backed up via rsync" >> /var/log/changelist.log
done
執行腳本後
bash aa.sh
rsync server端執行watch -n0.1 ls -l /data/backup
每0.1秒執行一次ls -l /data/backup