rsync+inotify實現實時同步

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章