Linux下Rsync+sersync實現資料實時同步
本教程實現的是Linux伺服器之間自動同步檔案或目錄的功能,網上有很多這方面的教程,大體有兩種途徑
(1)Rsync+inotify-tools
(2)Rsync+sersync
本教程採用第二種實現.下面先簡單介紹幾個專案中用到的軟體或概念.
Rsync
Rsync(remote synchronize)是一個遠端資料同步工具,可通過LAN/WAN快速同步多臺主機間的檔案。Rsync使用所謂的“Rsync演算法”來使本地和遠 程兩個主機之間的檔案達到同步,這個演算法只傳送兩個檔案的不同部分,而不是每次都整份傳送,因此速度相當快。
Rsync的基本特點如下:
- 1.可以映象儲存整個目錄樹和檔案系統;
- 2.可以很容易做到保持原來檔案的許可權、時間、軟硬連結等;
- 3.無須特殊許可權即可安裝;
- 4.優化的流程,檔案傳輸效率高;
- 5.可以使用rsh、ssh等方式來傳輸檔案,當然也可以通過直接的socket連線;
- 6.支援匿名傳輸。
inotify
Inotify是一種檔案變化通知機制,linux核心從2.6.13起,加入了Inotify支援,通過Inotify可以監控檔案系統中新增,刪除,修改,移動等各種事件,利用這個核心介面,第三方軟體就可以監控檔案系統下檔案的各種變化情況,而inotify-tools正是實施這樣監控的軟體。
inotify 的實現有幾款軟體
注意:大前提rsync daemon 服務配置成功,可以在rsync客戶端推送拉取資料,然後才能配置inotify服務。
- 1)inotify-tools,
- 2)sersync(金山周洋)
- 3)lsyncd
Rsync+inotify組合的起源
Rsync(remote sync)遠端同步工具,通過rsync可以實現對遠端伺服器資料的增量備份同步,但rsync自身也有瓶頸,同步資料時,rsync採用核心演算法對遠端伺服器的目標檔案進行比對,只進行差異同步。我們可以想象一下,如果伺服器的檔案數量達到了百萬甚至千萬量級,那麼檔案對比將是非常耗時的。而且發生變化的往往是其中很少的一部分,這是非常低效的方式。inotify的出現,可以緩解rsync不足之處,取長補短
為什麼要用Rsync+sersync架構
Rsync+Inotify-tools
(1)Inotify-tools只能記錄下被監聽的目錄發生了變化(包括增加、刪除、修改),並沒有把具體是哪個檔案或者哪個目錄發生了變化記錄下來;
(2)rsync在同步的時候,並不知道具體是哪個檔案或者哪個目錄發生了變化,每次都是對整個目錄進行同步,當資料量很大時,整個目錄同步非常耗時(rsync要對整個目錄遍歷查詢對比檔案),因此,效率很低。
Rsync+sersync
(1)sersync可以記錄下被監聽目錄中發生變化的(包括增加、刪除、修改)具體某一個檔案或某一個目錄的名字;
(2)rsync在同步的時候,只同步發生變化的這個檔案或者這個目錄(每次發生變化的資料相對整個同步目錄資料來說是很小的,rsync在遍歷查詢比對檔案時,速度很快),因此,效率很高。
小結:
當同步的目錄資料量不大時,建議使用Rsync+Inotify-tools;當資料量很大(幾百G甚至1T以上)、檔案很多時,建議使用Rsync+sersync。
——————————————————————————————————
什麼是xinetd
extended internet daemon
xinetd是新一代的網路守護程序服務程式,又叫超級Internet伺服器,常用來管理多種輕量級Internet服務。
xinetd提供類似於inetd+tcp_wrapper的功能,但是更加強大和安全。
—xinetd的特色
1) 強大的存取控制功能
— 內建對惡意使用者和善意使用者的差別待遇設定。
— 使用libwrap支援,其效能更甚於tcpd。
— 可以限制連線的等級,基於主機的連線數和基於服務的連線數。
— 設定特定的連線時間。
— 將某個服務設定到特定的主機以提供服務。
2) 有效防止DoS攻擊
— 可以限制連線的等級。
— 可以限制一個主機的最大連線數,從而防止某個主機獨佔某個服務。
— 可以限制日誌檔案的大小,防止磁碟空間被填滿。
3) 強大的日誌功能
— 可以為每一個服務就syslog設定日誌等級。
— 如果不使用syslog,也可以為每個服務建立日誌檔案。
— 可以記錄請求的起止時間以決定對方的訪問時間。
— 可以記錄試圖非法訪問的請求。
4) 轉向功能
可以將客戶端的請求轉發到另一臺主機去處理。
5) 支援IPv6
xinetd自xinetd 2.1.8.8pre*起的版本就支援IPv6,可以通過在./configure指令碼中使用with-inet6 capability選項來完成。
注意,要使這個生效,核心和網路必須支援IPv6。IPv4仍然被支援。
6) 與客戶端的互動功能
無論客戶端請求是否成功,xinetd都會有提示告知連線狀態。
—xinetd使用場景
原則上任何系統服務都可以使用xinetd,然而最適合的應該是那些常用的網路服務,同時,這個服務的請求數目和頻繁程度不會太高。像DNS和Apache就不適合採用這種方式,而像FTP、Telnet、SSH等就適合使用xinetd模式
專案實戰
伺服器 | 系統版本 | 處理器位數 | IP |
---|---|---|---|
源伺服器 | Ubuntu 17.04 | 64位 | 192.168.4.35 |
目標伺服器 | CentOS Linux 7 (Core) | 64位 | 192.168.0.151 |
目標伺服器配置
目標伺服器配置
(1)關閉SELINUX
[[email protected] ~]# vi /etc/sysconfig/selinux
#SELINUX=enforcing #註釋掉
SELINUX=disabled #增加
重啟系統
或者
[[email protected] ~]# setenforce 0 #臨時關閉(不用重啟機器)立即生效
注意:ubuntu下selinux路徑與上述的centos7不同,需執行如下命令
vi /etc/selinux/config ,將SELINUX=enforcing改為SELINUX=disabled 後重啟機器即可
(2)開啟防火牆tcp 873埠(Rsync預設埠)
[[email protected] ~]# vi /etc/sysconfig/iptables #編輯防火牆配置檔案
-A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 873 -j ACCEPT #新增到預設的22埠這條規則的下面,如下所示:
\######################################
\# Firewall configuration written by system-config-firewall
\# Manual customization of this file is not recommended.
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -m state –state ESTABLISHED,RELATED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 22 -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT
-A INPUT -m state –state NEW -m tcp -p tcp –dport 3306 -j ACCEPT
-A INPUT -j REJECT –reject-with icmp-host-prohibited
-A FORWARD -j REJECT –reject-with icmp-host-prohibited
COMMIT
\#####################################
/etc/init.d/iptables restart #最後重啟防火牆使配置生效
注意:
我在centos 7下的/etc/sysconfig未找到iptables 只有ip6tables-config ,iptables-config .這是因為centos 7中iptables已不再是預設的防火牆了.可通過
systemctl stop firewalld
systemctl disable firewalld
關閉centos7的防火牆.至於centos 7如何配置埠過濾,請自行百度.本案例是虛擬機器裝的centos7,用於學習練手,不存在安全的考慮.所以,直接關閉了防火牆,不做配置.
(3)檢查目標機是否安裝rsync
[[email protected] sysconfig]# whereis rsync
rsync: /usr/bin/rsync /usr/share/man/man1/rsync.1.gz #說明已經安裝了
若未安裝執行一下命令安裝:
yum install rsync
(4)編輯rsync配置檔案
[[email protected] sysconfig]# vi /etc/rsyncd.conf #建立配置檔案,新增以下程式碼
port=873
uid=root
gid=root
max connections=36000
use chroot=no
log file=/var/log/rsyncd.log
log format = %t %a %m %f %b
pid file=/var/run/rsyncd.pid
lock file=/var/run/rsyncd.lock
motd file = /etc/rsyncd.motd
timeout = 600
[sync_sms]
path=/usr/local/tomcat-app/webapps/
list=yes
comment =sms sync
ignore errors = yes
read only = no
hosts allow = *
#hosts deny = *
auth users = root
secrets file = /etc/rsyncd.secrets
使用者組最好設定為root,不然檔案許可權同步過去的時候會變化
- secrets file這個是配置同步的密碼檔案的。
- path是配置同步的目錄,
- hosts allow是允許同步的主機,
- hosts deny:拒絕同步的主機
(4)建立rsync傳輸過程中的認證檔案 ,即在secrets file指定的使用者密碼檔案
vim /etc/rsyncd.secrets 內容格式:使用者名稱:密碼
新增如下內容:
root:coolgirl
或者執行
echo “user:password” >> /etc/rsync.passwd
把內容追加到rsync.passwd末尾
然後,更改檔案的讀寫許可權為600
chmod 600 /etc/rsync.passwd
(5)建立同步目錄,即上述rsyncd.conf中[sync_sms]模組下path指定的路徑
mkdir -p /usr/local/tomcat-app/webapps/
(6)檢查並安裝xinetd(關於xinetd的介紹,請參照上文)
檢查系統是否已經安裝xinetd
[[email protected] webapps]# whereis xinetd
xinetd: /usr/sbin/xinetd /etc/xinetd.d /etc/xinetd.conf /usr/share/man/man8/xinetd.8.gz #說明已經安裝
否則執行安裝
yum -y install xinetd
(9)配置rsync以xinetd方式執行
[[email protected] webapps]# vi /etc/xinetd.d/rsync
新增如下內容:
service rsync
{
disable =no //使其隨xinetd啟動而啟動
wait =no
socket_type =stream
user =root
server =/usr/bin/rsync
server_args = --daemon #設定成守護程序
log_on_failure += USERID
}
注意:有的系統rsync是不存在的,可以執行上述命令建立並新增.xinetd的配置/etc/xinetd.conf 已配置包含了 /etc/xinetd.d/下的所有配置資訊
(9)啟動rsync與xinetd服務
systemctl start xinetd #啟動xinetd服務
systemctl enable xinetd #將xinetd服務加入開機項
rsync –daemon –config=/etc/rsyncd.conf #載入配置檔案rsyncd.conf啟動rsync服務
說明:–daemon 引數表示 啟動rsync守護程序
(7)配置rsync開機自啟動
echo “rsync –daemon –config=/etc/rsyncd.conf” >> /etc/rc.d/rc.local
———–截止目前,目標伺服器已經配置完成了—————–
源伺服器配置
(2)安裝sersync
1>解壓
tar -zxvf sersync2.5.4_64bit_binary_stable_final.tar.gz
GNU-Linux-x86 #解壓後的內容
sersync2.5.4_64bit_binary_stable_final.tar.gz
2>建立sersync的家目錄如下:
mkdir /usr/local/sersync
mkdir /usr/local/sersync/conf
mkdir /usr/local/sersync/bin
mkdir /usr/local/sersync/log
3>進入sersync解壓目錄,將內容拷貝到新建的sersync家目錄中如下:
cd GNU-Linux-x86/
cp confxml.xml /usr/local/sersync/conf
cp sersync2 /usr/local/sersync/bin
4>建立密碼檔案
密碼需和目標伺服器配置的一致,且不需要使用者名稱.將該檔案的許可權也更改為600
echo “coolgirl” >> /etc/rsync.passwd
chmod 600 /etc/rsync.passwd
5>配置剛剛拷貝過來的config.xml ,路徑/usr/local/sersync/conf/config.xml
cp config.xml config.xml.bak #配置前提前備份一下
配置詳情介紹,可參照以下示例.
<?xml version="1.0" encoding="UTF-8"?>
<head version="2.5">
<!--設定本地IP和埠-->
<host hostip="localhost" port="8008"></host>
<!--開啟DUBUG模式-->
<debug start="false"/>
<!--開啟xfs檔案系統 -->
<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="false"/>
<createFolder start="true"/>
<createFile start="false"/>
<closeWrite start="true"/>
<moveFrom start="true"/>
<moveTo start="true"/>
<attrib start="false"/>
<modify start="true"/>
</inotify>
<!--本地同步的目錄路徑-->
<sersync>
<localpath watch="/home/jing/projects/svn">
<!--遠端IP和rsync模組名 -->
<remote ip="192.168.0.151" name="sync_sms"/>
<!--<remote ip="192.168.8.39" name="tongbu"/>-->
<!--<remote ip="192.168.8.40" name="tongbu"/>-->
</localpath>
<rsync>
<!--rsync指令引數-->
<commonParams params="-auvzP"/>
<!-- rsync同步認證-->
<auth start="true" users="root" passwordfile="/etc/rsync.passwd"/>
<!--設定rsync遠端服務埠,遠端非預設埠則需開啟自定義-->
<userDefinedPort start="false" port="874"/><!-- port=874 -->
<!--設定超時時間-->
<timeout start="true" time="100"/><!-- timeout=100 -->
<!--設定rsync+ssh加密傳輸模式,預設關閉,開啟需設定SSH加密證書-->
<ssh start="false"/>
</rsync>
<!--sersync傳輸失敗日誌指令碼路徑,每隔60會重新執行該指令碼,執行完畢會自動清空。-->
<failLog path="/usr/local/sersync/log/rsync_fail_log.sh" timeToExecute="60"/><!--default every 60mins execute once-->
<!--設定rsync+crontab定時傳輸,預設關閉-->
<crontab start="false" schedule="600"><!--600mins-->
<crontabfilter start="false">
<exclude expression="*.php"></exclude>
<exclude expression="info/*"></exclude>
</crontabfilter>
</crontab>
<!-- 設定sersync傳輸後呼叫name指定的外掛指令碼,預設關閉-->
<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>
<!--外掛指令碼範例-->
<plugin name="socket">
<localpath watch="/opt/tongbu">
<deshost ip="192.168.138.20" port="8009"/>
</localpath>
</plugin>
<plugin name="refreshCDN">
<localpath watch="/data0/htdocs/cms.xoyo.com/site/">
<cdninfo domainname="ccms.chinacache.com" port="80" username="xxxx" passwd="xxxx"/>
<sendurl base="http://pic.xoyo.com/cms"/>
<regexurl regex="false" match="cms.xoyo.com/site([/a-zA-Z0-9]*).xoyo.com/images"/>
</localpath>
</plugin>
</head>
6>建立同步目錄:
mkdir /home/jing/projects/svn
7>設定環境變數
echo “export PATH=$PATH:/usr/local/sersync/bin/” >> /etc/profile
source /etc/profil
8>啟動sersync
sersync2 -r -d -o /usr/local/sersync/conf/confxml.xml
注:
選項-d 表示開啟serync並守護程序,-o表示指定配置檔案。
重啟操作:
killall sersync2 && sersync2 -r -d -o /usr/local/sersync/conf/confxml.xml
9>設定開機啟動
echo “sersync2 -r -d -o /usr/local/sersync/conf/confxml.xml” >> /etc/rc.local
源伺服器的配置再囉嗦幾句.
本人常用登入賬號是非root賬戶,按照上述配置後,啟動sersync2要麼說是沒有這個命令,要麼就是日誌報錯
set the system param
execute:echo 50000000 > /proc/sys/fs/inotify/max_user_watches
sh: 1: cannot create /proc/sys/fs/inotify/max_user_watches: Permission denied
execute:echo 327679 > /proc/sys/fs/inotify/max_queued_events
sh: 1: cannot create /proc/sys/fs/inotify/max_queued_events: Permission denied
提示Permission denied.糾結了很久終於找到了原因.因為我是按照root許可權配置,非root賬號沒有許可權訪問600許可權的配置檔案或者密碼檔案,故報錯.解決方案如下:
用sudo給非root賦予超管許可權,並將sersync2帶全路徑啟動.
sudo /usr/local/sersync/bin/sersync2 -r -d -o /usr/local/sersync/conf/conf.xml
以此命令啟動後,發現日誌檔案不在提示Permission denied錯誤,在同步目錄下,建立目錄
cd /home/jing/projects/svn && sudo mkdir -p data0/www #注意這裡建立時也必須用sudo獲取超管身份來建立.
發現目標主機實時的建立了相同結構的目錄.
此外,為了保險起見,將開機啟動設定為如下: