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