Linux下如何使用Rsync備份伺服器重要資料

上古南城發表於2021-07-19

 

            

Rsync介紹:

  • Rsync英文全稱Remote synchronization,從軟體的名稱就可以看出來,Rsync具有可使本地和遠端兩臺主機之間的資料快速複製同步映象,遠端備份的功能,這個功能類似ssh帶的scp命令,但又優於scp命令的功能,scp每次都是全量拷貝,而rsync可以增量拷貝。
  • Rsync還可以在本地主機的不同分割槽或目錄之間全量及增量的複製資料,這又類似cp命令,但同樣也優於cp命令,cp每次都是全量拷貝,而rsync可以增量拷貝。
  • Rsync是一款開源的,快速的,多功能的,可實現全量及增量的本地或遠端資料同步備份的優秀工具。Rsync軟體適用於unix/linux/windows等多種作業系統平臺。

Rsync優點:

  • 支援增量備份,第一次全量備份,第二次增量備份。邊複製邊比較邊統計,傳輸效率高。
  • 資料集中備份,客戶端可以推送資料至服務端,也可以從服務端獲取資料,與客戶端為參照物。
  • 保持檔案屬性,符號連結,硬連結,許可權,時間等。
  • 安全方式傳輸,Rsync本身不對資料加密,使用ssh作為傳輸埠。
  • 指定排除檔案,排除無需同步的檔案或目錄。
  • 程式方式同步,rsync執行在C/S架構,通過程式方式傳輸檔案或資料,預設監聽tcp873埠。

Rsync缺點:

  • 1.大量小檔案同步會比較慢,需要比對時間較長,可能造成Rsync程式停止。

   解決思路:將小檔案進行打包,然後再同步,減小比對時間,傳輸效率更高

  • 2.同步大檔案會出現中斷情況,而且長時間同步會造成網路資源耗盡。

   解決思路:配置限速同步,未同步完之前修改為隱藏檔案,同步完後修改為正常檔案

 Rsync語法格式:

SYNOPSIS
       Local:  rsync [OPTION...] SRC... [DEST]

       Access via remote shell:
         Pull: rsync [OPTION...] [USER@]HOST:SRC... [DEST]
         Push: rsync [OPTION...] SRC... [USER@]HOST:DEST

       Access via rsync daemon:
         Pull: rsync [OPTION...] [USER@]HOST::SRC... [DEST]
               rsync [OPTION...] rsync://[USER@]HOST[:PORT]/SRC... [DEST]
         Push: rsync [OPTION...] SRC... [USER@]HOST::DEST
               rsync [OPTION...] SRC... rsync://[USER@]HOST[:PORT]/DEST
    
測試傳送:rsync -nr -i SRC  DEST
OPTION
  -a, --archive 歸檔模式,表示以遞迴方式傳輸檔案,並保持所有檔案屬性,等於-rlptgoD
  -v, --verbose 詳細模式輸出
  -p, --perms 保持檔案許可權
  -g, --group 保持檔案屬組資訊
  -o, --owner 保持檔案屬主資訊
  -r, --recursive 對子目錄以遞迴模式處理。同步目錄的時候要加上這個引數
  -l, --links 保留軟鏈結,加上這個引數,同步過來的檔案會保持之前的軟連結屬性不變
  -H, --hard-links 保留硬鏈結
  -e, --rsh=COMMAND 指定使用rsh、ssh方式進行資料同步
  -z, --compress 對備份的檔案在傳輸時進行壓縮處理
  --stats 給出某些檔案的傳輸狀態
  --progress 列印同步的過程
  --timeout=TIME 同步過程中,IP超時時間,單位為秒
  --delete 刪除那些目標目錄中有而源目錄中沒有的多餘檔案。這個是rsync做增量方式的全備份的最佳選擇方案!!!!!!
  --delete-before 接受者在輸出之前進行刪除操作。即先將目標目錄中檔案全部刪除,再將源目錄檔案拷貝過去。這是rsync保持目標目錄跟源目錄一致的方案!!!
  --delete-after 在同步操作之後做比較,刪除那些目標目錄中有而源目錄中沒有的多餘檔案
  --delete-excluded 刪除目標目錄中那些被該選項指定排除的檔案
  --ignore-errors 即使出現IO錯誤也進行刪除,忽略錯誤
  --exclude 指定同步時需要過濾掉的檔案或子目錄(即不需要同步過去的),後面直接跟不需要同步的單個檔名或子目錄(不需要跟路徑) ,過濾多個檔案或子目錄,就使用多個--exclude
  --exclude-from 指定同步時需要過濾掉的檔案或子目錄,後面跟檔案(比如/root/exclue.txt),然後將不需要同步的檔案和子目錄放到/root/exclue.txt下。
  --version 列印版本資訊
  --port=PORT 指定其他的rsync服務埠
  --log-format=formAT 指定日誌檔案格式
  --password-file=FILE 從FILE中得到密碼
  --bwlimit=KBPS 限制I/O頻寬,KBytes per second
  --existing  只更新目標端已存在的檔案
  --ignore-existing   更新目標端不存在的檔案
  --remove-source-files   刪除源端檔案

 環境準備:

