1. 程式人生 > >Linux下Rsync+sersync實現資料實時同步

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獲取超管身份來建立.
發現目標主機實時的建立了相同結構的目錄.
此外,為了保險起見,將開機啟動設定為如下:

echo “sudo /usr/local/sersync/bin/sersync2 -r -d -o /usr/local/sersync/conf/conf.xml” >> /etc/rc.local #超管許可權全路徑啟動

———–好,源伺服器已經配置完成了—————–