在linux系統中,需要注意空格使用,有着整體性原則,並且注意大小寫問題
Rsync數據同步工具
開源、快速、多功能、可實現全量和增量的本地或遠程
具有本地和遠程兩台主機之間數據快速同步鏡像、遠程備份的功能類似ssh帶的scp命令,還可以實現刪除文件和目錄的功能,同步內容和屬性,還可以同步一個文件里有變化的內容部分
全量: 全部備份
增量:差異化備份,效率更高
rsync –version # 查看版本信息
Rsync的特性
- 支持拷貝特殊文件如鏈接文件、設備等
- 可以有排除指定文件或目錄同步功能,相當於tar的排除功能
- 可以做到保持原文件或,目錄的權限、時間、軟硬鏈接、主、組等所有屬性均不變
- 可以實現增量同步,即只同步發送變化的數據,因此數據傳輸效率很高
- 可以通過socket(進程方式)傳輸文件和數據(服務端和客戶端),遠程數據同步
- 支持匿名或認證(無需系統用戶)的進程模式傳輸,可實現方便安全的數據備份及鏡像
Rsync企業工作場景
兩台服務器之間同步數據
方案1:cron + rsync 定時備份針對內部人員,配置信息,發布代碼
方案2:sersync+rsync 或 inotify+rsync 實時備份,用戶所有數據
rsync工作方式
- 本地模式, 相當於cp
cp -a /etc/hosts /tmp/ # 把hosts文件拷貝到 /tmp目錄下 rsync -vzrtopg /etc/hosts /mnt/ # 等價於上一個 rsync -avz --delete /tmp/ /mnt/ # 刪除兩個文件中單個存在的文件,源和目標保持一致,這個慎用,除非必須要求兩個目錄文件文件保存一致
--delete 生產中不用和慎用刪除相關的操作,一旦刪除數據不可挽回
Rsync 作為客戶端詳細選項
進行備份時候,有末尾帶斜線和不帶斜線區別,帶斜線只備份該目錄下所有內容,不帶斜線包括目錄本身和目錄下所有內容
如: /data/mysql/ /data/mysql ,前者只備份mysql目錄下內容, 后者備份 mysql 目錄和目錄下所有內容
-v 詳細輸出,傳輸時的進度等信息
-z 傳輸是進行壓縮以提高傳輸效率
-a 歸檔模式,表示以遞歸方式傳輸文件,保持所有文件屬性,把下面的選項包了
-r 對子目錄以遞歸模式,即目錄下的所有目錄都是同樣傳輸
-t 保持文件時間信息
-o 保持文件主信息
-p 保持文件權限
-g 保持文件組信息
-P 顯示同步的過程與傳輸時的進度等信息
-D 保持設備文件信息
-l 保留軟鏈接
一般來講, -avz 就可以了
-e 使用信息協議,指定替代rsh和shell程序上
--exclude=PATTERN 指定排除必須的文件模式(和tar參數一樣)
--exclude-from=file(文件名所在的目錄文件)(和tar參數一樣)
--bwlimit= 限速,單位為k
--delete 讓目標目錄SRC和源目錄數據DST一致
備份需要考慮帶寬進行限速,時間選擇晚上用戶訪問少,rsync scp ftp 都有限速功能
遇到的工作故障:
1. 某DBA做數據同步,導致用戶無法訪問網站的問題。
問題原因:
白天時候進行數據庫同步備份,並沒有對備份進行帶寬限速,造成備份時候,占滿帶寬,用戶打不開網頁
解決方法:
選擇夜間用戶訪問量少的時候進行備份,以及備份時候進行備份帶寬限制,讓其不能占滿服務帶寬
dd if=/dev/zero of=test1 bs=1M count=128 # 當前目錄下創建 128M大小的 test1文件, 模擬測試數據 rsync -avz --bwlimit=10 /backup/ rsync_backup@172.16.1.41::backup/ --password-file=/etc/rsync.password # --bwlimit= 限速,單位是k/s
第二個模式: 使用遠端的shell
rsync -avz /etc/hosts -e 'ssh -p 22' root@10.0.0.31:/mnt # 把 /etc/hosts 文件通過 ssh 服務,推送到遠端服務器 10.0.0.31 以root角色接收,存放在/mnt下, 用戶@ip:目錄,其中兩個特殊符號@ 和 : , -p指定端口
第三個模式,以守護進程的方式傳輸數據(重點),采用這種模式
rsync 端口 873
守護進程: 持續運行的進程
demon 搭在備份服務器上,其他機器把備份文件推送到備份服務器,這個是大多數企業采用的方案
如何搭建demon,服務端?
1. 默認配置文件不存在,可以創建一個配置文件
touch /etc/rsyncd.conf # 在linux系統中,幾乎所有的配置文件都是這個格式
2. 編輯配置文件,並寫入以下配置信息, vim /etc/rsyncd.conf
##rysncd.conf start## uid = rsync # 主,在linux中進程和文件必須屬於主和組,遠端連接過來時候使用該主訪問文件 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 # 日志文件 [backup] # 配置模塊名 path = /backup # 服務器提供的訪問目錄 ignore errors # 忽略錯誤 read only = false # 可寫 list = false # 不可列表 host allow = 172.16.1.0/24 # 允許遠端連接的主機網段 host deny = 0.0.0.0/32 # 拒絕主機 auth users = rsync_backup # 獨立於系統的虛擬用戶,用於驗證 secrets file = /etc/rsync.password # 虛擬用戶名密碼 #rysnc_config_________________end
3. 添加用戶:
useradd rsync -s /sbin/nologin -M # 不允許登錄並不需要家目錄
4. 啟動rsync demon
rsync --daemon
5. 查看是否有這個進程:
ps -ef|grep rsync|grep -v grep # 進程是用root存在
6. 創建 /backup 目錄,更改用戶和組為配置文件中設定的主和組,不然遠端推送不過來
# low方法:把 這個目錄權限位 777,太危險,把配置文件中uid和gid都改為root mkdir /backup # 創建服務器提供的訪問目錄 chown rsync.rsync /backup/ # 用戶遠端推送使用 rsync身份 ll -d /backup/ # 檢查一下
7. 創建 /etc/rsync.password 文件,寫入: resync_backup:beimenchuixue
chmod 600 /etc/rsync.password # 存放密碼文件,縮小權限 # 這個文件是客戶端連接過來時候帶來的密碼beimenchuixue,用戶就可以不需要root密碼實現遠程推送文件,驗證用戶和密碼是以冒號作為分隔符,密碼是明文
8. 檢查端口:
lsof -i :873 # 查看端口是否開啟 或 netstat -lntup|grep 873
9. 讓其開機自啟動
echo '/usr/bin/rsync --daemon' >> /etc/rc.local cat /etc/rc.local # 檢查
客戶端:
1. 檢查是否有rsync服務
rpm -qa *rsync* rsync --version
2. 只需要生成密碼文件即可
echo 'beimenchuixue' >> /etc/rsync.password # 設置連接備份服務端密碼 cat /etc/rsync.password # 檢查 chmod 600 /etc/rsync.password # 最小化權限 ll /etc/rsync.password # 檢查
3. 創建 /backup目錄,對備份文件,首先要打包到這個目錄下,統一推送過去
mkdir -p /backup
測試:
客戶端
touch stu{01..100} # 在/backup下創建100個文件
推送1 :
rsync -avz /backup/ rsync_backup@172.16.1.41::backup/ --password-file=/etc/rsync.password
推送2:
rsync -avz /backup/ rsync://rsync_backup@172.16.1.41/backup/ --password-file=/etc/rsync.password
backup/ 模塊名,如果推到某個子目錄,直接在模塊后面跟子目錄,依賴於客戶端配置
在linux系統中,配置文件會加載到內存,修改配置文件需要重啟服務
pkill rsync # 結束進程 lsof -i :873 # 檢查進程是否結束 rsync --daemon # 啟動 lsof -i :873 # 檢查服務是否啟動
問題排錯:
1. @ERROR: chdir failed
服務器端對應模塊下沒有備份目錄
解決方法:
mkdir /backup # 創建這個模塊對應的目錄
2. rsync: mkstemp ".stu100.JWpxhq" (in backup) failed: Permission denied (13)
權限不夠
解決方法:
chown rsync.rsync /backup/ # 更改為 rsync需要的主和組 ll -d /backup/ # 檢查
3. @ERROR: invalid uid rsync
備份服務器rsync這個用戶不存在
解決方法:
useradd rsync -s /sbin/nologin -M # 添加這個用戶,不需要家目錄和不允許登錄 id rsync # 檢查
4. @ERROR: auth failed on module backup
模塊驗證失敗
解決方法:
客戶端和服務器端:
檢查客戶端 /etc/rsync.password ,注意文件中是有多余空格和敲錯的字符
檢查客戶端和服務端的 /etc/rsync.password 是否授權為600
cat -A /etc/rsync.password # 查看所有字符,包括空格結尾符號
5. rsync: failed to connect to 172.16.1.22: Connection refused (111)
解決方法: 服務端 rsync --daemon 沒開
ps -ef | grep rsync # 檢查 rsync --daemon # 啟動
如何對應多個模塊?
更改 /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 path = /backup ignore errors read only = false list = false host allow = 172.16.1.0/24 #host deny = 0.0.0.0/32 auth users = rsync_backup secrets file = /etc/rsync.password [backup] path = /backup [beimen] path = /beimen # 每個單獨的模塊,單獨有一個path,對應不同的推送過來的數據
修改配置的時候,需要時刻備份,出了問題可以快速復原
cp /etc/rsyncd.conf{,.$(date +%F)_v1} # 專業備份格式,加上備份時間和更改次數版本
假如想要排除一些文件如何做?
--exclude=文件名 # 排除單個文件
--exclude={filename1, filename2,...} 排除多個文件
--exclude={a..z} 排除連續的
--exclude=paichu.log 按文件排除
無差異同步
--delete
服務器端放了文件,推送的時候,以客戶端推送目錄為依據,客戶端有啥服務端就有啥,多余的刪除
拉取,以客戶端/backuo為依據
與這個無差異同步發生的血案:
視頻網站,推到服務器上上線發布,本地/backup只有當天發布的內容,服務器上卻有以前的所有文件,執行含 --delete 的rsync推送命令
結果: 服務器端刪除以前的所有,只有當天的了
相當於 rm -rf
提示: 非常危險,慎用
rsync三種工作模式:
1. 本地模式,相當於cp
2. 通道模式 -e指定用什么協議傳輸
rsync -avz /etc/hosts -e 'ssh -p 22' root@10.0.0.31:/mnt,配合ssh密鑰進行免密碼傳輸
3. daemon模式
提示:內網不需要加密,加密性能能有損失
跨機房,使用vpn(pptp, openvpn, ipsec)
rsync
優點:
- 增量備份,支持socket(deamon),集中備份(支持推拉,以客戶端為參照物)
- 可以利用ssh, vpn服務等加密傳輸遠程數據
缺點:
- 大量小文件同步時候,對比時間長,有時候rsync進程會停止
- 同步大文件,比如10G會出現中斷問題,未同步完成前,是隱藏文件,通過續傳等參數實現傳輸
- 一次性遠程拷貝可以用scp
如何檢查服務端防火牆是否阻擋?
telnet ip地址 端口
rsypnc服務配置過程總結:
服務器端:
1. 檢查rsync安裝包
rmp -qa rsync
2. 添加rsync服務用戶,管理本地目錄的
usradd rsync -s /sbin/nologin -M
3. 生成rsyncd.conf配置文件
vim rsyncd.conf 放入已經配置好的配置文本
4. 根據 rsyncd.conf 的auth users 配置賬號,用於遠程連接,並根據 secrets file 參數生成密碼文件
5. 為密碼文件配置權限
chmod 600 /etc/rsync.password ll /etc/rsync.password
6. 創建備份目錄,並授權rsync服務管理
mkdir -p /backup chown -R rsync.rsync /backup ll /backup
7. 啟動 rsync服務的daemon模式,接收其他服務器推送過來的數據
rsync --daemaon lsof -i :873
8. 加入開機自啟動
echo `/usr/bin/rsync --daemon` >> /etc/rc.local tail -1 /etc/rc.local
客戶端:
1. 生成服務器端需要的密碼文件
echo `beimenchuixue` > /etc/rysnc.password cat /etc/password
2. 為密碼文件配置權限
chmod 600 /etc/rsync.password ll /etc/rsync.password
測試:
往服務器推送文件,看能不能成功
rsync -avz /backup/ rsync_backup@172.16.1.41::backup --password-file=/etc/rsync.password
出錯誤排錯方式:
1. 看輸出結果
2. 看日志 /var/log/rsync.log
3. 熟悉部署流程
總結過程:
服務端:
1. 添加對備份文件操作的用戶,為了統一,客戶端和服務端統一名字
useradd rsync -s /sbin/nologin -M id rsync
2. 創建備份目錄 /backup
mkdir /backup
3. 把1步驟建立的用戶,授權 /backup目錄
chown -R rsync.rsync /backup/
4. 寫配置文件, /etc/rsyncd.conf
vim /etc/rsyncd.password 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 path = /backup ignore errors read only = false list = false host allow = 172.16.1.0/24 #host deny = 0.0.0.0/32 auth users = rsync_backup secrets file = /etc/rsync.password [backup] path = /backup
5. 寫密碼文件 /etc/rsync.password,rsync_backup這個只是用於客戶端驗證的用戶,讓其他人不可見
echo 'rsync_backup:beimenchuixue' > /etc/rsync.password
cat /etc/rsync.password
chmod 600 /etc/rsync.password
6. 啟動daemon,並將這條啟動寫入/etc/rc.local
rsync --daemon echo 'rsync --daemon' >> /etc/rc.local tail -1 /etc/rc.local
客戶端:
1. 編寫 /etc/rsync.password 文件,寫入密碼,讓其他人不可見
echo 'beimenchuixue' > /etc/rsync.password
chmod 600 /etc/rsync.password
2. -avz 備份上傳,--password-file指定密碼文件,本地文件和服務器的順序決定是推還是拉
mkdir /backup echo 'echo hello' > /backup/hello.sh # 創建測試文件 rsync -avz /backup/ rsync_backup@172.16.1.22::backup/ --password-file=/etc/rsync.password # v 具體腳本可以省略,表示顯示信息
3. 去backup服務器查看是否備份
過程程序化:
1. 一鍵配置rsync客戶端
#!/bin/sh # author: beimenchuixue # email: 42283556@qq.com # blog:Warning: http://www.cnblogs.com/2bjiujiu/ rsyncConf="/etc/rsyncd.conf" rsyncPid="/var/run/rsyncd.pid" rsyncPath="/backup" ServerPwdFile="/etc/rsync.password" rsyncUser="rsync" loginUser="beimenchuixue" loginPwd="123456" . /etc/init.d/functions function sureOK { [ $? -eq 0 ] && { action "$2 is" /bin/true } || { action "$2 is" /bin/false exit $? } } function hasInstallRsync { rsync --version &> /dev/null sureOK $? "hasInstallRsync" } # hasInstallRsync function rsyncConf { [ -f $rsyncConf ] && { cat /dev/null > $rsyncConf sureOK $? "init rsyncConf" } cat >>$rsyncConf<<EOF uid = $rsyncUser gid = $rsyncUser use chroot = no max connections = 200 timeout = 300 pid file = $rsyncPid lock file = /var/run/rsync.lock log file = /var/log/rsyncd.log ignore errors read only = false list = false # host allow = 172.16.1.0/24 # host deny=0.0.0.0/32 auth users = $loginUser secrets file = $ServerPwdFile [backup] path = $rsyncPath EOF sureOK $? "rsyncConf" } # rsyncConf function addRsyncUser { id $rsyncUser &> /dev/null [ $? -eq 0 ] || { useradd $rsyncUser -s /sbin/nologin -M } sureOK $? "addRsyncUser" } # addRsyncUser function initRsyncPath { [ -d $rsyncPath ] || { mkdir -p $rsyncPath sureOK $? "create $rsyncPath" } chown -R ${rsyncUser}.${rsyncUser} $rsyncPath sureOK $? "initRsyncPath" } # initRsyncPath function initServerRsyncPwdFile { [ -f $ServerPwdFile ] && { cat /dev/null > $ServerPwdFile sureOK $? "clear ServerRsyncPwdFile" } echo "$loginUser:$loginPwd" > $ServerPwdFile sureOK $? "write rsyncPwd" chmod 000 $ServerPwdFile } # initServerRsyncPwdFile function main_BeiMenChuiXue { hasInstallRsync rsyncConf addRsyncUser initRsyncPath initServerRsyncPwdFile } main_BeiMenChuiXue
2. rsync啟動腳本
#!/bin/sh # author: beimenchuixue # email: 42283556@qq.com # blog:Warning: http://www.cnblogs.com/2bjiujiu/ # chkconfig: 2345 98 25 rsyncPid="/var/run/rsyncd.pid" . /etc/init.d/functions function sureOK { [ $1 -eq 0 ] && { action "$2 is" /bin/true } || { action "$2 is" /bin/false exit $1 } } [ ${#} -eq 1 ] || { echo "$0 (start|stop|restart)" exit 1 } function startRsyncDaemon { [ -f $rsyncPid ] && { echo "rsync is running" sureOK 1 "start rsync" } rsync --daemon sureOK $? "start rsync" } # RsyncDaemon function stopRsyncDaemon { if [ ! -f $rsyncPid ]; then echo "rsync is stoping" sureOK 1 "stop rsync" else kill $(cat $rsyncPid) sleep 1 if [ -f $rsyncPid ]; then kill -9 $(cat $rsyncPid) sureOK $? "stop rsync" else sureOK 0 "stop rsync" fi fi } # stopRsyncDaemon function restartRsyncDaemon { stopRsyncDaemon startRsyncDaemon } case $1 in start) startRsyncDaemon ;; stop) stopRsyncDaemon ;; restart) restartRsyncDaemon ;; *) echo "$0 (start|stop|restart)" exit 3 esac