屬性 備份機 伺服器-01 伺服器-02
節點 rsyncBak Server-01 Server-02
系統 CentOS Linux release 7.5.1804 (Minimal) CentOS Linux release 7.5.1804 (Minimal) CentOS Linux release 7.5.1804 (Minimal)
核心 3.10.0-862.el7.x86_64 3.10.0-862.el7.x86_64 3.10.0-862.el7.x86_64
SELinux setenforce 0 | disabled setenforce 0 | disabled setenforce 0 | disabled
Firewlld systemctl stop/disable firewalld systemctl stop/disable firewalld systemctl stop/disable firewalld
IP地址 172.16.70.37 172.16.70.181 172.16.70.182

 說明:節點Server-01,Server-02已與rsyncBak實現公鑰認證登入。

 設定公鑰認證可參考:
   1.Linux下基於OpenSSH 你知道多少?
   2.Linux下如何使用Ansible處理批量操作

Rysnc命令簡單使用示例:

例1:本地以及遠端shell格式。
[root@Server-01 ~]# rsync /etc/fstab /tmp                # 在本地同步
[root@Server-01 ~]# rsync -r /etc 172.16.10.37:/tmp      # 將本地/etc目錄拷貝到遠端主機的/tmp下,以保證遠端/tmp目錄和本地/etc保持同步
[root@Server-01 ~]# rsync -r 172.16.10.5:/etc /tmp       # 將遠端主機的/etc目錄拷貝到本地/tmp下,以保證本地/tmp目錄和遠端/etc保持同步
[root@Server-01 ~]# rsync /etc/                          # 列出本地/etc/目錄下的檔案列表
[root@Server-01 ~]# rsync 172.16.10.5:/tmp/              # 列出遠端主機上/tmp/目錄下的檔案列表

例2:源路徑如果是一個目錄的話,帶上尾隨斜線和不帶尾隨斜線是不一樣的。
[root@Server-01 ~]# rsync -a /data /tmp       # 表示的是整個目錄包括目錄本身
[root@Server-01 ~]# rsync -a /data/ /tmp      # 表示的是目錄中的檔案,不包括目錄本身

