Rsync+inotify實時備份數據
rsync在同步數據的時候,需要掃描所有文件后進行對比,然后進行差量傳輸,如果文件達到了百萬或者千萬級別以上是,掃描文件的時間也很長,而如果只有少量的文件變更了,那么此時rsync是非常低效的。所以此時需要一個實時監控文件變化的軟件結合rsync來做實時數據備份。
what's inotify
inotify是一個強大的,細粒度的,異步的文件系統事件監控機制,linux內核從2.6.13開始加了這個功能,可以通過監控文件系統添加,刪除,修改移動等事件,利用這個接口,第三方軟件可以監控文件系統添加,刪除,修改移動等事,inotify-tools就是這樣的一個第三方軟件。
install it
安全前首先確認內核大于2.6.13以上,以下重新編譯內核加入inotify的支持,具體方法請自查。
[root@salt ~]# uname -r
2.6.32-504.el6.x86_64
[root@salt ~]# ll /proc/sys/fs/inotify/
total 0
-rw-r--r-- 1 root root 0 Nov 4 02:53 max_queued_events
-rw-r--r-- 1 root root 0 Nov 4 02:53 max_user_instances
-rw-r--r-- 1 root root 0 Nov 4 02:53 max_user_watches
如果 ll 后顯示有三個,那么說明支持inotify了。
既然系統支持,那么接下來安裝它 。
官網地址是:https://github.com/rvoicilas/inotify-tools
我這里的下載地址是:https://cloud.github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
[root@salt tmp]# tar zxf inotify-tools-3.14.tar.gz
[root@salt tmp]# cd inotify-tools-3.14
[root@salt inotify-tools-3.14]# ./configure --prefix=/usr/local/inotifytools && make && make install [root@salt inotify-tools-3.14]# cd /usr/local/inotifytools/
[root@salt inotifytools]# ls
bin include lib share
[root@salt inotifytools]# ll bin/inotifywa*
-rwxr-xr-x. 1 root root 44319 Nov 4 03:00 bin/inotifywait
-rwxr-xr-x. 1 root root 41425 Nov 4 03:00 bin/inotifywatch
安裝好inotify-tools,會生成inotifywait 或者 inotifywatch 兩個指令,
- inotifywait用于等待文件或者文件集上的特定事件,可以監控任何文件和目錄設置,并且可以遞歸地監控整個目錄樹
- inotifywatch用于收集被監控的文件系統統計數據,包括整個inotify時間發生多少次等信息。
inotify 相關參數
inotify定義了一些接口參數,用來限制inotify消耗kernel memory的大小。由于這些參數都是內存參數,因此根據實際情況調節其大小,下面介紹下這些參數:
- /proc/sys/fs/inotify/max_queued_events 表示調用了inotify_init時分配到inotify_instance中可排隊的event數最大值,超過這值就會被丟棄,但會出發IN_Q_QVRFLOW事件
- /proc/sys/fs/inotify/max_user_instances 表示每一個real_user ID可創建的inotify instances數量上限。
- /proc/sys/fs/inotify/max_user_watches 表示每個inotify 實例相關聯的watchs上限,也就是inotify實例監控最大文件的數量,如果文件數量巨大,這個值也需要調高。如我們修改成8百萬
[root@localhost inotify-tools-3.14]# cat /proc/sys/fs/inotify/max_user_watches
8192
[root@localhost inotify-tools-3.14]# echo "3000000" > /proc/sys/fs/inotify/max_user_watches
[root@localhost inotify-tools-3.14]# cat /proc/sys/fs/inotify/max_user_watches
3000000
inotifywait 相關參數
inotifywait是一個監控等待事件,可以配合shell腳本來使用它,下面說下常用的幾個參數:
- -m (--monitor) 表示處于一直保持時間監聽的狀態
- -r (--recursive) 表示遞歸查詢目錄
- -d (--daemon) 守護進程運行
- -q (--quiet) 表示打印出監控事件
- -c (--event) 通過此參數可以指定要監控的事件,常見的事件有modify,delete,create和attrib等等
man inotifywait可以查詢到更多的參數
公司應用案例:rsync+inotify搭建實時同步系統
網站架構簡單概要
這是一個應用商店業務,前端haproxy負載均衡,中間nginx作為web服務節點,網站數據訪問都到后端存儲節點,后端存儲節點與公司app發布節點通過rsync+inotify進行同步,此時你也許會問了,為什么不直接把APP放在后端存儲節點了呢,我們當時是這樣考慮:
- 存儲節點是有多臺服務器,如果要上傳app的話,就得上傳很多臺服務器,我們通過inotify+rsync就可以上傳到發布機上,自己自動同步到多臺后端存儲服務器了,這樣就實現了上傳到一臺,同步到多臺的效果。
- 服務器都在阿里云,發布機在內網,公司需要訪問的話,直接訪問內部發布機即可,避免訪問阿里云的服務器,占用它的帶寬資源。
所以下面就通過inotify+rsync來實現app文件的自動同步了
環境介紹:
以下為實驗環境,但是其生產情況和這類似。只不過是服務器數量多了幾臺罷了。
- 192.168.141.3 發布機 安裝inotify+rsync
- 192.168.141.4 存儲節點 rsync服務端模式
我們在剛才的操作中,已經在192.168.141.3上的發布機安裝好了rsync+inotify的,192.168.141.4上把rsync配置成服務器模式,發布機配制成客戶端模式,這樣發布機上一有東西都自動同步到存儲節點。
在存儲節點(192.168.141.4)上配置rsync
[root@localhost ~]# useradd store # 往store家目錄下同步數據
[root@localhost ~]# cat /etc/rsyncd.conf
uid = nobody
gid = nobody
use chroot = no
max connections = 10
strict modes = yes
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
[appstore]
path = /home/store
comment = app file
ignore errors
read only = no
write only = no
hosts allow = *
list = false
uid = root
gid = root
auth users = store
secrets file = /etc/server.pass
[root@localhost ~]# cat /etc/server.pass
store:123..aa
[root@localhost ~]# chmod 600 /etc/server.pass
[root@localhost ~]# ll /etc/server.pass
-rw-------. 1 root root 14 Nov 5 01:42 /etc/server.pass # 千萬不要忘記600權限
在發布機(192.168.141.3)上的配置
確保inotify安裝正確后,我們首先手動測試下看rsync能不能夠正常傳輸東西
[root@localhost ~]# rsync -vzrtopg --delete --progress /home/store store@192.168.141.4::appstore
Password:
sending incremental file list
store/
store/.bash_logout18 100% 0.00kB/s 0:00:00 (xfer#1, to-check=7/9)
....一堆東西
顯然,上面的狀態說明rsync正常工作的,接下來寫一個腳本,實現rsync+inotify結合工作
[root@localhost ~]# cat syncapp.sh
#!/bin/bash
node1="192.168.141.4" # 如果有多個服務端,可以node2=xx,node3=xxx,總之自由發揮吧
src=/home/store/ # 確保目錄存在
dst=appstore
user=store
/usr/local/inotifytools/bin/inotifywait -mrq --timefmt '%d/%m/%y %H:%M' --format '%T %w%f%e' -e close_write,delete,create,attrib $src \
| while read file
dorsync -vzrtopg --delete --progress --password-file=/etc/server.pass $src $user@$node1::$dstecho "${file} was rsynced" >> /var/log/rsyncd.log 2&>1
done
腳本相關參數如下:
- --timefmt 指定時間的輸出格式
- --format 指定變化文件的詳細信息
- -e close_write,delete,create,attrib 需要注意的這個close_write,表示等文件寫完以后在觸發rsync同步,
- -e modify,delete,create,attrib
測試是否正常工作
我們在發布機下的/home/store上放一個東西,或者新建一個目錄,刪除一個東西,如果存儲節點能夠自動同步過去,那么就正常了。。。。