Linux運維:rsync+inotify實時同步

數據實時同步

在生產中有一種需求是,當目錄下的文件數據發生變化時,就將數據備份到備份服務器上。實現這樣的需求須要作到如下兩點:html

  • 利用監控服務(inotify),監控到要同步服務器的目錄文件的變化
  • 發現目錄數據發生變化就利用rsync服務將數據發送到備份服務器

所以,利用rsync+inotify可實現數據的實時同步。linux

Inotify介紹

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

Inotify實際是一種事件驅動機制,它爲應用程序監控文件系統事件提供了實時響應事件的機制,而無須經過諸如cron等的輪詢機制來獲取事件。cron等機制不只沒法作到實時性,並且消耗大量系統資源。相比之下,inotify基於事件驅動,能夠作到對事件處理的實時響應,也沒有輪詢形成的系統資源消耗,是很是天然的事件通知接口,也與天然世界事件機制相符合。github

Inotify安裝

環境介紹web

[root@moli-linux03 ~] uname -r
3.10.0-862.2.3.el7.x86_64
[root@moli-linux03 ~] cat /etc/redhat-release 
CentOS Linux release 7.5.1804 (Core)

安裝前提
須要2.6.13之後內核版本才能支持inotify軟件。2.6.13內核以後版本,在沒有安裝inotify軟件以前,應該有這三個文件。算法

[root@moli-linux03 ~] ll /proc/sys/fs/inotify/
總用量 0
-rw-r--r--. 1 root root 0 2月   3 12:24 max_queued_events
-rw-r--r--. 1 root root 0 2月   3 12:24 max_user_instances
-rw-r--r--. 1 root root 0 2月   3 12:24 max_user_watches
[root@moli-linux03 ~]

三個文件的說明shell

文件 默認值 做用說明
max_user_watches 8192 設置inotifywait或inotifywatch命令能夠監視的文件數量(單進程)
max_user_instances 128 設置每一個用戶能夠運行的inotifywait或inotifywatch命令的進程數
max_queued_events 16384 設置inotify實例事件(event)隊列可容納的事件數量

注:能夠將三個文件的數值調大,監聽更大的範圍vim

安裝方式
可選擇yum安裝或者編譯安裝,yum安裝須要配置有epel源,編譯安裝須要到github下載源碼包。
yum安裝安全

yum install -y inotify-tools

