rsync+inotify-tools實現數據實時同步方案

簡介:

rsync數據同步優缺點

 與傳統的cp、tar備份方式相比,rsync具有安全性高、備份迅速、支持增量備份等優點,通過rsync可以解決對實時性要求不高的數據備份需求,例如定期的備份文件服務器數據到遠端服務器,對本地磁盤定期做數據鏡像等。

 隨着應用系統規模的不斷擴大,對數據的安全性和可靠性也提出的更好的要求,rsync在高端業務系統中也逐漸暴露出了很多不足。首先,rsync同步數據時,需要掃描所有文件後進行比對,進行差量傳輸。如果文件數量達到了百萬甚至千萬量級,掃描所有文件將是非常耗時的。而且正在發生變化的往往是其中很少的一部分,這是非常低效的方式。其次,rsync不能實時的去監測、同步數據,雖然它可以通過linux守護進程的方式進行觸發同步,但是兩次觸發動作一定會有時間差,這樣就導致了服務端和客戶端數據可能出現不一致,無法在應用故障時完全的恢復數據。基於以上原因,rsync+inotify組合出現了!

inotify

 inotify是一種強大的、細粒度的、異步的文件系統事件監控機制,linux內核從2.6.13起,加入了inotify支持,通過inotify可以監控文件系統中添加、刪除,修改、移動等各種細微事件,利用這個內核接口,第三方軟件就可以監控文件系統下文件的各種變化情況,而inotify-tools就是這樣的一個第三方軟件。

rsync+inotify-tools實現數據實時同步方案

一、環境準備

操作系統:CentOS release 6.8 (Final) x86_64

服務器IP:

rsync_server(數據源)192.168.0.44
rsync_client(目標端)192.168.0.45

同步目錄:

rsync_server       /app/rsync_server
rsync_client       /app/rsync_client 

二、安裝及配置rsync

客戶端配置(目標端)

1、安裝rsync

# yum -y install rsync xinetd
# cp /etc/xinetd.d/rsync{,.bak}
# vim /etc/xinetd.d/rsync
service rsync
{
        disable = no            #修改爲no
        flags           = IPv6
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/bin/rsync
        server_args     = --daemon
        log_on_failure  += USERID
}
# /etc/init.d/xinetd start 

2、配置rsync

# vim /etc/rsyncd.conf    #創建配置文件

logfile = /var/log/rsyncd.log    #日誌文件位置,啓動rsync後自動產生這個文件,無需提前創建
pidfile = /var/run/rsyncd.pid    #pid文件的存放位置
lockfile = /var/run/rsync.lock   #支持max connections參數的鎖文件
secretsfile = /etc/rsync.pass    #用戶認證配置文件,裏面保存用戶名稱和密碼,後面會創建這個文件
motdfile = /etc/rsyncd.Motd    #rsync啓動時歡迎信息頁面文件位置(文件內容自定義)
[app_rsync_client]   #自定義名稱
path = /app/rsync_client/    #rsync服務端數據目錄路徑
comment = app_rsync_client    #模塊名稱與[app_rsync_client]自定義名稱相同
uid = root    #設置rsync運行權限爲root
gid = root    #設置rsync運行權限爲root
port =873
use chroot = no    #默認爲true,修改爲no,增加對目錄文件軟連接的備份
read only = no    設置rsync服務端文件爲讀寫權限
list = no    #不顯示rsync服務端資源列表
mac connections = 200
timeout = 600
auth users = rsync    #執行數據同步的用戶名,可以設置多個,用英文狀態下逗號隔開
hosts allow = 192.168.0.45   #允許進行數據同步的客戶端IP地址,可以設置多個,用英文狀態下逗號隔開
hosts deny = 192.168.0.46,192.168.0.47    #禁止數據同步的客戶端IP地址,可以設置多個,用英文狀態下逗號隔開,先允許後拒絕

3、配置rsync同步的賬戶密碼

# vim /etc/rsync.pass    #配置文件,添加以下內容
rsync:123456    #格式,用戶名:密碼,可以設置多個,每行一個用戶名:密碼

4、賦權啓動rsync

# chmod 600 /etc/rsyncd.conf 
# chmod 600 /etc/rsync.pass 
# /etc/init.d/xinetd restart

服務端配置(數據源)

1、安裝rsync

# yum install rsync xinetd
# vim /etc/xinetd.d/rsync
service rsync
{
        disable = no    #修改爲no
        flags           = IPv6
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/bin/rsync
        server_args     = --daemon
        log_on_failure  += USERID
}

2、配置rsync同步的賬戶密碼

# vim /etc/passwd.txt
123456

# chmod 600 /etc/passwd.txt

3、測試手動同步

# mkdir -pv /app/rsync_server && touch /app/rsync_server/test.txt
在rsync_server的/app/rsync_server目錄下創建文件test.txt,在rsync_server端運行同步命令同步數據:

rsync -avH --port=873 --progress --delete  /app/rsync_client/ [email protected]::app_rsync_client --password-file=/etc/passwd.txt

註釋:
/app/rsync_server/             #數據源的目錄
-password-file=/etc/passwd.txt #數據源的密碼文件
[email protected]::app_rsync_client #rsync目標端rsync服務端配置的用戶名,app_rsync_client目標端rsync服務端配置的模塊名稱

檢查客戶端rsync_client目錄

# ls /app/rsync_client/
test.txt

三、安裝Inotify-tools實時觸發rsync進行同步

這裏可以參考github上的官方wiki文檔(包含安裝及配置使用示例)
https://github.com/rvoicilas/inotify-tools/wiki

1、下載安裝Inotify-tools

# uname -r        #Linux下支持inotify的內核最小爲2.6.13
2.6.32-642.el6.x86_64

