天天看點

Rsync基本使用rsync

rsync

rsync 全名 Remote Sync, 是類 unix 系統下的資料鏡像備份工具。可以友善的實作本地,遠端備份,rsync 提供了豐富的選項來控制其行為。rsync 優于其他工具的重要一點就是支援增量備份。

rsync 是一個功能非常強大的工具,其指令也有很多功能選項,它的特性如下:

可以保持檔案原來的權限、時間、所有者、組資訊、軟硬連結等等
可以從遠端或者本地鏡像儲存整個目錄樹和檔案系統
無須特殊權限 super-user 即可安裝使用
快速:要比 scp (Secure Copy) 要快;第一次同步時 rsync 會複制全部内容,但在下一次隻傳輸修改過的檔案。rsync 在傳輸資料的過程中可以實行壓縮及解壓縮操作,可以使用更少的帶寬
安全:可以使用 scp、ssh 等方式來傳輸檔案,當然也可以通過直接的 socket 連接配接
支援匿名傳輸,以友善進行網站鏡像
           

rsync 官方網址: https://rsync.samba.org

1 rsync 的使用

Rsync 的指令格式可以為以下六種:

# 本地模式
rsync [OPTION]... SRC [SRC]... DEST

# 遠端 Push
rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST

# 遠端 Pull
rsync [OPTION]... [USER@]HOST:SRC [DEST]

# 遠端 Rsync daemon Push
rsync [OPTION]... SRC [SRC]... [USER@]HOST::DEST
rsync [OPTION]... SRC [SRC]... rsync://[USER@]HOST[:PORT]/DEST

# 通過 Rsync daemon Pull
rsync [OPTION]... [USER@]HOST::SRC [DEST]
rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]
           

上述指令中,SRC 表示源位址,而 DEST 表示目标位址,這二者可以是本地目錄,也可以是遠端伺服器位址。當隻有 SRC 位址沒有 DEST 時會列出所有的檔案清單,而不會執行拷貝。

rsync 有兩種方式來連接配接遠端伺服器

  • 使用 remote shell 程式,比如 ssh 或者 rsh
  • 或者直接通過 TCP 來連接配接 daemon

    這兩種方式的直接差別展現在路徑中的冒号(:),當隻有一個冒号時使用 remote shell, 當有兩個冒号時使用 daemon 連接配接。

rsync 有六種不同的工作模式:

  • 拷貝本地檔案:當 SRC 和 DEST 路徑資訊都不包含有單個冒号“:”分隔符時就啟動這種工作模式。
  • 使用一個遠端 shell 程式(如 rsh、ssh)來實作将本地機器的内容拷貝到遠端機器。當 DEST 路徑位址包含單個冒号“:” 分割符時啟動該模式。
  • 使用一個遠端 shell 程式 (如 rsh、ssh) 來實作将遠端機器的内容拷貝到本地機器。當 SRC 位址路徑包含單個冒号”:“ 分割符時啟動該模式。
  • 從遠端 rsync 伺服器中拷貝檔案到本地機。當 SRC 路徑資訊包含”::”分隔符時啟動該模式。
  • 從本地機器拷貝檔案到遠端 rsync 伺服器中。當 DEST 路徑資訊包含”::”分隔符時啟動該模式。
  • 列遠端機的檔案清單。這類似于 rsync 傳輸,不過隻要在指令中省略掉本地機資訊即可。

這 6 中方式看似複雜,其實隻要記住一些常用參數,然後記住一些常用方法就能夠将 rsync 利用起來。

可以 man rsync 參考 rsync 文檔

下面是 rsync 參數的具體解釋:

-v, --verbose 詳細模式輸出
-q, --quiet 精簡輸出模式
-c, --checksum 打開校驗開關,強制對檔案傳輸進行校驗
-a, --archive 歸檔模式,表示以遞歸方式傳輸檔案,并保持所有檔案屬性,等于 -rlptgoD
-r, --recursive 對子目錄以遞歸模式處理
-R, --relative 使用相對路徑資訊
-b, --backup 建立備份,也就是對于目的已經存在有同樣的檔案名時,将老的檔案重新命名為~filename。可以使用 --suffix 選項來指定不同的備份檔案字首。
--backup-dir 将備份檔案(如~filename) 存放在在目錄下。
-suffix=SUFFIX 定義備份檔案字首
-u, --update 僅僅進行更新,也就是跳過所有已經存在于 DST,并且檔案時間晚于要備份的檔案。(不覆寫更新的檔案)
-l, --links 保留軟鍊結
-L, --copy-links 想對待正常檔案一樣處理軟鍊結
--copy-unsafe-links 僅僅拷貝指向 SRC 路徑目錄樹以外的鍊結
--safe-links 忽略指向 SRC 路徑目錄樹以外的鍊結
-H, --hard-links 保留硬鍊結
-p, --perms 保持檔案權限
-o, --owner 保持檔案屬主資訊
-g, --group 保持檔案屬組資訊
-D, --devices 保持裝置檔案資訊
-t, --times 保持檔案時間資訊
-S, --sparse 對稀疏檔案進行特殊處理以節省 DST 的空間
-n, --dry-run 現實哪些檔案将被傳輸
-W, --whole-file 拷貝檔案,不進行增量檢測
-x, --one-file-system 不要跨越檔案系統邊界
-B, --block-size=SIZE 檢驗算法使用的塊尺寸,預設是 700 位元組
-e, --rsh=COMMAND 指定使用 rsh、ssh 方式進行資料同步
--rsync-path=PATH 指定遠端伺服器上的 rsync 指令所在路徑資訊
-C, --cvs-exclude 使用和 CVS 一樣的方法自動忽略檔案,用來排除那些不希望傳輸的檔案
--existing 僅僅更新那些已經存在于 DST 的檔案,而不備份那些新建立的檔案
--delete 删除那些 DST 中 SRC 沒有的檔案
--delete-excluded 同樣删除接收端那些被該選項指定排除的檔案
--delete-after 傳輸結束以後再删除
--ignore-errors 及時出現 IO 錯誤也進行删除
--max-delete=NUM 最多删除 NUM 個檔案
--partial 保留那些因故沒有完全傳輸的檔案,以是加快随後的再次傳輸
--force 強制删除目錄,即使不為空
--numeric-ids 不将數字的使用者群組 ID 比對為使用者名群組名
--timeout=TIME IP 逾時時間,機關為秒
-I, --ignore-times 不跳過那些有同樣的時間和長度的檔案
--size-only 當決定是否要備份檔案時,僅僅察看檔案大小而不考慮檔案時間
--modify-window=NUM 決定檔案是否時間相同時使用的時間戳視窗,預設為 0
-T --temp-dir=DIR 在 DIR 中建立臨時檔案
--compare-dest=DIR 同樣比較 DIR 中的檔案來決定是否需要備份
-P 等同于 --partial
--progress 顯示備份過程
-z, --compress 對備份的檔案在傳輸時進行壓縮處理
--exclude=PATTERN 指定排除不需要傳輸的檔案模式
--include=PATTERN 指定不排除而需要傳輸的檔案模式
--exclude-from=FILE 排除 FILE 中指定模式的檔案
--include-from=FILE 不排除 FILE 指定模式比對的檔案
--version 列印版本資訊
           

2 工作模式執行個體

下面舉例說明 rsync 的六種不同工作模式

2.1 同機器拷貝檔案到不同位置

當 SRC 和 DES 路徑資訊都不包含有單個冒号 “:” 分隔符時就啟動這種工作模式

同步檔案

将備份檔案同步到 /backups/ 目錄下

同步目錄

rsync -avzh /home/ci-user  /backup/ci-user/
           

解釋: 将

/home/ci-user

目錄下的檔案同步發送到

backup/ci-user/

目錄下,記住如果目标位址沒有

src

目錄,rsync 會自動建立該檔案夾。

比較差別

rsync -avzh /home/ci-user/   /backup/ci-user/
           

解釋: SRC 路徑末尾的 / 表示不自動建立 DEST 檔案夾,在 man rsync 中的解釋就是末尾的 / 表示”拷貝目前目錄下的檔案” ,而不是”拷貝目前的目錄”.

2.2 不同機器利用遠端機器 shell 拷貝本地機器的内容到遠端機器

使用一個遠端 shell 程式(如 rsh、ssh) 來實作将本地機器的内容拷貝到遠端機器。當 DES 路徑位址包含單個冒号”:”分隔符時啟動該模式。

rsync -avz /home/ci-user/  [email protected]:/path/
           

解釋: 将本地

/home/ci-uesr/

中的檔案同步備份到遠端

/path/

目錄

2.3 不同機器利用遠端機器 shell 拷貝遠端機器的内容到本地機器

使用一個遠端 shell 程式(如 rsh、ssh) 來實作将遠端機器的内容拷貝到本地機器。當 SRC 位址路徑包含單個冒号”:”分隔符時啟動該模式。

rsync -avz [email protected]:/home/ci-user    /home/data
           

2.4 不同機器利用遠端機器 rsync 程式 拷貝遠端内容到本地機器

從遠端 rsync 伺服器中拷貝檔案到本地機。當 SRC 路徑資訊包含”::”分隔符時啟動該模式。

rsync -av [email protected]::clickhouse  /data/clickhouse
           

2.5 不同機器利用遠端機器 rsync 程式 拷貝本地内容到遠端機器