編譯安裝(源碼包地址:https://github.com/rvoicilas/...bash

tar -zxf  tar -zxf inotify-tools-3.13.tar.gz 
./configure
make
make install

inotify主要安裝的兩個軟件
inotifywait: (主要)
  在被監控的文件或目錄上等待特定文件系統事件(open close delete等)發生,執行後處於阻塞狀態,適合在shell腳本中使用
inotifywatch
  收集被監控的文件系統使用的統計數據,指文件系統事件發生的次數統計。
  說明:在實時實時同步的時候,主要是利用inotifywait對目錄進行監控

inotifywait重要命令參數說明

參數 說明
-m 始終保持事件監聽
-r 遞歸監控目錄數據信息變化
-q 輸出信息少(只打印事件信息)
-timefmt 指定時間輸出格式
-format 打印使用指定的輸出相似格式字符串;即實際監控輸出內容
-e 指定監聽指定的事件,若是省略,表示全部事件都進行監聽

-e[參數] 能夠指定的事件類型

事件名稱 說明
close_write 文件或目錄關閉,在寫入模式打開以後關閉的。
move 文件或目錄無論移動到或是移出監控目錄都觸發事件
create 文件或目錄建立在監控目錄中
delete 文件或目錄被刪除在監控目錄中

示例測試
對一個服務器打開兩個終端窗口,終端1執行建立,刪除,修改,移動文件等操做,終端2執行inotifywait命令。
建立事件

[root@終端2 ~] inotifywait -mrq  /root/rsync_test --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e create
[root@終端1 rsync_test]# touch 1.txt
下面顯示出事件信息,在終端一執行建立文件操做以後終端二才顯示的事件
03-02-19 12:48 /root/rsync_test/1.txt 事件信息: CREATE

刪除事件

[root@moli_linux1 ~]#  inotifywait -mrq  /data --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e delete
[root@moli_data ~]# rm -f 1.txt

修改事件

[root@moli_linux1 ~]# inotifywait -mrq  /data --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e close_write
[root@moli_data ~]# echo "hahaha"  > 2 .txt

移動事件move_to
把其餘目錄文件移動到監控目錄

[root@moli_linux1 ~]#  inotifywait -mrq  /data --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e moved_to
[root@moli_data ~]# mv /etc/passwd .

移動事件move_from
把監控目錄文件移到其餘目錄

[root@moli_linux1 ~]# inotifywait -mrq  /data --timefmt "%d-%m-%y %H:%M" --format "%T %w%f 事件信息: %e" -e moved_from
[root@moli_data ~]# mv 2.txt /tmp

inotifywait --timefmt時間參數說明

命令參數 說明
%y 年份信息,顯示信息爲十進制,而且沒有世紀信息
%m 顯示月份,顯示信息爲十進制(範圍 01-12 )
%d 每個月的第幾天,顯示倍息爲十進制數(範圍是 01-31 )
%H 小時信息,顯示信息爲十進制,使用 24小時制(範圍 00-23 )
%M 顯示分鐘,顯示信息爲十進制(範圍 00-59 )

inotifywait --format參數說明

命令參數 說明
%w 事件出現時,監控文件或目錄的名稱信息
%f 事件出現時,將顯示監控目錄下觸發事件的文件或目錄信息,不然爲空
%e 顯示發生的事件信息,不一樣的事件信息用逗號進行分隔
%T 輸出時間格式中定義的時間格式信息,經過 --timefmt option 語法格式指定時間信息這個格式是經過strftime函數進行匹配時間格式信息的

Linux文件同步工具rsync

介紹

rsync是一款開源,快速,多功能的可實現增量的本地或遠程的數據鏡像同步備份的優秀工具。適用於多個平臺。從軟件名稱能夠看出來是遠程同步的意思(remote sync)。可以使本地主機不一樣分區或目錄之間及本地和遠程兩臺主機之間的數據快速同步鏡像,遠程備份等功能。

在同步備份時,默認狀況下,rsync經過其獨特的「quick check」算法,僅同步大小或者最後修改時間發生變化的文件或目錄(也可根據權限,屬主等變化同步,須要制定參數)。甚至是隻同步一個文件裏變化的內容部分,因此能夠實現快速的同步數據的功能。

提示:傳統的cp,scp工具拷貝每次均爲完整拷貝,而rsync除了完整拷貝,還具有增量拷貝的功能,所以今後性能及效率上更勝一籌。

Rsync的特性
1)支持拷貝特殊文件如連接,設備等
2)能夠有排除指定文件或目錄同步的功能,至關於打包命令tar
3)能夠保持原來文件或目錄的權限,時間,軟硬連接等全部屬性均不改變。
4)可實現增量同步,即只同步發生變化的數據,所以數據傳輸效率更高
5)可使用rcp,rsh,ssh等方式來配合傳輸文件,也能夠經過直接的socker連接
6)支持匿名的或認證的進程模式傳輸,方便進行數據備份及鏡像。

核心算法介紹
假定在名爲α和β的兩臺計算機之間同步類似的文件 A 與 B ,其中α對文件 A 擁有訪問權,β對文件 B 擁有訪問權。而且假定主機α與β之間的網絡帶寬很小。那麼 rsync 算法將經過下面的五個步驟來完成:

  1. β將文件 B 分割成一組不重疊的固定大小爲 S 字節的數據塊。最後一塊可能會比 S 小。
  2. β對每個分割好的數據塊執行兩種校驗:一種是 32 位的滾動弱校驗,另外一種是 128 位的 MD4 強校驗。
  3. β將這些校驗結果發給α。
  4. α經過搜索文件 A 的全部大小爲 S 的數據塊 ( 偏移量能夠任選,不必定非要是 S 的倍數 ) ,來尋找與文件 B 的某一塊有着相同的弱校驗碼和強校驗碼的數據塊。這項工做能夠藉助滾動校驗的特性很快完成。
  5. α發給β一串指令來生成文件 A 在β上的備份。這裏的每一條指令要麼是對文件 B 經擁有某一個數據塊而不須重傳的證實,要麼是一個數據塊,這個數據塊確定是沒有與文件 B 的任何一個數據塊匹配上的。