# 安裝前要先下載epel源
# yum install inotify-tools -y

查看其程序是否安裝成功
# rpm -qa inotify-tools
inotify-tools-3.14-1.el6.x86_64

查看程序包含的文件
#rpm -ql inotify-tools
/usr/bin/inotifywait
/usr/bin/inotifywatch
/usr/lib64/libinotifytools.so.0
/usr/lib64/libinotifytools.so.0.4.1
/usr/share/doc/inotify-tools-3.14
/usr/share/doc/inotify-tools-3.14/AUTHORS
/usr/share/doc/inotify-tools-3.14/COPYING
/usr/share/doc/inotify-tools-3.14/ChangeLog
/usr/share/doc/inotify-tools-3.14/NEWS
/usr/share/doc/inotify-tools-3.14/README
/usr/share/man/man1/inotifywait.1.gz
/usr/share/man/man1/inotifywatch.1.gz

2、配置inotify-tools

# sysctl -a|egrep -i "max_queued_events|max_user_watches|max_user_instances"    #修改inotify默認參數(inotify默認內核參數值太小)
fs.inotify.max_user_instances = 128
fs.inotify.max_user_watches = 8192
fs.inotify.max_queued_events = 16384
fs.epoll.max_user_watches = 201420

# vim /etc/sysctl.conf 添加
fs.inotify.max_queued_events = 99999999
fs.inotify.max_user_watches = 99999999
fs.inotify.max_user_instances = 65535

#sysctl  -p   參數立即生效

# cat /proc/sys/fs/inotify/{max_user_instances,max_user_watches,max_queued_events}  #檢查參數是否生效
65535
99999999
99999999

註釋:
    max_queued_events:inotify隊列最大長度,如果值太小,會出現"** Event Queue Overflow **"錯誤,導致監控文件不準確
    max_user_watches:要同步的文件包含多少目錄,可以用:find /app/rsync_server/ -type d | wc -l 統計,必須保證max_user_watches值大於統計結果(這裏/app/rsync_server/爲同步文件目錄)
    max_user_instances:每個用戶創建inotify實例最大值

3、創建實時同步腳本

# vim  /usr/local/inotify/rsync.sh
#!/bin/bash
src_dir="/app/rsync_server/"
dst_dir="app_rsync_client"
exclude_dir="/usr/local/inotify/exclude.list"
rsync_user="rsync"
rsync_passwd="/etc/passwd.txt"
dst_ip="192.168.0.45"
rsync_command(){
                  rsync -avH --port=873 --progress --delete --exclude-from=$exclude_dir $src_dir $rsync_user@$ip::$dst_dir --password-file=$rsync_passwd
}
for ip in $dst_ip;do
     rsync_command
done
    /usr/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,modify,delete,create,attrib,move $src_dir \
| while read file;do
   for ip in $dst_ip;do
       rsync_command
       echo "${file} was rsynced" >> /tmp/rsync.log 2>&1
   done
 done 

註釋:
    src_dir="/app/rsync_server/"    #源服務器同步目錄
    dst_dir="app_rsync_client"    #目標服務器rsync同步目錄模塊名稱
    exclude_dir="/usr/local/inotify/exclude.list"    #不需要同步的目錄,如果有多個,每一行寫一個目錄,使用相對於同步模塊的路徑;
    例如:不需要同步/app/rsync_server/"目錄下的a目錄和b目錄下面的b1目錄,exclude.list文件可以這樣寫
    a/
    b/b1/

    rsync_user="rsync"    #目標服務器rsync同步用戶名
    rsync_passwd="/etc/passwd.txt"    #目標服務器rsync同步用戶的密碼在源服務器的存放路徑
    dst_ip="192.168.0.45"    #目標服務器ip,多個ip用空格分開

##賦權,添加開機啓動

# chmod +x /usr/local/inotify/rsync.sh
# touch /usr/local/inotify/exclude.list
# vim /etc/rc.d/rc.local
nohup /bin/sh /usr/local/inotify/rsync.sh &
# nohup /bin/sh /usr/local/inotify/rsync.sh &

4、測試

在rsync_server(數據源)192.168.0.44的/app/rsync_server創建文件
# cd /app/rsync_server
# touch test{1..9}
# touch test{a..j}
# ls
test1  test2  test3  test4  test5  test6  test7  test8  test9  testa  testb  testc  testd  teste  testf  testg  testh  testi  testj

在rsync_client(目標端)192.168.0.45上查看已經同步
# cd /app/rsync_client
# ls
test1  test2  test3  test4  test5  test6  test7  test8  test9  testa  testb  testc  testd  teste  testf  testg  testh  testi  testj

如果以上測試都通過,說明inotify實時觸發rsync同步腳本運行正常。
至此,Linux下Rsync+Inotify-tools實現數據實時同步完成。如果要雙向同步可以把以上反過來部署一次。

FAQ

Q1:
#rsync -avH --port=873 --progress --delete /app/rsync_client/ [email protected]::app_rsync_client --password-file=/etc/passwd.txt

@ERROR: auth failed on module app_rsync_client
rsync error: error starting client-server protocol (code 5) at main.c(1503) [sender=3.0.6]

A:如果出現這個錯誤,請詳細檢查配置文件是否有誤,建議刪掉無用的註釋

Q2:
#rsync -avH --port=873 --progress --delete /app/rsync_client [email protected]::app_rsync_client --password-file=/etc/passwd.txt

sending incremental file list
rsync: link_stat "/app/rsync_client" failed: No such file or directory (2)

A:檢查客戶端及服務端文件夾是否存在,這裏應該還有一個坑,就是這裏是在服務端(數據源)同步,目錄應該指向“/app/rsync_client”

因此,如果是同步應用程序目錄,建議這裏的源目錄,與目標目錄設置爲同一個。

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