rsync+inotify實現數據實時備份
一、rsync簡介
rsync是類unix系統下的數據鏡像備份工具——remote sync。與傳統的cp、tar備份方式相比,rsync具有安全性高、備份迅速、支持增量備份、本地復制,遠程同步等優點,通過rsync可以解決對實時性要求不高的數據備份需求,例如定期的備份文件服務器數據到遠端服務器,對本地磁盤定期做數據鏡像等。
隨著應用系統規模的不斷擴大,對數據的安全性和可靠性也提出的更好的要求,rsync在高端業務系統中也逐漸暴露出了很多不足,首先,rsync同步數據時,需要掃描所有文件後進行比對,進行差量傳輸。如果文件數量達到了百萬甚至千萬量級,掃描所有文件將是非常耗時的。而且正在發生變化的往往是其中很少的一部分,這是非常低效的方式。其次,
二、inotify簡介
Inotify 是一種強大的、細粒度的、異步的文件系統事件監控機制,linux內核從2.6.13起,加入了Inotify支持,通過Inotify可以監控文件系統中添加、刪除,修改、移動等各種細微事件,利用這個內核接口,第三方軟件就可以監控文件系統下文件的各種變化情況,而inotify-tools就是這樣的一個第三方軟件。
在之前章節中,我們講到,rsync可以實現觸發式的文件同步,但是通過crontab守護進程方式進行觸發,同步的數據和實際數據會有差異,而inotify可以監控文件系統的各種變化,當文件有任何變動時,就觸發rsync同步,這樣剛好解決了同步數據的實時性問題。
三、實時同步和定期同步的優缺點
定期同步的優點:可定時備份,節約CPU資源和帶寬資源,
定期同步的不足:執行備份的時間固定,延期明顯,實時性差,當同步源長期不變化時,密集的定期任務是不必要的
實時同步的優點:一旦同步源出現變化,立即啟動備份;只要同步源無變化,則不執行備份。
實時同步的不足:服務器壓力較大時,執行實時備份會增加服務器負載。
四、先使用 rsync實現服務器數據備份
1、安裝前的準備工作
主機名 | 主機IP地址 | 系統版本 | 系統內核版本 |
數據服務器server | 192.168.115.120 | CentOS 7.x | 3.10.0-514.el7.x86_64 |
備份服務器backup | 192.168.115.130 | CentOS 7.x | 3.10.0-514.el7.x86_64 |
(1)兩臺服務器都關閉防火墻和selinux
[root@backup ~]# systemctl stop firewalld
[root@backup ~]# systemctl disable firewalld
[root@backup ~]# sed -i "7s/enforcing/disabled/" /etc/selinux/config
[root@backup ~]# setenforce 0
(2)配置數據服務器IP地址為192.168.115.120,備份服務器IP為192.168.115.130
2、在備份服務器安裝rsync,並創建用戶及模塊目錄並更改其用戶組
[root@backup ~]# yum -y install rsync 數據服務器
[root@backup ~]# useradd rsync -s /sbin/nologin -M
[root@backup ~]# grep rsync /etc/passwd
rsync:x:1000:1000::/home/rsync:/sbin/nologin
[root@backup ~]# mkdir /backup 創建rsync daemon工作模式的模塊目錄
[root@backup ~]# chown rsync.rsync /backup/ 更改模塊目錄的用戶組
[root@backup ~]# ll -d /backup/
drwxr-xr-x 2 rsync rsync 6 3月 4 13:57 /backup/
3、修改rsync daemon配置文件/etc/rsyncd.conf
[root@backup ~]# vim /etc/rsyncd.conf
# /etc/rsyncd: configuration file for rsync daemon mode
# See rsyncd.conf man page for more options.
# configuration example:
uid = rsync 設置rsync運行權限為root
gid = rsync 設置rsync運行權限為root
use chroot = no 修改為no,增加對目錄文件軟連接的備份
read only = no 設置rsync服務端文件為讀寫權限
list = no 不顯示rsync服務端資源列表
max connections = 20 最大連接數
log file = /var/log/rsyncd.log 日誌文件位置
pidfile = /var/run/rsyncd.pid pid文件的存放位置
lock file = /var/run/rsync.lock 支持max connections參數的鎖文件
secrets file = /etc/rsync.passwd 虛擬用戶的密碼文件,後面會創建這個文件
transfer logging = yes 使 rsync 服務器將傳輸操作記錄到傳輸日誌文件
timeout = 600 設置超時時間
ignore nonreadable = yes 指定 rysnc 服務器完全忽略那些用戶沒有訪問權限的文件
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
指定那些在傳輸之前不進行壓縮處理的文件
[backup] 自定義模塊名稱
path = /backup 需要同步的備份目錄
ignore errors 表示出現錯誤忽略錯誤
comment = backup 給模塊指定一個描述
auth users = user1 執行數據同步的用戶名,可以設置多個,用英文逗號隔開
4、創建虛擬用戶認證文件並設置權限
[root@backup ~]# echo "user1:123456" >/etc/rsync.passwd
[root@backup ~]# cat /etc/rsync.passwd
user1:123456 註:user1為虛擬用戶,123456為這個虛擬用戶的密碼
[root@backup ~]# chmod 600 /etc/rsync.passwd
5、啟動rsync服務並查看端口是否開啟
[root@backup ~]# rsync --daemon
[root@backup ~]# netstat -antp|grep 873
tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 12313/rsync
tcp6 0 0 :::873 :::* LISTEN 12313/rsync
6、在數據服務器安裝Rsync客戶端並創建密碼文件
[root@server ~]# yum -y install rsync
[root@server ~]# rpm -q rsync
rsync-3.0.9-18.el7.x86_64
[root@server ~]# echo "123456"> /etc/passwd.txt 註:passwd.txt密碼文件裏只寫密碼即可
[root@server ~]# chmod 600 /etc/passwd.txt
7、在數據服務器上測試能否推送備份成功
[root@server ~]# rsync -avz /server/www/ [email protected]::backup --password-file=/etc/passwd.txt
sending incremental file list
./
1.txt
a.txt
sent 147 bytes received 49 bytes 392.00 bytes/sec
total size is 26 speedup is 0.13
上面推送成功之後,到備份服務器查看是否備份成功
[root@backup ~]# ls /backup/
1.txt a.txt
通過測試發現我們已經可以從數據服務器同步文件到備份服務器了。
五、安裝inotify-tools配合rsync實現數據實時備份
1、查看服務器內核是否支持inotify
[root@server ~]# ll /proc/sys/fs/inotify 出現下面的內容,說明內核支持inotify
-rw-r--r-- 1 root root 0 3月 3 17:48 max_queued_events
-rw-r--r-- 1 root root 0 3月 3 17:48 max_user_instances
-rw-r--r-- 1 root root 0 3月 3 17:48 max_user_watches
備註:Linux下支持inotify的內核最小為2.6.13,可以輸入命令:uname -a查看內核
2、下載源碼包並安裝inotify-tools
[root@server ~]# yum -y install make gcc gcc-c++
[root@server ~]# wget --no-check-certificate https://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
[root@server ~]# tar -xf inotify-tools-3.14.tar.gz
[root@server ~]# cd inotify-tools-3.14
[root@server inotify-tools-3.14]# ./configure --prefix=/usr/local/inotify
[root@server inotify-tools-3.14]# make && make install
3、inotify的inotifywait命令常用參數及可監控的事件
inotifywait命令參數
-m 始終保持事件監聽狀態。
-r 使用遞歸形式監視目錄。
-q 減少冗余信息,只打印監控事件的信息。
-e 指定要監視的事件列表。
--timefmt 是指定時間的輸出格式。
--format 打印使用指定的輸出類似格式字符串。
--excludei 排除文件或目錄時,不區分大小寫。
可監聽的事件 | |
事件 | 描述 |
access | 讀取文件或目錄內容 |
modify | 修改文件或目錄內容 |
attrib | 文件或目錄的屬性改變 |
close_write | 修改真實文件內容 |
move | 移動文件或目錄移動到監視目錄 |
moved_to | 文件或目錄移動到 |
moved_from | 文件或目錄從移動 |
create | 在監視目錄下創建文件或目錄 |
open | 文件或目錄被打開 |
close | 關閉,對文件進行關閉操作。 |
delete | 刪除監視目錄下的文件或目錄 |
unmount | 卸載文件系統 |
4、修改inotify默認參數(inotify默認內核參數值太小)
(1)查看系統默認參數
[root@server ~]# sysctl -a | grep max_queued_events
fs.inotify.max_queued_events = 16384 監控隊列大小,如果值太小,會出錯
[root@server ~]# sysctl -a | grep max_user_watches
fs.inotify.max_user_watches = 8192 同時同一用戶可以監控的目錄數量
[root@server ~]# sysctl -a | grep max_user_instances
fs.inotify.max_user_instances = 128 每個用戶創建inotify實例最大值
(2)修改後的參數(參數可根據需要適當調大)
使用下面的這種方法修改的參數是生效的
[root@server ~]# echo 65535 > /proc/sys/fs/inotify/max_user_instances
[root@server ~]# echo 999999 > /proc/sys/fs/inotify/max_queued_events
[root@server ~]# echo 9 > /proc/sys/fs/inotify/max_user_watches
註意:按照網上說法在/etc/sysctl.conf裏添加或在/usr/lib/sysctl.d/50-default.conf文件添加下面的參數都是無效的。本人親測!
[root@server ~]# vim /etc/sysctl.conf
max_queued_events = 999999
max_user_instances = 65535
max_user_watches = 999999
[root@server ~]# vim /usr/lib/sysctl.d/50-default.conf
max_queued_events = 999999
max_user_instances = 65535
max_user_watches = 999999
5、編寫監控腳本並加載到後臺執行
[root@server ~]# cat inotify.sh
#!/bin/bash
host=192.168.115.130 #備份服務器IP
src=/server/www #數據服務器需要備份的目錄
dst=backup #備份服務器的備份數據目錄
user=user1 #rsync --daemon定義的驗證用戶名
rsync_passfile=/etc/passwd.txt # rsync驗證的密碼文件
inotify_home=/usr/local/inotify #inotify安裝路徑
#判斷上面這些目錄和文件是否全部存在
if [ ! -e "$src" ] || [ ! -e "${rsync_passfile}" ] || [ ! -e "${inotify_home}/bin/inotifywait" ] || [ ! -e "/usr/bin/rsync" ];
then
echo "Please check whether there is a directory or file"
exit 9
fi
#這裏必須要先cd到源目錄,inotify再監聽,./ 才能rsync同步後目錄結構一致
cd ${src}
${inotify_home}/bin/inotifywait -mrq --format '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ./ | while read file
#把監控到有發生更改的"文件路徑列表"循環
do
# 把inotify輸出切割 把事件類型部分賦值給INO_EVENT
INO_EVENT=$(echo $file | awk '{print $1}')
# 把inotify輸出切割 把文件路徑部分賦值給INO_FILE
INO_FILE=$(echo $file | awk '{print $2}')
echo "-------------------------------$(date)------------------------------------"
echo $file
#這裏判斷是否有文件的創建、修改、移動等操作
if [[ $INO_EVENT =~ 'CREATE' ]] || [[ $INO_EVENT =~ 'MODIFY' ]] || [[ $INO_EVENT =~ 'CLOSE_WRITE' ]] || [[ $INO_EVENT =~ 'MOVED_TO' ]]
then
echo 'CREATE or MODIFY or CLOSE_WRITE or MOVED_TO'
#如果有上面的條件則同步文件到目標服務器
rsync -avzcR --password-file=${rsync_passfile} $(dirname ${INO_FILE}) ${user}@${host}::${dst}
fi
#這裏判斷是否有文件的刪除、移動的操作
if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
then
echo 'DELETE or MOVED_FROM'
#如果有上面的條件則同步文件到目標服務器
rsync -avzR --delete --password-file=${rsync_passfile} $(dirname ${INO_FILE}) ${user}@${host}::${dst}
fi
#這裏判斷文件的屬性是否發生改變
if [[ $INO_EVENT =~ 'ATTRIB' ]]
then
echo 'ATTRIB'
if [ ! -d "$INO_FILE" ]
then
#如果有上面的條件則同步文件到目標服務器
rsync -avzcR --password-file=${rsync_passfile} $(dirname ${INO_FILE}) ${user}@${host}::${dst}
fi
fi
done
給腳本授予執行權限並在後臺運行腳本監控
[root@server ~]# chmod +x inotify.sh
[root@server ~]# nohup ./inotify.sh &
[root@server ~]# ps -aux|grep inotify
root 14741 0.0 0.1 113132 1420 pts/2 S 11:23 0:00 /bin/bash ./inotify.sh
root 14742 0.0 0.0 6480 644 pts/2 S 11:23 0:00 /usr/local/inotify/bin/inotifywait -mrq --format %Xe %w%f -e modify,create,delete,attrib,close_write,move ./
root 14743 0.0 0.0 113132 384 pts/2 S 11:23 0:00 /bin/bash ./inotify.sh
6、設置定時任務,防止意外導致無法同步
因為inotify只在啟動時會監控目錄,他沒有啟動期間的文件發生更改,他是不知道的,所以這裏每2個小時做1次全量同步,防止各種意外遺漏,保證目錄一致。
[root@localhost ~]# crontab -e
* */2 * * * rsync -avz --password-file=/etc/passwd.txt /server/www/ [email protected]::backup
7、 實時同步測試
(1)在數據服務器端創建文件,看是否能夠同步備份
在數據服務器創建文件並查看
[root@server ~]# touch /server/www/{1..5}.txt
[root@server ~]# ls /server/www/
1.txt 2.txt 3.txt 4.txt 5.txt
在備份服務器查看是否同步備份
[root@backup ~]# ls /backup/
1.txt 2.txt 3.txt 4.txt 5.txt
(2)在數據服務器端刪除文件,看是否能夠同步刪除
在數據服務器刪除文件並查看
[root@server ~]# rm -f /server/www/1.txt /server/www/2.txt
[root@server ~]# ls /server/www/
3.txt 4.txt 5.txt
在備份服務器查看是否同步刪除
[root@backup ~]# ls /backup/
3.txt 4.txt 5.txt
(3)在數據服務器端修改文件內容,看是否能夠同步內容
在數據服務器修改文件內容並查看
[root@server ~]# echo -e "33333333333\n444444444444">/server/www/3.txt
[root@server ~]# cat /server/www/3.txt
33333333333
444444444444
在備份服務器查看文件內容是否同步
[root@backup ~]# cat /backup/3.txt
33333333333
444444444444
(4)修改文件權限看能否同步
在數據服務器修改文件權限並查看
[root@server ~]# ls -l /server/www/
-rw-r--r-- 1 root root 25 3月 5 11:37 3.txt
-rw-r--r-- 1 root root 0 3月 5 11:28 4.txt
-rw-r--r-- 1 root root 0 3月 5 11:28 5.txt
[root@server ~]# chmod 755 /server/www/*
[root@server ~]# ls -l /server/www/
-rwxr-xr-x 1 root root 25 3月 5 11:37 3.txt
-rwxr-xr-x 1 root root 0 3月 5 11:28 4.txt
-rwxr-xr-x 1 root root 0 3月 5 11:28 5.txt
在備份服務器查看文件權限是否同步
[root@backup ~]# ls -l /backup/
-rwxr-xr-x 1 rsync rsync 25 3月 5 11:37 3.txt
-rwxr-xr-x 1 rsync rsync 0 3月 5 11:28 4.txt
-rwxr-xr-x 1 rsync rsync 0 3月 5 11:28 5.txt
以上所有的測試做完之後,發現都可以同步,說明我們的rsync+inotify實現數據實時備份已經配置完成了
rsync+inotify實現數據實時備份