序言:如果我們後端有多臺網站服務器或者文件服務器,而且沒有好的文件同步機制,那麼當我們升級程序或者更新文件的時候,就需要每臺服務器或者目錄都要更新,這樣很容易出問題,並很容易導致兩邊的文件不一致,從而出現很多莫民其妙的問題。因此我們需要使用好的文件同步方式來實現幾個後端服務器文件的同步,目前廣泛採用的方案是使用rsync+inotify的方式來實現文件的觸發更新。原理是採用inotify來對文件進行監控,當監控到文件有文件發生改變的時候,就會調用rsync實現觸發式實時同步!本文就來詳細介紹金山的一個居於inotify+rsync進行二次開發實現文件同步的小工具sersync,能夠很方便的實現文件觸發式同步
inotify簡介
Inotify 是基於inode級別的文件系統監控技術,是一種強大的、細粒度的、異步的機制,它滿足各種各樣的文件監控需要,不僅限於安全和性能,內核要求2.6.13以上,inotify能監控非常多的文件系統事件,通過監控這些事件來監控文件是否發生變更,然後通過rsync來更新發生變更的文件,Inotify 可以監視的文件系統事件包括:
·IN_ACCESS,即文件被訪問
·IN_MODIFY,文件被 write
·IN_ATTRIB,文件屬性被修改,如 chmod、chown、touch 等
·IN_CLOSE_WRITE,可寫文件被 close
·IN_CLOSE_NOWRITE,不可寫文件被 close
·IN_OPEN,文件被 open
·IN_MOVED_FROM,文件被移走,如 mv
·IN_MOVED_TO,文件被移來,如 mv、cp
·IN_CREATE,創建新文件
·IN_DELETE,文件被刪除,如 rm
·IN_DELETE_SELF,自刪除,即一個可執行文件在執行時刪除自己
·IN_MOVE_SELF,自移動,即一個可執行文件在執行時移動自己
·IN_UNMOUNT,宿主文件系統被 umount
·IN_CLOSE,文件被關閉,等同於(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
·IN_MOVE,文件被移動,等同於(IN_MOVED_FROM | IN_MOVED_TO)
備註:上面的文件也包括目錄。
Rsync簡介
rsync,remote synchronize顧名思意就知道它是一款實現遠程同步功能的軟件,它在同步文件的同時,可以保持原來文件的權限、時間、軟硬鏈接等附加信息。rsync是用 “rsync 算法”提供了一個客戶機和遠程文件服務器的文件同步的快速方法,而且可以通過ssh方式來傳輸文件,這樣其保密性也非常好,另外它還是免費的軟件。
rsync 包括如下的一些特性:
能更新整個目錄和樹和文件系統;
有選擇性的保持符號鏈鏈、硬鏈接、文件屬於、權限、設備以及時間等;
對於安裝來說,無任何特殊權限要求;
對於多個文件來說,內部流水線減少文件等待的延時;
能用rsh、ssh 或直接端口做爲傳輸入端口;
支持匿名rsync 同步文件,是理想的鏡像工具;
sersync簡介
sersync利用inotify與rsync對服務器進行實時同步,其中inotify用於監控文件系統事件,rsync是目前廣泛使用的同步算法,其優點是隻對文件不同的部分進行操作,所以其優勢大大超過使用掛接文件系統的方式進行鏡像同步。由金山的周洋開發完成,是目前使用較多的文件同步工具之一。該工具和其他的工具相比有如下優點:
sersync是使用c++編寫,由於只同步發生更改的文件,因此比其他同步工具更節約時間、帶寬;
安裝方便、配置簡單;
使用多線程進行同步,能夠保證多個服務器實時保持同步狀態;
自帶出錯處理機制,通過失敗隊列對出錯的文件重新出錯,如果仍舊失敗,則每10個小時對同步失敗的文件重新同步;
自帶crontab功能,只需在xml配置文件中開啓,即可按您的要求,隔一段時間整體同步一次;
自帶socket與http協議擴展,你可以方便的進行二次開發;
sersync實現觸發式文件同步實戰
服務器文件同步圖
2.從服務器的安裝配置
a)安裝rsync
yum -y install rsync
b)配置rsync
Rsync配置文件的配置
cat /etc/rsyncd.conf
# Rsync configuration file
uid = root
gid = root
port = 873
max connections = 20000
use chroot = yes
timeout = 200
log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsyncd.lock
log format = %t %a %m %f %b
auth users = root
secrets file = /etc/rsyncd.secret
[test]
path = /data/test/
comment = "test directory file"
list = yes
read only = no
ignore errors = yes
hosts allow = 192.168.3.205
hosts deny = *
Rsync密碼文件的配置
cat /etc/rsyncd.secret
root:abc123@#$
chmod 600 /etc/rsyncd.secret
需要設置密碼文件爲600權限,不然同步的時候會報password file must not be other-accessible錯誤!
c)Rsync的啓動
Rsync的啓動有兩種方式,兩種方式哪一種都可以,讀者可以自行選擇:
一種是採用daemon的方式啓動:
/usr/bin/rsync --daemon --config=/etc/rsyncd.conf
另外一種是xinetd集成啓動方式:
chkconfig xined on
chkconfig rsync on
/etc/init.d/xinetd start
d)驗證rsync是否啓動
查看進程和端口是否存在
[root@test_machine test]# ps aux | grep rsync
root32750.00.065516472 ?Ss13:440:00 /usr/bin/rsync --daemon --config=/etc/rsyncd.conf
root33060.00.171812936 ?S14:490:00 /usr/bin/rsync --daemon --config=/etc/rsyncd.conf
[root@test_machine test]# netstat -lnp | grep rsync
tcp00 0.0.0.0:8730.0.0.0:*LISTEN3275/rsync
tcp00 :::873:::*LISTEN3275/rsync
3.主服務器的安裝配置
u安裝rsync
yum -y install rsync
安裝sersync
下載安裝文件
wget http://sersync.googlecode.com/files/sersync2.5_64bit_binary_stable_final.tar.gz
解壓並拷貝到安裝目錄
tar xzvf sersync2.5_64bit_binary_stable_final.tar.gz
mv GNU-Linux-x86 /usr/local/sersync
配置sersync
Sersync的配置
cat confxml.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<head version="2.5">
<host hostip="localhost" port="8008"></host>
<debug start="false"/>
<fileSystem xfs="false"/>
<filter start="false">
<exclude expression="(.*)\.svn"></exclude>
<exclude expression="(.*)\.gz"></exclude>
<exclude expression="^info/*"></exclude>
<exclude expression="^static/*"></exclude>
</filter>
<inotify>
<delete start="true"/>
<createFolder start="true"/>
<createFile start="false"/>
<closeWrite start="true"/>
<moveFrom start="true"/>
<moveTo start="true"/>
<attrib start="true"/>
<modify start="true"/>
</inotify>
<sersync>
<localpath watch="/data/test">
<!—-設置監控的目錄-->
<remote ip="192.168.3.203" name="test"/>
<!—設置從服務器的IP-->
<!--<remote ip="192.168.8.39" name="tongbu"/>-->
<!--<remote ip="192.168.8.40" name="tongbu"/>-->
</localpath>
<rsync>
<commonParams params="-artuz"/>
<auth start="true" users="root" passwordfile="/etc/rsyncd.secret"/>
<!—-設置同步的用戶名和密碼文件-->
<userDefinedPort start="true" port="873"/><!-- port=874 -->
<!—-設置rsync的端口,要和從那邊開啓的端口一致-->
<timeout start="false" time="100"/><!--timeout=100 -->
<ssh start="false"/>
</rsync>
<failLog path="/tmp/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
<crontab start="true" schedule="300"><!--600mins-->
<!—-設置300分鐘全部同步一次-->
<crontabfilter start="false">
<exclude expression="*.php"></exclude>
<exclude expression="info/*"></exclude>
</crontabfilter>
</crontab>
<plugin start="false" name="command"/>
</sersync>
<plugin name="command">
<param prefix="/bin/sh" suffix="" ignoreError="true"/><!--prefix /opt/tongbu/mmm.sh suffix-->
<filter start="false">
<include expression="(.*)\.php"/>
<include expression="(.*)\.sh"/>
</filter>
</plugin>
</head>
密碼文件的配置
cat /etc/rsyncd.secret
abc123@#$
主服務器的密碼配置文件不需要用戶,如果添加用戶的話同步的時候會報
rsync error: error starting client-server protocol (code 5) at main.c(1296) [sender=2.6.8]錯誤
啓動sersync
/usr/local/sersync/sersync2 -d -r -o /usr/local/sersync/confxml.xml
將上面的命令添加進/etc/rc.local,以後重啓系統以後才能正常同步
腳本監控sersync
因爲有的時候sersync腳本會自動關掉,因此需要寫一個腳本自動的去檢測該進程是否存在,不存在就啓動,腳本內容如下:
cat /var/script/check_sersync.sh
#!/bin/bash
#Purpose: Check sersync whether it is alive
#Author: Carl Zhang
SERSYNC="/usr/local/sersync/sersync2"
CONF_FILE="/usr/local/sersync/confxml.xml"
STATUS=$(ps aux |grep 'sersync2'|grep -v 'grep'|wc -l)
if [ $STATUS -eq 0 ];
then
$SERSYNC -d -r -o $CONF_FILE &
else
exit 0;
fi
腳本寫好以後,添加到計劃任務中去
*/5 * * * * /var/script/check_sersync.sh > /dev/null 2>&1
總結:通過以上幾步以後,你從服務器的/data/test就能夠從主服務器實時更新,升級的時候只升級主服務器的文件,從服務器也會自動同步過去,減少你的工作量以及出錯的概率