從本地機器拷貝檔案到遠端 rsync 伺服器中。當 DES 路徑資訊包含”::”分隔符時啟動該模式。

rsync -av /data/clickhouse  [email protected]::clickhouse
           

2.6 檔案清單

列遠端機器的檔案清單。這類似于 rsync 傳輸,不過隻要在指令中省略掉本地機器資訊即可

rsync -v rsync://remoteip  /www
           

3 rsync 使用非标準端口

經常遇見的一種情況就是 ssh 更改了預設 22 端口,這個時候就需要使用 -e 參數

rsync 在不同機器間使用時,有兩種常用的認證方式,一個是 daemon 方式,一個是 ssh。

當遠端機器的 ssh 端口不再是預設的22時,當我們執行下面指令就會出現錯誤

rsync 中的指令參數

-e, --rsh=COMMAND

指定使用 rsh、ssh 方式進行資料同步

當ssh端口不是預設的情況下,我們可以這樣寫

rsync -avz -e "ssh -p $port" /home/ci-user/ [email protected]:/path/  
# 注意 /home/ci-user 和 /home/ci-user/ 效果是不一樣的,差別在于要不要把ci-user目錄也傳遞過去
           

4 顯示備份進度-針對單個檔案傳輸而言

可以使用

--progress

選項來顯示進度

rsync -avzhe ssh --progress /home/ci-user/  [email protected]:/path/
           

5 限制傳輸速率

rsync --bwlimit=10000 -avzhe ssh /mtn/disks/2/  [email protected]:/data/
           

6 全量備份-ssh方式

rsync --bwlimit=10000 --progress -azue ssh /mnt/disks/2/data [email protected]:/data01/dev8-ck-backup/
# 這裡限制傳輸速度 1w Kb,但是實際中是最高是超過 1w Kb 但是在 2w Kb 之下,具體什麼原因還沒查出來,難道是指整個傳輸過程中的平均速率?
01 00 * * * rsync --bwlimit=10000 --progress -azue ssh /mnt/disks/2/data [email protected]:/data01/dev8-ck-backup/ >/dev/null 2>&1
           

7 全量備份+實時備份

上面一個遠端容災系統已經搭建完成,但這并非是一個完整意義上的容災方案,由于rsync需要通過觸發才能将伺服器端資料同步,是以兩次觸發同步的時間間隔内,

伺服器和用戶端的資料可能不一緻,如果在這個時間間隔内,網站系統出現問題,資料必然丢失,Linux 2.6.13以後的核心提供了inotify檔案系統監控機制,

用過rsync與inotify的組合,完全可以實作rsync伺服器端和用戶端的實時資料同步。

7.1 rsync服務端配置檔案 (clickhouse-backup-test01(192.168.1.24)服務端,dev8用戶端)

root使用者啟動rsync服務端

[[email protected] run]# cat /etc/rsyncd.conf

# /etc/rsyncd: configuration file for rsync daemon mode

# See rsyncd.conf man page for more options.

# configuration example:

# uid = nobody
# gid = nobody
# use chroot = yes
# max connections = 4
# pid file = /var/run/rsyncd.pid
# /etc/rsyncd: configuration file for rsync daemon mode
# exclude = lost+found/
# transfer logging = yes
# timeout = 900
# ignore nonreadable = yes
# dont compress   = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2

# [ftp]
#        path = /home/ftp
#        comment = ftp export area


uid = root
gid = root
use chroot = no
max connections = 0
ignore errors
exclude = lost+found/
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
reverse lookup = yes
[clickhouse]
path = /data01/dev8-ck-backup/ckdata
comment = clickhouse-backup
read only = no
auth users = rsyncuser
secrets file = /etc/rsync.pass
           

需要注意上面配置檔案中的目錄,不要寫錯了

添加 /etc/rsync.pass 檔案

echo "rsyncuser:clickhouse"  >/etc/rsync.pass
           

修改 /etc/rsync.pass 檔案權限

chmod 600 /etc/rsync.pass
           

root 使用者啟動

rsync --daemon
           

7.2 用戶端dev8 啟動指令

首先檢查用戶端是否已經安裝rsync軟體

# 每兩個小時做一次增量備份
00 */2 * * * rsync --bwlimit=10240 --progress -avz --password-file=/etc/rsync.pass /mnt/disks/2/data/ [email protected]::clickhouse
           

7.3 rsync用戶端安裝inotify軟體 實時同步

安裝 inotify 的用戶端工具 inotify-tools,我們可以了解 inotify 是核心一個功能,屬于核心空間,我們需要一個使用者空間工具來操作它,這點應該和 netfiler 與 iptables 的關系類似。

