天天看點

Rsync+Inotify實時同步環境部署記錄

随着應用系統規模的不斷擴大,對資料的安全性和可靠性也提出的更好的要求,rsync在高端業務系統中也逐漸暴露出了很多不足。

首先,rsync在同步資料時,需要掃描所有檔案後進行比對,進行差量傳輸。如果檔案數量達到了百萬甚至千萬量級,掃描所有檔案将是非常耗時的,并且正在發生變化的往往是其中很少的一部分,這是非常低效的方式。

其次,rsync不能實時的去監測、同步資料,雖然它可以通過linux守護程序的方式進行觸發同步,但是兩次觸發動作一定會有時間差,這樣就導緻了服務端和用戶端資料可能出現不一緻,無法在應用故障時完全的恢複資料。

基于以上兩種情況,可以使用rsync+inotify的組合來解決,可以實作資料的實時同步。

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

在使用rsync首次全量同步後,結合inotify對源目錄進行實時監控,隻有有檔案變動或新檔案産生,就會立刻同步到目标目錄下,非常高效使用!

-----------------------------------------------------------------------------------------------------------

下面分享下我在實際工作中的一個rsync+inotify案例(其實是個網站圖檔備份方案):

需求說明:

分别将

192.168.1.106的/Data/fangfull_upload和/Data/erp_upload

192.168.1.57的/Data/xqsj_upload/和/Data/fanghu_upload_src

192.168.1.139的/Data/Static_img/webroot/ssapp-prod和/usr/local/nginx/html/ssapp.prod

實時同步到

192.168.1.5的/home/backup/image-back目錄下對應的fangfull_upload、erp_upload、xqsj_upload、fanghu_upload_src、ssapp-prod和ssapp.prod目錄。

這樣的話:

(1)192.168.1.106、192.168.1.57、192.168.1.139這三台伺服器是源伺服器,作為rsync的用戶端,部署rsync+inotify。

(2)192.168.1.5是目标伺服器,作為rsync的服務端。隻需要安裝配置rsync即可,不需要安裝inotify。

---------------------------------------------------------------

詳細部署過程,記錄如下:

第一部分:在目标伺服器192.168.1.5上部署rsync服務端。

1)關閉selinux

[root@bastion-IDC ~]# vim /etc/selinux/config

SELINUX=disabled

[root@bastion-IDC ~]# setenforce 0

2)防火牆上允許以上三台源伺服器通路它的22端口和873端口

[root@bastion-IDC ~]# vim /etc/sysconfig/iptables

.......

-A INPUT -s 192.168.1.106 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

-A INPUT -s 192.168.1.57 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

-A INPUT -s 192.168.1.139 -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

-A INPUT -s 192.168.1.106 -m state --state NEW -m tcp -p tcp --dport 873 -j ACCEPT

-A INPUT -s 192.168.1.57 -m state --state NEW -m tcp -p tcp --dport 873 -j ACCEPT

-A INPUT -s 192.168.1.139 -m state --state NEW -m tcp -p tcp --dport 873 -j ACCEPT

[root@bastion-IDC ~]# /etc/init.d/iptables restart

如若hosts.allow裡面做了限制,同樣也要開放以上三台源伺服器的權限

[root@bastion-IDC ~]# vim /etc/hosts.allow

#

# hosts.allow This file contains access rules which are used to

# allow or deny connections to network services that

# either use the tcp_wrappers library or that have been

# started through a tcp_wrappers-enabled xinetd.

# See 'man 5 hosts_options' and 'man 5 hosts_access'

# for information on rule syntax.

# See 'man tcpd' for information on tcp_wrappers

sshd:192.168.1.106,192.168.1.57,192.168.1.139:allow

sshd:all:deny

[root@bastion-IDC ~]# cat /etc/hosts.deny

# hosts.deny This file contains access rules which are used to

# deny connections to network services that either use

# the tcp_wrappers library or that have been

# The rules in this file can also be set up in

