1.安裝rsync+inotify
是否支持inotify:
~]# uname -r #2.6.13以上內核版本
3.10.0-957.el7.x86_64
~]# ll /proc/sys/fs/inotify/ #在沒安裝inotify軟件之前,應該有這三個文件
total 0
-rw-r--r-- 1 root root 0 Sep 10 22:38 max_queued_events
-rw-r--r-- 1 root root 0 Sep 10 22:38 max_user_instances
-rw-r--r-- 1 root root 0 Sep 10 22:38 max_user_watches
安裝軟件:
~]# rpm -ivh https://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm
~]# yum install -y inotify-tools # inotify依賴於epel源
~]# yum install -y rsync # 依賴於base源
對rsync和inotify不熟悉的同學可以看看下面兩篇文章:
rsync實現數據同步
inotify異步監控機制
2.實現實時同步
同步應考慮的問題:
- 每個文件都儘量少地產生監控事件,但又不能遺漏事件。
- 讓rsync同步目錄,而不是同步產生事件的單個文件。
- 一次性操作同步目錄下的多個文件會產生多個事件,導致多次觸發rsync。如果能讓一批操作只觸發一次rsync,則會大幅降低資源的消耗。
- rsync同步目錄時,考慮好是否要排除某些文件,是否要加上"–delete"選項等。
- 爲了性能,可以考慮對子目錄、對不同事件單獨設計inotify+rsync腳本。
測試腳本:
我們在 192.168.164.156 這臺測試服務器上的目錄,實時同步到 192.168.164.145 這臺備份服務器上
我們需要監控目錄中的 刪除文件、創建文件、移入文件、移出文件、修改文件 這幾個事件
~]# cat inotify_backup.sh
#!/bin/bash
#author by chuan
WATCH_DIR=/work
BACKUP_IP=192.168.164.145
inotifywait -mrq --timefmt "%y-%m-%d %H:%M:%S" --format "%T %w%f %e" -e delete,close_write,moved_to,moved_from,isdir $WATCH_DIR --exclude=".*.swp" |\
while read line;
do
if echo $line | grep -i -E "delete|moved_from|moved_to";then
echo "$line" >> /var/log/inotify_away.log
fi
rsync -az --delete --exclude="*.swp" --exclude="*.swx" $WATCH_DIR $BACKUP_IP:/tmp
if [ $? -eq 0 ];then
echo "sent $WATCH_DIR success.."
else
echo "sent $WATCH_DIR failed.."
fi
done
~]# chmod a+x inotify_backup.sh
配置免密登錄:
因爲每次rsync同步時,都需要輸入備份服務器的密碼,我們實驗爲了方便添加免密登錄
~]# ssh-keygen -t rsa #一直回車即可,會生成一對密鑰,將公鑰發送給需要登錄的服務器就可以實現免密登錄了
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:luIK3hWF/1okK+WfbtZ6R3eHlx0vWMTKAVIWNg1kpj4 root@localhost.localdomain
The key's randomart image is:
+---[RSA 2048]----+
| .o%= . |
| . B .o o |
| . o . + |
| + . o .. |
| o E . o .=|
| . * * . +.B|
| . + o o. . +o|
| . o o . +o.o . |
| . o .+=o . |
+----[SHA256]-----+
~]# ssh-copy-id 192.168.164.145 #發送公鑰目標服務器,發送時需要輸入一次目標服務器密碼
測試:
我在測試中發現,每有一個文件進行改變,就需要同步一次,當我們拷貝一個目錄 /etc 到監控目錄中,由於拷入了多個文件,rsync被觸發了多次,但其實rsync只要同步一次 /etc 目錄到遠端就足夠了,多餘的rsync操作完全是浪費資源。如果拷入少量文件,其實無所謂,但如果拷入成千上萬個文件,將長時間調用rsync。
改進腳本
~]# cat inotify_backup.sh
#!/bin/bash
WATCH_DIR=/work
BACKUP_IP=192.168.164.145
rsync -az --delete --exclude="*.swp" --exclude="*.swx" $WATCH_DIR $BACKUP_IP:/tmp
inotifywait -mrq --timefmt "%y-%m-%d %H:%M:%S" --format "%T %w%f %e" -e delete,close_write,moved_to,moved_from,isdir $WATCH_DIR --exclude=".*.swp" >>/etc/inotifywait.log &
while true;do
if [ -s "/etc/inotifywait.log" ];then
grep -i -E "delete|moved_from" /etc/inotifywait.log >> /etc/inotify_away.log
rsync -az --delete --exclude="*.swp" --exclude="*.swx" $WATCH_DIR $BACKUP_IP:/tmp
if [ $? -ne 0 ];then
echo "$WATCH_DIR sync to $BACKUP_IP failed at `date +"%F %T"`,please check it by manual" |\
mail -s "inotify+Rsync error has occurred" root@localhost
fi
echo "" > /etc/inotifywait.log
rsync -az --delete --exclude="*.swp" --exclude="*.swx" $WATCH_DIR $BACKUP_IP:/tmp
else
sleep 1
fi
done