1.1 什麼是rsync
rsync是一個遠程數據同步工具,可經過LAN/WAN快速同步多臺主機間的文件。它使用所謂的「Rsync演算法」來使本地和遠程兩個主機之間的文件達到同步,這個算法只傳送兩個文件的不一樣部分,而不是每次都整份傳送,所以速度至關快。因此一般能夠做爲備份工具來使用。linux
運行Rsync server的機器也叫backup server,一個Rsync server可同時備份多個client的數據;也能夠多個Rsync server備份一個client的數據。Rsync能夠搭配ssh甚至使用daemon模式。Rsync server會打開一個873的服務通道(port),等待對方rsync鏈接。鏈接時,Rsync server會檢查口令是否相符,若經過口令查覈,則能夠開始進行文件傳輸。第一次連通完成時,會把整份文件傳輸一次,下一次就只傳送二個文件之間不一樣的部份。正則表達式
基本特色:算法
- 能夠鏡像保存整個目錄樹和文件系統;
- 能夠很容易作到保持原來文件的權限、時間、軟硬連接等;
- 無須特殊權限便可安裝;
- 優化的流程,文件傳輸效率高;
- 可使用rcp、ssh等方式來傳輸文件,固然也能夠經過直接的socket鏈接;
- 支持匿名傳輸。
命令語法:
rsync的命令格式能夠爲如下六種:
rsync [OPTION]… SRC DEST
rsync [OPTION]… SRC [USER@]HOST:DEST
rsync [OPTION]… [USER@]HOST:SRC DEST
rsync [OPTION]… [USER@]HOST::SRC DEST
rsync [OPTION]… SRC [USER@]HOST::DEST
rsync [OPTION]… rsync://[USER@]HOST[:PORT]/SRC [DEST]shell
對應於以上六種命令格式,咱們能夠總結rsync有2種不一樣的工做模式:安全
- shell模式:使用遠程shell程序(如ssh或rsh)進行鏈接。當源路徑或目的路徑的主機名後面包含一個冒號分隔符時使用這種模式,rsync安裝完成後就能夠直接使用了,無所謂啓動。(目前沒有嘗試過這個方法)
- daemon模式:使用TCP直接鏈接rsync daemon。當源路徑或目的路徑的主機名後面包含兩個冒號,或使用rsync://URL時使用這種模式,無需遠程shell,但必須在一臺機器上啓動rsync daemon,默認端口873,這裏能夠經過
rsync --daemon
使用獨立進程的方式,或者經過xinetd超級進程來管理rsync後臺進程。
當rsync做爲daemon運行時,它須要一個用戶身份。若是你但願啓用chroot,則必須以root的身份來運行daemon,監聽端口,或設定文件屬主;若是不啓用chroot,也能夠不使用root用戶來運行daemon,但該用戶必須對相應的模塊擁有讀寫數據、日誌和lock file的權限。當rsync以daemon模式運行時,它還須要一個配置文件——rsyncd.conf。修改這個配置後沒必要重啓rsync daemon,由於每一次的client鏈接都會去從新讀取該文件。服務器
咱們通常把DEST遠程服務器端成爲rsync Server,運行rsync命令的一端SRC稱爲Client。網絡
安裝:
rsync在CentOS6上默認已經安裝,若是沒有則可使用yum install rsync -y
,服務端和客戶端是同一個安裝包。app
1
|
|
1.2 同步測試
關於rsync
命令的諸多選項說明,見另一篇文章rsync與inotifywait命令和配置選項說明。框架
1.2.1 本機文件夾同步
1
|
# rsync -auvrtzopgP --progress
/root/ /tmp/rsync_bak/
|
會看到從/root/
傳輸文件到/tmp/rsync_bak/
的列表和速率,再運行一次會看到sending incremental file list下沒有複製的內容,能夠在/root/下touch
某一個文件再運行看到只同步了修改過的文件。
上面須要考慮如下問題:
- 刪除/root/下的文件不會同步刪除/tmp/rsync_bak,除非加入
--delete
選項 - 文件訪問時間等屬性、讀寫等權限、文件內容等有任何變更,都會被認爲修改
- 目標目錄下若是文件比源目錄還新,則不會同步
- 源路徑的最後是否有斜槓有不一樣的含義:有斜槓,只是複製目錄中的文件;沒有斜槓的話,不但要複製目錄中的文件,還要複製目錄自己
1.3 同步到遠程服務器
在服務器間rsync傳輸文件,須要有一個是開着rsync的服務,而這一服務須要兩個配置文件,說明當前運行的用戶名和用戶組,這個用戶名和用戶組在改變文件權限和相關內容的時候有用,不然有時候會出現提示權限問題。配置文件也說明了模塊、模塊化管理服務的安全性,每一個模塊的名稱都是本身定義的,能夠添加用戶名密碼驗證,也能夠驗證IP,設置目錄是否可寫等,不一樣模塊用於同步不一樣需求的目錄。
1.3.1 服務端配置文件
/etc/rsyncd.conf:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
#2014-12-11 by Sean
uid=root
gid=root
use
chroot=no
max
connections=10
timeout=600
strict
modes=yes
port=873
pid
file=/var/run/rsyncd.pid
lock
file=/var/run/rsyncd.lock
log
file=/var/log/rsyncd.log
[module_test]
path=/tmp/rsync_bak2
comment=rsync test logs
auth
users=sean
uid=sean
gid=sean
secrets
file=/etc/rsyncd.secrets
read
only=no
list=no
hosts
allow=172.29.88.204
hosts
deny=0.0.0.0/32
|
這裏配置socket方式傳輸文件,端口873,[module_test]開始定義一個模塊,指定要同步的目錄(接收)path,受權用戶,密碼文件,容許哪臺服務器IP同步(發送)等。關於配置文件中選項的詳細說明依然參考rsync與inotifywait命令和配置選項說明。
經測試,上述配置文件每行後面不能使用#
來來註釋
/etc/rsyncd.secrets:
1
|
sean:passw0rd
|
一行一個用戶,用戶名:密碼。請注意這裏的用戶名和密碼與操做系統的用戶名密碼無關,能夠隨意指定,與/etc/rsyncd.conf
中的auth users
對應。
修改權限:chmod 600 /etc/rsyncd.d/rsync_server.pwd
。
1.3.2 服務器啓動rsync後臺服務
修改/etc/xinetd.d/rsync
文件,disable 改成 no
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# default: off
# description: The rsync server is a good addition to an ftp server, as it \
# allows crc checksumming etc.
service rsync
{
4
disable = no
4
flags = IPv6
4
socket_type = stream
4
wait = no
4
user = root
4
server = /usr/bin/rsync
4
server_args = --daemon
4log_on_failure += USERID
}
|
執行service xinetd restart
會一塊兒重啓rsync後臺進程,默認使用配置文件/etc/rsyncd.conf
。也可使用/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
。
爲了以防rsync寫入過多的無用日誌到/var/log/message
(容易塞滿從而錯太重要的信息),建議註釋掉/etc/xinetd.conf
的success:
1
|
|
若是使用了防火牆,要添加容許IP到873端口的規則。
1
2
3
|
|
建議關閉selinux
,可能會因爲強訪問控制致使同步報錯。
1.3.3 客戶端測試同步
單向同步時,客戶端只須要一個包含密碼的文件。
/etc/rsync_client.pwd:
1
|
passw0rd
|
chmod 600 /etc/rsync_client.pwd
命令:
將本地/root/
目錄同步到遠程172.29.88.223的/tmp/rsync_bak2目錄(module_test指定):
1
|
/usr/bin/rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd /root/ sean@172.29.88.223::module_test
|
固然你也能夠將遠程的/tmp/rsync_bak2目錄同步到本地目錄/root/tmp:
1
|
/usr/bin/rsync -auvrtzopgP --progress --password-file=/etc/rsync_client.pwd sean@172.29.88.223::module_test /root/
|
從上面兩個命令能夠看到,其實這裏的服務器與客戶端的概念是很模糊的,rsync daemon都運行在遠程172.29.88.223上,第一條命令是本地主動推送目錄到遠程,遠程服務器是用來備份的;第二條命令是本地主動向遠程索取文件,本地服務器用來備份,也能夠認爲是本地服務器恢復的一個過程。
1.4 rsync不足
與傳統的cp、tar備份方式相比,rsync具備安全性高、備份迅速、支持增量備份等優勢,經過rsync能夠解決對實時性要求不高的數據備份需求,例如按期的備份文件服務器數據到遠端服務器,對本地磁盤按期作數據鏡像等。
隨着應用系統規模的不斷擴大,對數據的安全性和可靠性也提出的更好的要求,rsync在高端業務系統中也逐漸暴露出了不少不足,首先,rsync同步數據時,須要掃描全部文件後進行比對,進行差量傳輸。若是文件數量達到了百萬甚至千萬量級,掃描全部文件將是很是耗時的。並且正在發生變化的每每是其中不多的一部分,這是很是低效的方式。其次,rsync不能實時的去監測、同步數據,雖然它能夠經過crontab方式進行觸發同步,可是兩次觸發動做必定會有時間差,這樣就致使了服務端和客戶端數據可能出現不一致,沒法在應用故障時徹底的恢復數據。基於以上緣由,rsync+inotify組合出現了!
2. inotify-tools
2.1 什麼是inotify
inotify是一種強大的、細粒度的、異步的文件系統事件監控機制,Linux內核從2.6.13開始引入,容許監控程序打開一個獨立文件描述符,並針對事件集監控一個或者多個文件,例如打開、關閉、移動/重命名、刪除、建立或者改變屬性。
CentOS6天然已經支持:
使用ll /proc/sys/fs/inotify
命令,是否有如下三條信息輸出,若是沒有表示不支持。
1
2
3
4
|
total 0
-rw-r--r--
1 root root 0 Dec 11 15:23 max_queued_events
-rw-r--r--
1 root root 0 Dec 11 15:23 max_user_instances
-rw-r--r--
1 root root 0 Dec 11 15:23 max_user_watches
|
/proc/sys/fs/inotify/max_queued_evnets
表示調用inotify_init時分配給inotify instance中可排隊的event的數目的最大值,超出這個值的事件被丟棄,但會觸發IN_Q_OVERFLOW事件。/proc/sys/fs/inotify/max_user_instances
表示每個real user ID可建立的inotify instatnces的數量上限。/proc/sys/fs/inotify/max_user_watches
表示每一個inotify instatnces可監控的最大目錄數量。若是監控的文件數目巨大,須要根據狀況,適當增長此值的大小。
inotify-tools:
inotify-tools是爲linux下inotify文件監控工具提供的一套C的開發接口庫函數,同時還提供了一系列的命令行工具,這些工具能夠用來監控文件系統的事件。 inotify-tools是用c編寫的,除了要求內核支持inotify外,不依賴於其餘。inotify-tools提供兩種工具,一是inotifywait
,它是用來監控文件或目錄的變化,二是inotifywatch
,它是用來統計文件系統訪問的次數。
下載inotify-tools-3.14-1.el6.x86_64.rpm,經過rpm包安裝:
1
2
3
4
5
6
|
# rpm -ivh /apps/crm/soft_src/inotify-tools-3.14-1.el6.x86_64.rpm
warning: /apps/crm/soft_src/inotify-tools
-3.14-1.el6.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 4026433f: NOKEY
Preparing...
########################################### [100%]
1:inotify-tools ########################################### [100%]
# rpm -qa|grep inotify
inotify-tools
-3.14-1.el5.x86_64
|
2.2 inotifywait使用示例
監控/root/tmp目錄文件的變化:
1
2
|
/usr/bin/inotifywait -mrq --timefmt '
%Y/%m/%d-%H:%M:%S' --format '%T %w %f' \
-e modify,delete,create,move,attrib /root/tmp/
|
上面的命令表示,持續監聽/root/tmp
目錄及其子目錄的文件變化,監聽事件包括文件被修改、刪除、建立、移動、屬性更改,顯示到屏幕。執行完上面的命令後,在/root/tmp
下建立或修改文件都會有信息輸出:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
2014/12/11-15:40:04 /root/tmp/ new.txt
2014/12/11-15:40:22 /root/tmp/ .new.txt.swp
2014/12/11-15:40:22 /root/tmp/ .new.txt.swx
2014/12/11-15:40:22 /root/tmp/ .new.txt.swx
2014/12/11-15:40:22 /root/tmp/ .new.txt.swp
2014/12/11-15:40:22 /root/tmp/ .new.txt.swp
2014/12/11-15:40:23 /root/tmp/ .new.txt.swp
2014/12/11-15:40:31 /root/tmp/ .new.txt.swp
2014/12/11-15:40:32 /root/tmp/ 4913
2014/12/11-15:40:32 /root/tmp/ 4913
2014/12/11-15:40:32 /root/tmp/ 4913
2014/12/11-15:40:32 /root/tmp/ new.txt
2014/12/11-15:40:32 /root/tmp/ new.txt~
2014/12/11-15:40:32 /root/tmp/ new.txt
...
|
3. rsync組合inotify-tools完成實時同步
這一步的核心其實就是在客戶端建立一個腳本rsync.sh
,適用inotifywait
監控本地目錄的變化,觸發rsync
將變化的文件傳輸到遠程備份服務器上。爲了更接近實戰,咱們要求一部分子目錄不一樣步,如/root/tmp/log
和臨時文件。
3.1 建立排除在外不一樣步的文件列表
排除不須要同步的文件或目錄有兩種作法,第一種是inotify監控整個目錄,在rsync中加入排除選項,簡單;第二種是inotify排除部分不監控的目錄,同時rsync中也要加入排除選項,能夠減小沒必要要的網絡帶寬和CPU消耗。咱們選擇第二種。
3.1.1 inotifywait排除
這個操做在客戶端進行,假設/tmp/src/mail/2014/
以及/tmp/src/mail/2015/cache/
目錄下的全部文件不用同步,因此不須要監控,/tmp/src/
下的其餘文件和目錄都同步。(其實對於打開的臨時文件,能夠不監聽modify
時間而改爲監聽close_write
)
inotifywait排除監控目錄有--exclude <pattern>
和--fromfile <file>
兩種格式,而且能夠同時使用,但主要前者能夠用正則,然後者只能是具體的目錄或文件。
1
2
3
|
@
|
使用fromfile
格式只能用絕對路徑,不能使用諸如*
正則表達式去匹配,@
表示排除。
若是要排除的格式比較複雜,必須使用正則,那隻能在inotifywait
中加入選項,如--exclude '(.*/*\.log|.*/*\.swp)$|^/tmp/src/mail/(2014|201.*/cache.*)'
,表示排除/tmp/src/mail/如下的2014目錄,和全部201*目錄下的帶cache的文件或目錄,以及/tmp/src目錄下全部的以.log或.swp結尾的文件。
3.1.2 rsync排除
使用inotifywait排除監控目錄的狀況下,必須同時使用rsync排除對應的目錄,不然只要有觸發同步操做,必然會致使不應同步的目錄也會同步。與inotifywait相似,rsync的同步也有--exclude
和--exclude-from
兩種寫法。
我的仍是習慣將要排除同步的目錄卸載單獨的文件列表裏,便於管理。使用--include-from=FILE
時,排除文件列表用絕對路徑,但FILE裏面的內容請用相對路徑,如:/etc/rsyncd.d/rsync_exclude.lst
:
1
2
3
4
5
6
7
8
9
10
11
|
mail/
2014/
mail/
201*/201*/201*/.??*
mail??*
src
/*.html*
src/js/
src/ext3/
src/2014/20140[1-9]/
src/201*/
201*/201*/.??*
membermail/
membermail??*
membermail/
201*/201*/201*/.??*
|
排除同步的內容包括,mail下的2014目錄,相似2015/201501/20150101/下的臨時或隱藏文件,等。
3.2 客戶端同步到遠程的腳本rsync.sh
下面是一個完整的同步腳本,請根據須要進行裁剪,rsync.sh
:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
#rsync auto sync script with inotify
#2014-12-11 Sean
#variables
current_date=$(date +%Y%m%d_%H%M%S)
source_path=/tmp/src/
log_file=/var/
log/rsync_client.log
#rsync
rsync_server=172.29.88.223
rsync_user=sean
rsync_pwd=/etc/rsync_client.pwd
rsync_module=module_test
INOTIFY_EXCLUDE=
'(.*/*\.log|.*/*\.swp)$|^/tmp/src/mail/(2014|20.*/.*che.*)'
RSYNC_EXCLUDE=
'/etc/rsyncd.d/rsync_exclude.lst'
#rsync client pwd check
if [ ! -e ${rsync_pwd} ];then
echo -e "rsync client passwod file ${rsync_pwd} does not exist!"
exit 0
fi
#inotify_function
inotify_fun(){
/usr/bin/inotifywait -mrq --timefmt
'%Y/%m/%d-%H:%M:%S' --format '%T %w %f' \
--exclude
${INOTIFY_EXCLUDE} -e modify,delete,create,move,attrib ${source_path} \
|
while read file
do
/usr/bin/rsync -auvrtzopgP --exclude-from=
${RSYNC_EXCLUDE} --progress --bwlimit=200 --password-file=${rsync_pwd} ${source_path} ${rsync_user}@${rsync_server}::${rsync_module}
done
}
#inotify log
inotify_fun >>
${log_file} 2>&1 &
|
--bwlimit=200
用於限制傳輸速率最大200kb,由於在實際應用中發現若是不作速率限制,會致使巨大的CPU消耗。
在客戶端運行腳本# ./rsync.sh
便可實時同步目錄。
疑問
對於rsync的同步海量存在一個疑問,假如個人文件數不少即便在排除不監控和不一樣步目錄的狀況下依然有10萬個文件,僅文件列表就達10M,那麼豈不是每一次有文件產生或修改都會觸發同步,很容易致使大部分狀況下在傳輸文件列表和進行列表的比對,僅同步一個小文件而使用的網絡帶寬和CPU代價很高,特別是網絡情況不佳時,上一次的列表還未傳送完,又有新的文件產生觸發發送文件列表。不知道rsync內部有沒有這樣的處理?
其餘功能:雙向同步、sersync2實時同步多遠程服務器