# /etc/hosts.allow with a 'deny' option instead.

3)安裝部署rsync服務

注意:CentOS中是以xinetd來管理Rsync服務的

[root@bastion-IDC ~]# yum install rsync xinetd

[root@bastion-IDC ~]# vim /etc/xinetd.d/rsync

.....

disable = no               #由預設的yes改為no,設定開機啟動rsync

啟動xineted服務

[root@bastion-IDC ~]# /etc/init.d/xinetd start

建立/etc/rsyncd.conf檔案,并配置同步政策。添加如下代碼:

[root@bastion-IDC ~]# vim /etc/rsyncd.conf

log file = /var/log/rsyncd.log          #日志檔案位置,啟動rsync後自動産生這個檔案,無需提前建立

pidfile = /var/run/rsyncd.pid           #pid檔案的存放位置

lock file = /var/run/rsync.lock        #支援max connections參數的鎖檔案

secrets file = /etc/rsync.pass         #使用者認證配置檔案,裡面儲存使用者名稱和密碼,後面會建立這個檔案

motd file = /etc/rsyncd.Motd          #rsync啟動時歡迎資訊頁面檔案位置(自己建立這個檔案,内容随便自定義)

[fangfull_upload]                            #自定義名稱

path = /home/backup/image-back/fangfull_upload           #rsync服務端資料目錄路徑,即同步到目标目錄後的存放路徑

comment = fangfull_upload                                             #子產品名稱與[fangfull_upload]自定義名稱相同

uid = nobody                                 #設定rsync運作的uid權限。這個要保證同步到目标目錄後的權限和源目錄一緻,即都是nobody!

gid = nobody                                #設定rsync運作的gid權限。

port=873                                    #預設的rsync端口

use chroot = no                          #預設為true,修改為no或false,增加對目錄檔案軟連接配接的備份

read only = no                            #設定rsync服務端檔案為讀寫權限

list = no                                      #不顯示rsync服務端資源清單

max connections = 200              #最大連接配接數

timeout = 600                           #設定逾時時間

auth users = RSYNC_USER          #執行資料同步的使用者名,需要後面手動設定。可以設定多個,用英文狀态下逗号隔開

hosts allow = 192.168.1.106        #允許進行資料同步的用戶端IP位址,可以設定多個,用英文狀态下逗号隔開

hosts deny = 192.168.1.194       #禁止資料同步的用戶端IP位址,可以設定多個,用英文狀态下逗号隔開(如果沒有禁止,就不用設定這一行)

[erp_upload]

path = /home/backup/image-back/erp_upload

comment = erp_upload

uid = nobody

gid = nobody

port=873

use chroot = no

read only = no

list = no

max connections = 200

timeout = 600

auth users = RSYNC_USER

hosts allow = 192.168.1.106

[xqsj_upload]

path = /home/backup/image-back/xqsj_upload

comment = xqsj_upload

hosts allow = 192.168.1.57

[fanghu_upload_src]

path = /home/backup/image-back/fanghu_upload_src

comment = fanghu_upload_src

[ssapp-prod]

path = /home/backup/image-back/ssapp-prod

comment = ssapp-prod

uid = nginx

gid = nginx

hosts allow = 192.168.1.139

[ssapp.prod]

path = /home/backup/image-back/ssapp.prod

comment = ssapp.prod

uid = nginx

建立使用者認證檔案 (多個子產品用的是這同一個認證檔案)

[root@bastion-IDC ~]# vim /etc/rsync.pass

RSYNC_USER:123456@rsync

設定檔案權限,即rsyncd.conf和rsync.pass認證檔案都是600權限!

[root@bastion-IDC ~]# chmod 600 /etc/rsyncd.conf

[root@bastion-IDC ~]# chmod 600 /etc/rsync.pass

重新開機rsync服務

[root@bastion-IDC ~]# /etc/init.d/xinetd restart

[root@bastion-IDC ~]# lsof -i:873

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