摘抄自[email protected]如下,該腳本一旦被執行,就會通過核心的 inotify 機制實時監控同步路徑下的目錄和檔案,當這些目錄和檔案發生create、delete、attrib、close_write、move ./ 動作時,就會産生事件通知,rsync用戶端的程序sender就會把這些變化的目錄或檔案發送到服務端進行校驗處理

[[email protected] ~]# cat >> inotify_rsync.sh << EOF
#!/bin/bash
src=/mnt/disks/2/data                          # 需要同步的源路徑
des=clickhouse                             # 目标伺服器上 rsync --daemon 釋出的名稱,rsync --daemon這裡就不做介紹了,網上搜一下,比較簡單。
rsync_passwd_file=/etc/rsync.pass            # rsync驗證的密碼檔案
ip1=10.176.6.24                 # 目标伺服器1
user=rsyncuser                            # rsync --daemon定義的驗證使用者名
cd ${src}                              # 此方法中,由于rsync同步的特性,這裡必須要先cd到源目錄,inotify再監聽 ./ 才能rsync同步後目錄結構一緻,有興趣的同學可以進行各種嘗試觀看其效果
inotifywait -mrq --format  '%Xe %w%f' -e modify,create,delete,attrib,close_write,move ./ | while read file         # 把監控到有發生更改的"檔案路徑清單"循環
do
        INO_EVENT=$(echo $file | awk '{print $1}')      # 把inotify輸出切割 把事件類型部分指派給INO_EVENT
        INO_FILE=$(echo $file | awk '{print $2}')       # 把inotify輸出切割 把檔案路徑部分指派給INO_FILE
        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_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des}         # INO_FILE變量代表路徑哦  -c校驗檔案内容
                 #仔細看 上面的rsync同步指令 源是用了$(dirname ${INO_FILE})變量 即每次隻針對性的同步發生改變的檔案的目錄(隻同步目标檔案的方法在生産環境的某些極端環境下會漏檔案 現在可以在不漏檔案下也有不錯的速度 做到平衡) 然後用-R參數把源的目錄結構遞歸到目标後面 保證目錄結構一緻性
        fi
        #删除、移動出事件
        if [[ $INO_EVENT =~ 'DELETE' ]] || [[ $INO_EVENT =~ 'MOVED_FROM' ]]
        then
                echo 'DELETE or MOVED_FROM'
                rsync -avzR --delete --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des}
                #看rsync指令 如果直接同步已删除的路徑${INO_FILE}會報no such or directory錯誤 是以這裡同步的源是被删檔案或目錄的上一級路徑,并加上--delete來删除目标上有而源中沒有的檔案,這裡不能做到指定檔案删除,如果删除的路徑越靠近根,則同步的目錄月多,同步删除的操作就越花時間。這裡有更好方法的同學,歡迎交流。
        fi
        #修改屬性事件 指 touch chgrp chmod chown等操作
        if [[ $INO_EVENT =~ 'ATTRIB' ]]
        then
                echo 'ATTRIB'
                if [ ! -d "$INO_FILE" ]                 # 如果修改屬性的是目錄 則不同步,因為同步目錄會發生遞歸掃描,等此目錄下的檔案發生同步時,rsync會順帶更新此目錄。
                then
                        rsync -avzcR --password-file=${rsync_passwd_file} $(dirname ${INO_FILE}) ${user}@${ip1}::${des}
                fi
        fi
done

EOF

           

放到背景運作

7.4 優化 Inotify

在 /proc/sys/fs/inotify 目錄下有三個檔案,對inotify機制有一定的限制,可以通過修改下面參數的值,來提高 inotify 的性能

[[email protected] ~]# ll /proc/sys/fs/inotify/
total 0
-rw-r--r--. 1 root root 0 Sep  5 19:00 max_queued_events
-rw-r--r--. 1 root root 0 Sep  5 19:00 max_user_instances
-rw-r--r--. 1 root root 0 Sep  5 19:00 max_user_watches

# 我們可以把這三個參數修改後,寫入 /etc/sysctl.conf 檔案中
[[email protected] ~]# cat >>/etc/sysctl.conf <eof
fs.inotify.max_user_watches=212400
fs.inotify.max_user_instances=1024
fs.inotify.max_queued_events=999999
eof

# 臨時使上面檔案生效
[[email protected] ~]# sysctl -p

# max_user_watches:  設定inotifywait 或 inotifywatch指令可以監視的檔案數量(單程序)
# max_user_instances: 設定每個使用者可以運作的 inotifywait 或 inotifywatch 指令的程序數
# max_queued_events: 設定 inotify 執行個體事件(event)隊列可容納的事件數量
           

參考

  • https://www.cnblogs.com/qiuhom-1874/p/12246660.html
  • https://cloud.tencent.com/developer/article/1373541
  • https://einverne.github.io/post/2017/07/rsync-introduction.html

繼續閱讀