例3:如果要拷貝的源路徑較長,但只想在目標主機上保留一部分目錄結構,例如要拷貝/etc/sysconfig/network-scripts/*到/tmp下,但只想在/tmp下保留從sysconfig開始的目錄,如何操作?
[root@Server-01 ~]# rsync -r -R /etc/./sysconfig/network-scripts /tmp
skipping non-regular file "sysconfig/network-scripts/ifdown"
skipping non-regular file "sysconfig/network-scripts/ifdown-isdn"
skipping non-regular file "sysconfig/network-scripts/ifup"
skipping non-regular file "sysconfig/network-scripts/ifup-isdn"
[root@Server-01 ~]# ls /tmp/
sysconfig

例4:可以使用"--backup-dir"指定備份檔案儲存路徑,但要求儲存路徑必須存在。
[root@Server-01 ~]# rsync -r -R --backup --backup-dir=/tmp/sysconfig_bak /etc/./sysconfig/network-scripts /tmp
skipping non-regular file "sysconfig/network-scripts/ifdown"
skipping non-regular file "sysconfig/network-scripts/ifdown-isdn"
skipping non-regular file "sysconfig/network-scripts/ifup"
skipping non-regular file "sysconfig/network-scripts/ifup-isdn"
[root@Server-01 ~]#
[root@Server-01 ~]# ls /tmp/
sysconfig  sysconfig_bak

例5:排除資料夾或檔案,使用 '--exclude-from' ;
[root@Server-01 ~]# rsync -r -v --exclude-from='dir1' /data/ /tmp    # 同步/data/目錄下所有目錄(除/data/dir1目錄)

情景一:

  分別將172.16.70.181的/data/mongodbServer01和/data/logServer01目錄;172.16.70.182的/data/logServer02和/data/mongodbServer02目錄,定期同步到172.16.70.37的/data/backup/hosts目錄下。

情景二:

  分別將172.16.70.181的/data/mongodbServer01目錄;172.16.70.182的/data/mongodbServer02目錄,實時同步到172.16.70.37的/data/backup/momgo目錄下。

  即是:172.16.70.181,172.16.70.182 作為rsync的傳送端,部署rsync+inotify;172.16.70.37 作為rsync的接收端,只需要安裝配置rsync即可,不需要安裝inotify。

 

情景一二共同配置:部署源伺服器(2臺機器同樣操作),rsync傳送端過程。

[root@Server-01 ~]# yum install -y rsync
[root@Server-01 ~]# rpm -qa | grep rsync
rsync-3.1.2-10.el7.x86_64

[root@Server-01 ~]# systemctl start rsyncd
[root@Server-01 ~]# systemctl enable rsyncd
[root@Server-01 ~]# netstat -nutlp | grep rsync
tcp        0      0 0.0.0.0:873             0.0.0.0:*               LISTEN      12414/rsync
tcp6       0      0 :::873                  :::*                    LISTEN      12414/rsync

# 建立rsync虛擬賬戶名和密碼,並賦予密碼檔案600許可權
[root@Server-01 ~]# echo "123456" > /etc/rsyncd.passwd
[root@Server-01 ~]# chmod 600 /etc/rsyncd.passwd
[root@Server-01 ~]# ls -l /etc/rsyncd.passwd
-rw-------. 1 root root 20 Jun 30 14:55 /etc/rsyncd.passwd

[root@Server-01 ~]# mkdir /data/{logServer01,mongodbServer01}
[root@Server-01 ~]# ls -l /data/
drwxr-xr-x. 2 root root 6 Jun 30 15:02 logServer01
drwxr-xr-x. 2 root root 6 Jun 30 15:02 mongodbServer01

# 在傳送端進行推送/data/logServer01;/data/mongodbServer01測試
[root@Server-01 ~]# rsync -avzP /data/logServer01 rsync_backup@172.16.70.37::log --password-file=/etc/rsyncd.passwd
[root@Server-01 ~]# rsync -avzP /data/mongodbServer01 rsync_backup@172.16.70.37::mongodb --password-file=/etc/rsyncd.passwd

# 在接收端檢驗是否同步
[root@rsyncBak ~]# ls -l /data/*
/data/logBk:
total 0
drwxr-xr-x. 2 rsync rsync 18 Jun 30 15:10 logServer01

/data/mongodbBk:
total 0
drwxr-xr-x. 2 rsync rsync 17 Jun 30 15:10 mongodbServer01

情景一二共同配置:部署backup伺服器,rsync接收端過程。

[root@rsyncBak ~]# rpm -qa | grep rsync
[root@rsyncBak ~]# yum install -y rsync
[root@rsyncBak ~]# rsync --version
rsync  version 3.1.2  protocol version 31
Copyright (C) 1996-2015 by Andrew Tridgell, Wayne Davison, and others.
Web site: http://rsync.samba.org/
Capabilities:
    64-bit files, 64-bit inums, 64-bit timestamps, 64-bit long ints,
    socketpairs, hardlinks, symlinks, IPv6, batchfiles, inplace,
    append, ACLs, xattrs, iconv, symtimes, prealloc

rsync comes with ABSOLUTELY NO WARRANTY.  This is free software, and you
are welcome to redistribute it under certain conditions.  See the GNU
General Public Licence for details. 

[root@rsyncBak ~]# cp /etc/rsyncd.conf{,.bak}
[root@rsyncBak ~]# vim /etc/rsyncd.conf
......
# 末行新增以下內容
######## 全域性配置引數 ##########
uid = rsync
# rsync服務的執行使用者,預設是nobody,檔案傳輸成功後屬主將是這個uid
gid = rsync
# rsync服務的執行組,預設是nobody,檔案傳輸成功後屬組將是這個gid
port = 873
# 指定rsync埠。預設873
fake super = yes
# 無需讓rsync以root身份執行,允許接收檔案的完整屬性
use chroot = no
# rsync daemon在傳輸前是否切換到指定的path目錄下,並將其監禁在內
max connections = 200
# 指定最大連線數量,0表示沒有限制
timeout = 300
# 確保rsync伺服器不會永遠等待一個崩潰的客戶端,0表示永遠等待
ignore errors
# 忽略某些IO錯誤資訊
auth users = rsync_backup
# 指定連線到該模組的使用者列表,只有列表裡的使用者才能連線到模組,使用者名稱和對應密碼儲存在secrts file中,這裡使用的不是系統使用者,而是虛擬使用者。不設定時,預設所有使用者都能連線,但使用的是匿名連線
secrets file = /etc/rsyncd.passwd
#儲存auth users使用者列表的使用者名稱和密碼,每行包含一個username:passwd。由於"strict modes",預設為true,所以此檔案要求非rsync daemon使用者不可讀寫。只有啟用了auth users該選項才有效,echo "rsync_backup:123456" > /etc/rsyncd.password  許可權:600
read only = false
# 指定該模組是否可讀寫,即能否上傳檔案,false表示可讀寫,true表示可讀不可寫。所有模組預設不可上傳
write only = false
# 指定該模式是否支援下載,設定為true表示客戶端不能下載。所有模組預設可下載
list = false
# 客戶端請求顯示模組列表時,該模組是否顯示出來,設定為false則該模組為隱藏模組。預設true
motd file = /var/rsyncd/rsync.motd
# 客戶端連線過來顯示的訊息
pid file = /var/run/rsyncd.pid
# 指定rsync daemon的pid檔案
lock file = /var/run/rsync.lock
# 指定鎖檔案
log file = /var/log/rsyncd.log
# 指定rsync的日誌檔案,而不把日誌傳送給syslog
dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2
# 指定哪些檔案不用進行壓縮傳輸

########## 模組配置引數,可以建立多個模組 ###########
[backup]
# 模組ID1
path = /data/backup/hosts
# 指定該模組的路徑,該引數必須指定。啟動rsync服務前該目錄必須存在。rsync請求訪問模組本質就是訪問該路徑。
hosts allow = 172.16.0.0/16
# 指定允許連線到該模組的機器,多個ip用空格隔開或者設定區間
hosts deny = 0.0.0.0/32
# 指定不允許連線到該模組的機器

[mongodb]
# 模組ID2
path = /data/backup/mongodb
hosts allow = 172.16.0.0/16
hosts deny = 0.0.0.0/32

# 建立rsync賬戶及共享目錄並修改目錄屬主為rsync [root@rsyncBak ~]# useradd -M -s /sbin/nologin rsync
[root@rsyncBak ~]# mkdir /data/backup/{hosts,mongodb} -p
[root@rsyncBak ~]# chown -R rsync /data/backup/{hosts,mongodb}
[root@rsyncBak ~]# ls -l /data/backup/
drwxr-xr-x. 2 rsync root 6 Jul  1 10:35 hosts
drwxr-xr-x. 2 rsync root 6 Jul  1 10:35 mongodb
[root@rsyncBak ~]# ls -ld /data/backup/
drwxr-xr-x. 4 root root 30 Jul  1 10:35 /data/backup/

# 建立rsync虛擬賬戶名和密碼,並賦予密碼檔案600許可權
[root@rsyncBak ~]# echo "rsync_backup:123456" > /etc/rsyncd.passwd
[root@rsyncBak ~]# chmod 600 /etc/rsyncd.passwd
[root@rsyncBak ~]# ls -l /etc/rsyncd.passwd
-rw-------. 1 root root 20 Jun 30 12:25 /etc/rsyncd.passwd

# 啟動rsync
[root@rsyncBak ~]# systemctl start rsyncd
[root@rsyncBak ~]# systemctl enable rsyncd
[root@rsyncBak ~]# netstat -ntpul | grep rsync
tcp        0      0 0.0.0.0:873             0.0.0.0:*               LISTEN      2665/rsync
tcp6       0      0 :::873                  :::*                    LISTEN      2665/rsync

注意:每次修改配置檔案rsyncd.conf後,都需要執行 systemctl restart rsyncd

以下為各情景區別之處。

  • 情景一:部署源伺服器(2臺機器同樣操作),rsync傳送端過程。
[root@Server-01 ~]#/data/scripts/backup.sh
#!/bin/bash
#
# 備份解決方案rsync傳送端打包指令碼

Path=/data/backup
backup_Server=172.16.70.37
local_IP=`ifconfig ens33|awk -F"[ :]+" 'NR==2{print $3}'`
Dir=${local_IP}_$(date +%F)

mkdir -p $Path/$Dir
[ -d /data/logServer01 ] && cp -rp /data/logServer01 $Path/$Dir/
[ -d /data/mongodbServer01 ] && cp -rp /data/mongodbServer01 $Path/$Dir/
cd $Path

tar -zcf $Path/${Dir}.tar.gz $Dir

rm -rf $Path/$Dir
# 建立md5sum驗證資訊
/usr/bin/md5sum $Path/${Dir}.tar.gz > $Path/md5sum_${local_IP}.txt

# 推送打包的檔案到備份伺服器
rsync -az $Path/ rsync_backup@${backup_Server}::backup --password-file=/etc/rsyncd.passwd

[ $? -eq 0 ] && echo "推送打包檔案傳送成功." || echo "推送打包檔案傳送失敗.

# 找出超過7天的備份並刪除
find $Path/ -name "${local_IP}*" -type f -mtime +7 | xargs rm -rf

# 測試執行同步指令碼
[root@Server-01 ~]# bash /data/scripts/backup.sh
推送打包檔案傳送成功.

# 將指令碼掛定時任務
00 04 * * *  root /bin/bash /server/scripts/backup.sh >/dev/null 2>&1
  • 情景一:部署backup伺服器,rsync接收端過程。
[root@rsyncBak ~]# cat /data/scripts/rsync_Server.sh
#!/bin/bash
#
# 備份解決方案rsync接收端檢查指令碼

. /etc/init.d/functions
Path=/data/backup
fileName="md5sum.txt"
# 一共有幾臺客戶端在推送資料
rsync_ClientNum=2

if [ `find $Path/ -type f -name "md5sum*" | wc -l` -eq $rsync_ClientNum ];then
    for filepath in `find $Path/ -type f -name "md5sum*"`
    do
        /usr/bin/md5sum -c $filepath
        if [ $? -eq 0 ];then
            action "${filepath}備份正常!" /bin/true
            rm -rf $filepath
        else
            action "${filepath}備份異常!" /bin/false
            echo "${filepath}備份異常!" | mail -s "$(date +%F)備份檢查告警" xxxxxxxx@qq.com
        fi
    done
else
    echo “Rsync客戶端推送不完整!”
    echo "Rsync推送不完整" | mail -s "$(date +%F)備份推送告警" xxxxxxxxx@qq.com
fi

# 找出超過180天的不是周1的備份檔案並刪除
find $Path/ ! -name "*_2.tar.gz" -mtime +180 -type f | xargs rm -rf


# 測試執行同步檢查指令碼
[root@rsyncBak ~]# bash /data/scripts/rsync_Server.sh
/data/backup/172.16.70.181_2021-07-01.tar.gz: OK
/data/backup/md5sum_172.16.70.181.txt備份正常!            [  OK  ]
/data/backup/172.16.70.182_2021-07-01.tar.gz: OK
/data/backup/md5sum_172.16.70.182.txt備份正常!            [  OK  ]

# 將指令碼掛定時任務
00 06 * * * root /bin/bash /data/scripts/rsync_Server.sh >/dev/null 2>&1
  • 情景二:部署源伺服器(2臺機器同樣操作),rsync傳送端過程。
# 檢視伺服器核心是否支援inotify,出現下面的內容,說明伺服器核心支援inotify。
[root@rsyncBak ~]# ls -l /proc/sys/fs/inotify/
total 0
-rw-r--r--. 1 root root 0 Jun 30 16:12 max_queued_events
-rw-r--r--. 1 root root 0 Jun 30 16:12 max_user_instances
-rw-r--r--. 1 root root 0 Jun 30 16:12 max_user_watches


# 安裝inotify軟體
[root@Server-01 ~]# yum install -y inotify-tools
[root@Server-01 ~]# rpm -qa | grep inotify
inotify-tools-3.14-9.el7.x86_64
[root@Server-01 ~]# rpm -ql inotify-tools-3.14-9.el7.x86_64
/usr/bin/inotifywait    # 在被監控的檔案或目錄上等待特定檔案系統事件(open close delete等)發生,執行後處於阻塞狀態,適合在shell指令碼中使用
/usr/bin/inotifywatch    # 收集被監控的檔案系統使用的統計資料,指檔案系統事件發生的次數統計。

#命令 man手冊說明
    # man inotifywait
    inotifywait - wait for changes to files using inotify  使用inotify進行監控,等待產生變化的檔案資訊

    # man inotifywatch
    inotifywatch - gather filesystem access statistics using inotify  使用inotify進行監控,收集檔案系統訪問統計佶息


# 編寫指令碼實現inotify與rsync相結合
[root@Server-01 ~]# cat /data/scripts/inotify.sh
#!/bin/bash
# 實時檢測/data/backup目錄內檔案是否有變化,如有則同步到172.16.70.37的mongodb模組
#
Path='/data'
# 排查/data目錄下以".sh"檔案,不需同步
excludefile='*.sh'
backup_Server=172.16.70.37

/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 --exclude=$excludefile rsync_backup@$backup_Server::mongodb --password-file=/etc/rsyncd.passwd
    else
        cd $Path &&\
        rsync -az ./ --delete --exclude=$excludefile rsync_backup@$backup_Server::mongodb --password-file=/etc/rsyncd.passwd
    fi

done

# 後臺執行實時同步指令碼
[root@Server-01 ~]# bash /data/scripts/inotify.sh &
[1] 2895

# 建立測試檔案
[root@Server-01 ~]# touch  /data/db{1..3} /data/{4..6}.sh
[root@Server-01 ~]# ls -l /data/
-rw-r--r--  1 root root   0 Jul  1 17:24 4.sh
-rw-r--r--  1 root root   0 Jul  1 17:24 5.sh
-rw-r--r--  1 root root   0 Jul  1 17:24 6.sh
-rw-r--r--  1 root root   0 Jul  1 17:24 db1
-rw-r--r--  1 root root   0 Jul  1 17:24 db2
-rw-r--r--  1 root root   0 Jul  1 17:24 db3
  •  情景二:部署backup伺服器,rsync接收端過程。
# 檢查測試檔案是否按要求同步
[root@rsyncBak ~]# ls -l /data/backup/mongodb/
total 0
-rw-r--r--. 1 rsync rsync 0 Jul  1 17:24 db1
-rw-r--r--. 1 rsync rsync 0 Jul  1 17:24 db2
-rw-r--r--. 1 rsync rsync 0 Jul  1 17:24 db3

# 檢視後臺執行的程式
[root@Server-01 ~]# jobs
[1]+  Running                 bash /data/scripts/inotify.sh &

# 程式的前臺和後臺的執行方法:
 fg -- 前臺
 bg -- 後臺

 

相關文章