xinetd 22041 root 5u IPv6 3336440 0t0 TCP *:rsync (LISTEN)

4)最後,建立rsync同步過來後的目标目錄

[root@bastion-IDC ~]# cd /home/backup/image-back/

[root@bastion-IDC image-back]# mkdir fangfull_upload erp_upload xqsj_upload fanghu_upload_src ssapp-prod ssapp.prod

[root@bastion-IDC image-back]# ll

total 40

drwxr-xr-x. 8 nobody nobody 4096 Jun 12 17:25 erp_upload

drwxrwxrwx. 584 nobody nobody 20480 Oct 26 13:41 fangfull_upload

drwxr-xr-x. 11 nobody nobody 4096 Oct 26 14:23 fanghu_upload_src

drwxr-xr-x. 10 nginx nginx 4096 Oct 26 13:44 ssapp-prod

drwxr-xr-x. 7 nginx nginx 4096 Oct 24 18:01 ssapp.prod

drwxrwxrwx. 144 nobody nobody 4096 Sep 26 11:25 xqsj_upload

第二部分:在源伺服器192.168.1.106、192.168.1.57、192.168.1.139部署rsync用戶端和inotify監控。

1)三台機器同樣操作

關閉selinux,做為用戶端的rsync可以不用在iptables裡開放873端口

[root@static-img ~]# vim /etc/selinux/config

[root@static-img ~]# setenforce 0

2)三台機器同樣操作

安裝rsync

[root@static-img ~]# yum install rsync xinetd

[root@static-img ~]# vim /etc/xinetd.d/rsync

disable = no                     #由預設的yes改為no,設定開機啟動rsync

啟動rsync服務

[root@static-img ~]# /etc/init.d/xinetd start

[root@static-img ~]# lsof -i:873

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME

xinetd 3268 root 5u IPv4 4139812 0t0 TCP *:rsync (LISTEN)

建立同步的密碼檔案,這個檔案名可以跟服務端的認證檔案不一樣,但是裡面的密碼必須一緻!用于rsync同步指令中。不過,最好兩邊的檔案設定成一樣,便于管理

[root@static-img ~]# vim /etc/rsync.pass

123456@rsync

設定rsync.pass密碼檔案為600權限

[root@static-img ~]# chmod 600 /etc/rsync.pass

3)三台機器同樣操作

檢視伺服器核心是否支援inotify,出現下面的内容,說明伺服器核心支援inotify

[root@static-img ~]# ll /proc/sys/fs/inotify

total 0

-rw-r--r-- 1 root root 0 Oct 26 12:03 max_queued_events

-rw-r--r-- 1 root root 0 Oct 26 12:03 max_user_instances

-rw-r--r-- 1 root root 0 Oct 26 12:03 max_user_watches

注意:Linux下支援inotify的核心最小為2.6.13,可以輸入指令:uname -a檢視核心

CentOS 5.X 核心為2.6.18,預設已經支援inotify

[root@static-img ~]# uname -a

Linux static-img 2.6.32-573.22.1.el6.x86_64 #1 SMP Wed Mar 23 03:35:39 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

下面開始安裝inotify-tools

[root@static-img ~]# yum install make gcc gcc-c++                          #安裝編譯工具

[root@static-img ~]# cd /usr/local/src

[root@static-img src]# wget http://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz

[root@static-img src]# tar zxvf inotify-tools-3.14.tar.gz

[root@static-img src]# cd inotify-tools-3.14

[root@static-img inotify-tools-3.14]# ./configure --prefix=/usr/local/inotify

[root@static-img inotify-tools-3.14]# make && make install

發現已經成功安裝inotify-tools了

[root@static-img inotify-tools-3.14]# ll -d /usr/local/inotify/

drwxr-xr-x 6 root root 4096 Oct 26 12:01 /usr/local/inotify/

設定系統環境變量

[root@static-img ~]# vim /etc/profile

......

export PATH=$PATH:/usr/local/inotify/bin