結論:rsync就是會同步咱們指定的兩端目錄之間的數據,這個數據能夠是特殊的數據。同步以前就先進行兩端的數據的比對,只會同步二者之間不一樣的部分,並保留文件本來的屬性。而且支持匿名的方式進行同步傳輸。因此rsync在備份,同步上就會較爲快速。
rsync命令經常使用選項

選項 說明
-a(重要) 包含-rtplgoD選項
-r(重要) 同步目錄時要加上,相似cp命令的-r選項
-v(重要) 同步時顯示一些信息,讓咱們知道同步的過程
-l 保留軟連接
-L 同步軟連接時會把源文件給同步
-p 保持文件的權限屬性
-o 保持文件的屬主
-g 保持文件的屬組
-D 保持設備文件信息
-t 保持文件的時間屬性
--delete 刪除DEST中SRC沒有的文件
--exclude 過濾指定文件,如--exclude "logs" 會把文件名包含logs的文件或者目錄過濾掉,不一樣步
-p 顯示同步過程,好比速率,比-v更加詳細
-u 若是DEST中的文件比SRC新,就不會同步
-z 傳輸時壓縮

rsync的簡單示例

示例1 將目錄下1.txt拷貝到本目錄下的2.txt
在本地裏使用rsync就相似於cp命令,rsync == cp

[root@moli-linux03 rsync_test]# ls
1.txt
[root@moli-linux03 rsync_test]# rsync -av 1.txt 2.txt
sending incremental file list
1.txt

sent 87 bytes  received 35 bytes  244.00 bytes/sec
total size is 0  speedup is 0.00
[root@moli-linux03 rsync_test]# ls
1.txt  2.txt

示例2 把/etc/passwd文件拷貝到遠程主機的/tmp目錄下,並更名叫1.txt

rsync -av /etc/passwd root@192.168.199.7:/tmp/1.txt

示例3 經過ssh同步,指定端口號
rsync == scp

rsync -av -e "ssh -p 22" /etc/passwd 192.168.199.3:/tmp/test

經過服務進行文件同步

rsync也能夠經過啓動守護進程方式來同步數據,須要有服務端和客戶端。
4.1 環境準備

ip 說明
192.168.30.5 rsync服務端
192.168.30.6 rsync客戶端

4.2 服務端配置
① 編輯rysnc配置文件vim /etc/rsyncd.conf,配置內容以下:

uid = rsync
gid = rsync
use chroot = no
max connections = 200
timeout = 300
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
ignore errors
read only = false
list = false
hosts allow = 192.168.30.0/24
auth users = rsync_backup
secrets file = /etc/rsync.passwd
[backup]
comment = "backup dirtory"
path = /root/rsync_test

② 建立用戶

useradd -s /sbin/nologin -M rsync

③ 建立同步數據目錄,受權屬主

mkdir rsync_test
 chown -R rsync.rsync rsync_test/

④ 建立用戶認證密碼文件,權限600

touch /etc/rsync.passwd
echo "rsync_backup:syushin" > /etc/rsync.passwd
chmod 600 /etc/rsync.passwd

⑤ 啓動rsync服務

rsync --daemon

⑥查看進程

ps aux | grep rsync
netstat -lntp | grep rsync

4.3 rsync客戶端配置
① 檢查rsync是否有安裝

rpm -qa | grep rsync

若是沒有執行安裝便可。

② 建立安全認證文件(客戶端的認證文件只須要有密碼便可),受權600

touch /etc/rsync.passwd
echo "syushin" > /etc/rsync.passwd
chmod 600 /etc/rsync.passwd

③ 推(push)文件測試
將客戶端文件motd同步到服務端中backup定義的同步數據目錄下,並更名叫test.txt
交互式:

rsync -avP /etc/motd rsync_backup@192.168.30.5::backup/test.txt

非交互式:

rsync -avP /etc/motd rsync_backup@192.168.30.5::backup/test.txt --password-file=/etc/rsync.passwd

⑤ 拉(pull)文件測試
把服務端同步數據目錄中的test.txt文件同步到本地的tmp目錄下,並更名叫server-file.txt

rsync -avP rsync_backup@192.168.30.5::backup/test.txt /tmp/server-file.txt --password-file=/etc/rsync.passwd

4.4 rsync啓動腳本
經過上面步驟可知rsync啓動使用rsync --daemon命令,關閉則須要手動kill掉,這樣對於管理rsync來講很是不方便,所以這裏經過shell寫一個rsync管理腳本。腳本內容以下:

vim /etc/init.d/rsyncd

#!/bin/bash
# chkconfig: 2345 20 80
# desription: Rsync Startup scripts by oldboy
. /etc/init.d/functions

function usage(){
    echo $"usage:$0 {start|stop|restart}"
    exit 1
}

function start(){
    rsync --daemon
    sleep 1
    if [ `netstat -lntp | grep rsync | wc -l` -ge 1 ]
      then
          action "Rsyncd is started." /bin/true
    else
        action "Rsyncd is started." /bin/false
    fi
}

function stop(){
    killall rsync &>/dev/null
    sleep 2
    if [ `netstat -lntp|grep rsync|wc -l` -eq 0 ]
      then
       action "rsyncd is stopped." /bin/true
    else
      action "rsyncd is stopped." /bin/false
    fi
}

function main(){
    if [ $# -ne 1 ]
      then
       usage
    fi
    if [ "$1" == "start" ]
      then
          start
    elif [ "$1" == "stop" ]
      then
          stop
    elif [ "$1" == "restart" ]
      then
         stop
         sleep 1
         start
    else
     usage
    fi
}
main $*

授予腳本可執行權限

chmod +x /etc/init.d/rsyncd

測試,執行腳本,而後經過查看進程判斷腳本是否執行成功。

/etc/init.d/rsyncd start
netstat -lntp | grep rsync
ps aux |grep rsync

關於rsyncd.conf配置文件的解釋

#設置服務器信息提示文件名稱,在該文件中編寫提示信息
motd file = /etc/rsyncd.motd

#開啓Rsync數據傳輸日誌功能
transfer logging = yes

#設置日誌文件名稱,能夠經過log format參數設置日誌格式
log file = /var/log/rsyncd.log

#設置Rsync進程保存文件名稱
pid file = /var/run/rsyncd.pid

#設置鎖文件名稱
lock file = /var/run/rsyncd.lock

#設置服務器監聽的端口號,默認是873端口
port = 873

#設置進行數據傳輸所使用的帳戶名稱或ID號,默認使用nobody
uid = rsync

#設置進行數據傳輸所使用的組名稱或組ID,默認使用nobody
gid = rsync

#設置服務器所監聽的IP地址,這裏的服務器地址是192.168.30.5
address = 192.168.30.5

#設置user chroot爲yes後,rsync首先會進行chroot設置,將根映射到path參數路徑下,對客戶端而言,系統的根就是path參數所指定的路徑。但這樣作須要root權限,而且在同步符號鏈接資料時僅會同步名稱,而內容不會同步。
use chroot = no

#是否容許客戶端上傳數據,這是設置只讀
read only = yes

#設置併發鏈接數,0表明無限制。超出併發數後,若是依然有客戶端鏈接請求,則會收到稍後重試的提示信息。
max connections = 10

#模塊,Rsync經過模塊定義同步的目錄,模塊以[name] 的形式定義,在Rsync中也能夠定義多個模塊
[test]

#comment定義註釋說明字串
comment = web content

#同步目錄的真實路徑經過path指定
path = /root/rsync_test

#exclude 能夠指定例外的目錄,即將/tmp/rsync目錄下的某個目錄設置不一樣步數據
exclude = test/

#設置容許鏈接服務器的用戶,帳戶能夠是不存在的用戶
auth users = rsync_backup

#設置密碼驗證文件名稱,注意該文件的權限要求爲只讀,建議權限600,僅在設置了auth users 後生效
secrets file = /etc/rsync.passwd

#設置容許那些主機能夠同步數據,能夠是單個IP也能夠是一個網段,多個IP之間用空格隔開
hosts allows=192.168.30.5 192.168.30.0/24

#設置拒絕全部,除了hosts allows定義的
hosts deny = *

#客戶端請求顯示模塊列表,本模塊名稱是否顯示,默認爲true
list = false

use chroot true|false:表示在傳輸文件前首先chroot到path參數所指定的目錄下。這樣作的緣由是實現額外的安全防禦,但缺點是須要以roots權限,而且不能備份指向外部的符號鏈接所指向的目錄文件。默認狀況下chroot值爲true,若是你的數據當中有軟鏈接文件,建議你設置成false。

當設置了auth users和secrets file後,客戶端連服務端也須要用用戶名密碼了,若想在命令行中帶上密碼,能夠設定一個密碼文件。
rsync -avL test@192.168.133.130::test/test1/ /tmp/test8/ --password-file=/etc/pass 其中/etc/pass內容就是一個密碼,權限要改成600

rsync -avP --port 8730 /etc/passwd 192.168.30.5::backup/test.txt
--port能夠指定端口。

rsync+inotify相結合,實現文件實時同步

經過上面對inotify和rsync的瞭解,實現文件實時同步就很簡單了。大概流程是利用腳本,先對同步數據的目錄進行監控,若是監控到數據發生變化,就執行rsync同步,而後將腳本放到任務計劃中執行。
下面是操做步驟.
環境

系統 IP 說明
CentOS7 192.168.30.5 rsync服務端
CentOS7 192.168.30.6 rsync客戶端

第一步,部署rsync服務

客戶端和服務端都查看是否有安裝rsync

rpm -qa | grep rsync

服務端的配置(流程和上面的經過服務同步文件同樣,這裏再次寫上)
① 編輯rysnc配置文件vim /etc/rsyncd.conf,配置內容以下:

uid = rsync
gid = rsync
use chroot = no
max connections = 200
timeout = 300
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log
ignore errors
read only = false
list = false
hosts allow = 192.168.30.0/24
auth users = rsync_backup
secrets file = /etc/rsync.passwd
[backup]
comment = "backup dirtory"
path = /root/rsync_test

② 建立用戶

useradd -s /sbin/nologin -M rsync

③ 建立同步數據目錄,受權屬主

mkdir rsync_test
 chown -R rsync.rsync rsync_test/

④ 建立用戶認證密碼文件,權限600

touch /etc/rsync.passwd
echo "rsync_backup:syushin" > /etc/rsync.passwd
chmod 600 /etc/rsync.passwd

⑤ 啓動rsync服務

rsync --daemon

客戶端的配置
① 檢查rsync是否有安裝

rpm -qa | grep rsync

若是沒有執行安裝便可。

② 建立安全認證文件(客戶端的認證文件只須要有密碼便可),受權600

touch /etc/rsync.passwd
echo "syushin" > /etc/rsync.passwd
chmod 600 /etc/rsync.passwd

第二步,部署inotify

服務端和客戶端都檢查是否安裝inotify

rpm -qa |grep inotify-tools

若是沒有就執行安裝命令

yum install -y inotify-tools

或者手動編譯安裝,須要源碼包
源碼包參考地址:https://github.com/rvoicilas/...

tar -zxf  tar -zxf inotify-tools-3.13.tar.gz 
    ./configure
    make
    make install

至此,inotify安裝完成。

第三步,編寫腳本實現inotify與rsync相結合

同步數據的操做一般在客戶端進行,下面命令都在客戶端執行。
rsync同步目錄數據命令
將本地data目錄數據同步到服務端的同步數據目錄中

rsync -avz --delete /data rsync_backup@192.168.30.5::backup --password-file=/etc/rsync.passwd

inotify監控data同步目錄數據發生變化命令

inotifywait -mrq /data -format "%w%f"  -e create,delete,move_to,close_write

編寫腳本

#!/bin/bash
Path=/root/rsync_data
backup_Server=192.168.30.5

/usr/bin/inotifywait -mrq --format '%w%f' -e create,close_write,delete $Path  | while read line  
do
    if [ -f $line ];then
        rsync -az $line --delete rsync_backup@$backup_Server::backup --password-file=/etc/rsync.passwd
    else
        cd $Path &&\
        rsync -az ./ --delete rsync_backup@$backup_Server::backup --password-file=/etc/rsync.passwd
    fi

done

測試
讓腳本後臺運行

sh /root/server/scripts/inotify.sh

在同步數據目錄建立文件

cd /root/rsync_data
touch {1..6}.txt

在服務端查看文件,已經生成。

[root@moli-linux03 rsync_test]# ls
hh.txt  rsync_data
[root@moli-linux03 rsync_test]# cd rsync_data/
[root@moli-linux03 rsync_data]# ls
1.txt  2.txt  3.txt  4.txt  5.txt  6.txt

至此,實現文件實時同步已經完成。

關於腳本後臺運行的相關命令,後續再說。

參考資料

慘綠少年的博客:https://www.cnblogs.com/clsn/...
慘綠少年的博客:https://www.cnblogs.com/clsn/...

相關文章
相關標籤/搜索