[root@static-img ~]# source /etc/profile

添加庫檔案

[root@static-img ~]# vim /etc/ld.so.conf

/usr/local/inotify/lib

[root@static-img ~]# ldconfig

修改inotify預設參數(inotify預設核心參數值太小)

檢視系統預設參數值

[root@static-img ~]# sysctl -a | grep max_queued_events

fs.inotify.max_queued_events = 16384

[root@static-img ~]# sysctl -a | grep max_user_watches

fs.inotify.max_user_watches = 8192

[root@static-img ~]# sysctl -a | grep max_user_instances

fs.inotify.max_user_instances = 128

修改參數:

[root@static-img ~]# sysctl -w fs.inotify.max_queued_events="99999999"

[root@static-img ~]# sysctl -w fs.inotify.max_user_watches="99999999"

[root@static-img ~]# sysctl -w fs.inotify.max_user_instances="65535"

參數說明:

max_queued_events:

inotify隊列最大長度,如果值太小,會出現"** Event Queue Overflow **"錯誤,導緻監控檔案不準确

max_user_watches:

要同步的檔案包含多少目錄,可以用:find /Data/xqsj_upload -type d | wc -l 統計這些源目錄下的目錄數,必須保證max_user_watches值大于統計結果(這裡/Data/xqsj_upload為同步的源檔案目錄)

max_user_instances:

每個使用者建立inotify執行個體最大值

4)接着執行同步操作:

分别在三台源伺服器上執行rsync首次全量同步的操作(加--delete參數,保持目标目錄和源目錄下檔案絕對一緻)

-------------------------------------------------------------------------------------------------------------------------------------------------------

在192.168.1.106伺服器上

第一次全量同步:

[root@fangfull_web ~]# rsync -avH --port=873 --progress --delete /Data/fangfull_upload/ [email protected]::fangfull_upload --password-file=/etc/rsync.pass

[root@fangfull_web ~]# rsync -avH --port=873 --progress --delete /Data/erp_upload/ [email protected]::erp_upload --password-file=/etc/rsync.pass

待第一次rsync全量同步完成後,就進行rsync+inotify實時同步腳本操作。

實時同步腳本裡添加的是--delete-before參數,而不是--delete參數(第一次全量同步時rsync用的參數),二者差別:

--delete參數:表示rsync同步前,暴力删除目标目錄中的所有檔案,然後再執行同步操作。

--delete-before參數:表示rsync同步前,會先對目标目錄進行一次掃描檢索,删除目标目錄中對比源目錄的多餘檔案,然後再執行同步操作。顯然比--delete參數安全些。

[root@fangfull_web1 ~]# cd /home/rsync/

[root@fangfull_web1 rsync]# cat rsync_fangfull_upload_inotify.sh

#!/bin/bash

SRCDIR=/Data/fangfull_upload/

USER=RSYNC_USER

IP=192.168.1.5

DESTDIR=fangfull_upload

/usr/local/inotify/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,modify,delete,create,attrib,move $SRCDIR | while read file

do

/usr/bin/rsync -avH --port=873 --progress --delete-before $SRCDIR $USER@$IP::$DESTDIR --password-file=/etc/rsync.pass

echo " ${file} was rsynced" >> /tmp/rsync.log 2>&1

done

[root@fangfull_web1 rsync]# cat rsync_erp_upload_inotify.sh

SRCDIR=/Data/erp_upload/

DESTDIR=erp_upload

然後啟動同步腳本,放在背景執行!

[root@fangfull_web1 rsync]# nohup sh rsync_fangfull_upload_inotify.sh &

[root@fangfull_web1 rsync]# nohup sh rsync_erp_upload_inotify.sh &

檢查下是否腳本啟動成功了

[root@fangfull_web1 rsync]# ps -ef|grep inotify

root 11390 1 0 13:41 ? 00:00:00 sh rsync_erp_upload_inotify.sh

root 11392 11390 0 13:41 ? 00:00:00 sh rsync_erp_upload_inotify.sh

root 11397 1 0 13:41 ? 00:00:00 sh rsync_fangfull_upload_inotify.sh

root 11399 11397 0 13:41 ? 00:00:00 sh rsync_fangfull_upload_inotify.sh

root 21842 11702 0 17:22 pts/0 00:00:00 grep --color=auto inotify

最後進行測試:

比如在源目錄/Data/fangfull_upload中建立一個檔案或目錄,會自動實時同步到目标機器192.168.1.5的目标目錄/home/backup/image-back/fangfull_upload中。

--------------------------------------------------------------------------------------------------------------------------------------------------

在192.168.1.57伺服器上

[root@xqsj_web ~]# rsync -avH --port=873 --progress --delete /Data/xqsj_upload/ [email protected]::xqsj_upload --password-file=/etc/rsync.pass

[root@xqsj_web ~]# rsync -avH --port=873 --progress --delete /Data/fanghu_upload_src/ [email protected]::fanghu_upload_src --password-file=/etc/rsync.pass

rsync+inotify實時同步:

[root@xqsj_web1 ~]# cd /home/rsync/

[root@xqsj_web1 rsync]# cat rsync_xqsj_upload_inotify.sh

SRCDIR=/Data/xqsj_upload/

DESTDIR=xqsj_upload

[root@xqsj_web1 rsync]# cat rsync_fanghu_upload_src_inotify.sh

SRCDIR=/Data/fanghu_upload_src/

DESTDIR=fanghu_upload_src

[root@fangfull_web1 rsync]# nohup sh rsync_xqsj_upload_inotify.sh &

[root@fangfull_web1 rsync]# nohup rsync_fanghu_upload_src_inotify.sh &

比如在源目錄/Data/xqsj_upload中建立一個檔案或目錄,會自動實時同步到目标機器192.168.1.5的目标目錄/home/backup/image-back/xqsj_upload中。

--------------------------------------------

在192.168.1.139伺服器上

[root@static-img ~]# rsync -avH --port=873 --progress --delete /Data/Static_img/webroot/ssapp-prod/ [email protected]::ssapp-prod --password-file=/etc/rsync.pass

[root@static-img ~]# rsync -avH --port=873 --progress --delete /usr/local/nginx/html/ssapp.prod/ [email protected]::ssapp.prod --password-file=/etc/rsync.pass

[root@static-img ~]# cd /home/rsync/

[root@static-img rsync]# cat rsync_ssapp-prod_inotify.sh

SRCDIR=/Data/Static_img/webroot/ssapp-prod/

DESTDIR=ssapp-prod

[root@static-img rsync]# cat rsync_ssapp.prod_inotify.sh

SRCDIR=/usr/local/nginx/html/ssapp.prod/

DESTDIR=ssapp.prod

[root@fangfull_web1 rsync]# nohup sh rsync_ssapp-prod_inotify.sh &

[root@fangfull_web1 rsync]# nohup rsync_ssapp.prod_inotify.sh &

比如在源目錄/Data/Static_img/webroot/ssapp-prod中建立一個檔案或目錄,會自動實時同步到目标機器192.168.1.5的目标目錄/home/backup/image-back/ssapp-prod中。

如果在同步過程中,發現中途報錯!重複執行同步指令一直是報這個錯誤:

rsync error: some files/attrs were not transferred (see previous errors) (code 23) at

main.c(1505)

最後發現原因:

是因為在同步的時候,源目錄下有軟連結檔案!

rsync同步軟連結檔案,應該加參數-l

是以,最好在使用rsync同步指令的時候,後面跟-avpgolr參數組合(将上面的-avH改成-avpgolr)

-a:遞歸

-v:列印詳細過程

-p:保持檔案屬性

-g:檔案所屬組不變

-o:檔案所屬者不變

-l:軟連接配接屬性

-r:同步目錄時的參數

*************** 當你發現自己的才華撐不起野心時,就請安靜下來學習吧!***************