1. 程式人生 > >Magent+keepalived+Memcached緩存高可用群集

Magent+keepalived+Memcached緩存高可用群集

href 用戶 修復 block rtu 腳本 一個 設置 cto

一、Memcached群集
  • Memcached由Memcached服務端和Memcache客戶端組成,其中分布式緩存效果必須由客戶端實現,但其分布式是個偽集群,Memcached各節點之間不通信,無數據備份,負載均衡功能由客戶端實現
  • Memcached本身是基於內存的緩存,設計本身沒有冗余機制;如果一個Memcached節點失去了所有的數據(如斷電、重啟等),理論上後端的應用程序可以從數據庫中再次獲取到數據,但當訪問量大時會大大加重數據庫的負擔,這時可以通過增加更多的節點來減少丟失一個節點的影響,熱備節點在其他節點宕機的時候接管VIP;但是多臺節點無法同步數據,容易造成單點故障

二、實現Memcached緩存集群的方式


1.Repcached

  • Repcached(replication cached,高可用技術,簡稱復制緩沖區技術),Repcached主要優點是數據冗余,兩臺Memcached都可以進行讀寫操作,但只支持單Master、單Slave的解決方案,所以受到的局限性很大;使用過程中Repcached必須與Memcached版本一致(當然也可下載整合包Memcached,包裏自帶Repcached)
    註:雖然Repcached解決方案單獨使用有局限性,但一般環境中,會配合其余軟件一起使用(如Repcached+Magent+Monit:Repcached負責單主單從的同步備份,Magent代理實現N主N備,Monit監聽以上組件的各個實例端口,保證故障自動重啟)
  • (日本人發明的memcached的高可用性技術,簡稱復制緩沖區技術。單master單slave的方案,但master/slave都是可讀寫的,而且可以相互同步。如果master宕機,slave偵測到連接斷了,它會自動listen而成為master,並且等待新的從節點加入。如原來掛掉的master恢復之後,只能人工手動以從節點的方式去啟動,原來的主節點並不能搶占成為新的主節點,除非新的主節點(即slave)掛掉;這也就意味著,基於Repcached實現的 Memcached主從,針對主節點並不具備搶占功能。假設主從節點都掛掉,則數據就丟失了!因此,這是Repcached的一個短板,不過可以通過結合其它的工具來彌補這個缺點(如Keepalived)。而如果slave壞掉,master也會偵測到連接斷開,會重新listen等待新的slave加入)

2.Magent

  • Magent每次寫數據都會寫到主Memcached和從Memcached上,並且向主從Memcached寫的算法一樣
  • 當主Memcached冗機,Magent會向從Memcached中讀取數據
  • 當主Memcached恢復後,Magent將重新向主Memcached中讀數據;此時由於主Memcached剛恢復,其中並無數據,因此會導致部分數據無法讀取,這也是Magent的一大缺點

    註:Magent用於實現多主多從結構,但各節點間不會同步數據,並且從節點只用於備用,請求時不會從從節點請求數據(主節點損壞除外)

  • 在生產環境中主Memcached宕掉的可能性非常小,大部分時間都是工作的;而從Memcached只是在主Memcached宕掉後才使用,因此從Memcached分配的空間不可能和主Memcached一樣,這樣無疑是在浪費寶貴的內存空間
  • 既然從Memcached分配空間較小,而隨著存入的數據會越來越多,會導致緩存的數據不斷被過期驅逐出內存,因此在主Memcached宕掉後,從Memcached只能暫時起到緩解數據庫壓力的作用
  • 主Memcached宕掉後,不宜直接將其啟動,應在數據庫壓力較小的時候再啟動,當預熱緩存(大量的同時請求會造成節點擁堵)
  • 還可部署兩臺Magent節點,實現Memcached入口的負載均衡,也就是說讀寫請求按照一定的算法分配到兩個Magent入口上,一個專處理讀請求、另一個專處理寫請求,既能達到高可用,還能起到負載均衡
  • 通過Magent緩存代理,防止單點現象,通過客戶端(Memcache)連接到緩存代理服務器(Magent),緩存代理服務器(Magent)連接緩存服務器(Memcached),緩存代理服務器(Magent)可以連接多個Memcached,但是如果緩存代理服務器(Magent)故障,那麽緩存代理服務器(Magent)將無法繼續提供服務,所以配合Keepalived軟件實現高可用

    註:Memcache前面已經說過一般和Web一起部署,而Magent一般和Memcached一起部署,關於Memcache怎麽和Magent調用合作,由開發人員通過JAVA調用寫入(或自學JAVA配置)

三、Magent實現方案


Magent

技術分享圖片

  • M1(Memcached)做主,M2(Memcached)做備份,此時利用MA(Magent)調度兩個Memcached,可以實現當M1宕機時,MA可以從M2中獲取數據,對用戶來說無影響
  • 缺點:
  • M1宕機時可以從M2獲取數據,但當M1恢復時,MA無法從中獲取數據(M1由於故障,再啟動緩存數據丟失)。雖然當有N個主機時,Memcached數據丟失的量僅為1/N,但M1宕機時從M2獲取數據效率不高
  • M1重啟時無法從M2中同步到數據

Magent+Repcached

技術分享圖片

  • 首先,通過MA-USER(Memcache)到MA-1(Magent)、MA-2(Magent)這層實現負載分擔(一讀、一寫或者輪詢),通過多MA-n(Magent)來有效利用系統的硬件資源來快速響應數據訪問的請求
  • 其次通過MA-1到M1-S(Memcached)、M1-B(Memcached)這層來實現單點故障恢復
  • 具體來說,當M1-S宕機時,M1-B將自動成為主機,這樣當M1-S重啟恢復時有兩點好處。第一:對於MA-USER來說,MA-1/MA-2的邏輯順序沒有發生改變,這對於存在MA-MGR的系統是有好處的,因為MA-USER在分配key到MA-n上時使用的是簡單的散列余數算法。第二:對於MA-1來說,由於MA-1在初始化的時候就已經指定主備關系了,使用過程中並不會修改MA-1的設置,所以無論MA-1中的主備關系如何倒換,都會屏蔽在MA-n層面,將不會影響後續相關的擴展和移植
    案例:Repcached+Magent+Monit+Memcached

案例:Magent+Memcached群集


主機 系統 IP 網卡 軟件
Magent_1 Centos 6.7 64Bit 192.168.1.10 vmnet1(橋接) Magent、Keepalived
Magent_2 Centos 6.7 64Bit 192.168.1.20 vmnet1(橋接) Magent、Keepalived
Memcached_1 Centos 6.7 64Bit 192.168.1.100 vmnet1 memcached、libevent
Memcached_2 Centos 6.7 64Bit 192.168.1.200 vmnet1 memcached、libevent
測試機 Centos 6.7 64Bit 192.168.1.111 vmnet1 telnet

技術分享圖片

Memcached_1(Server)

1.環境準備(Memcached_1)

vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0                             //網卡名稱
TYPE=Ethernet                           //網卡類型為以太網
ONBOOT=yes                          //開機自啟該網卡
NM_CONTROLLED=no                        //關閉NetworkManager
BOOTPROTO=static                        //網卡設置為靜態方式
IPADDR=192.168.1.100                    //IP地址配置
NETMASK=255.255.255.0                   //子網掩碼配置
/etc/init.d/network restart     //重啟網絡服務

2.安裝Memcached(Memcached_1)
安裝libevent
libevent是memcached所依賴的異步時間通知庫,作為Memcached的依賴需要先完成安裝

tar -zxvf libevent-1.4.9-stable.tar.gz -C /usr/src/
cd /usr/src/libevent-1.4.9-stable/
./configure --prefix=/usr/local/libevent
make && make install

安裝Memcached

tar -zxvf memcached-1.2.6.tar.gz -C /usr/src/
cd /usr/src/memcached-1.2.6/
./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent

選項:
--with-libevent:指定libevent事件庫位置

make && make install
echo "PATH=$PATH:/usr/local/memcached/bin">>/etc/profile
source /etc/profile
vim /etc/ld.so.conf             //打開系統額外加載庫定義文件
/usr/local/libevent/lib         //增加libevent事件庫文件夾路徑
ldconfig                            //重新讀取/etc/ld.so.conf文件內容

3.啟動Memcached服務(Memcached_1)

memcached -d -m 1 -u root -l 192.168.1.100 -p 11211
netstat -utpln |grep 11211

Memcached_2(Server)

1.環境準備(Memcached_2)

vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0                             //網卡名稱
TYPE=Ethernet                           //網卡類型為以太網
ONBOOT=yes                          //開機自啟該網卡
NM_CONTROLLED=no                        //關閉NetworkManager
BOOTPROTO=static                        //網卡設置為靜態方式
IPADDR=192.168.1.200                    //IP地址配置
 NETMASK=255.255.255.0                  //子網掩碼配置
/etc/init.d/network restart     //重啟網絡服務

2.安裝Memcached(Memcached_2)
安裝libevent
libevent是memcached所依賴的異步時間通知庫,作為Memcached的依賴需要先完成安裝

tar -zxvf libevent-1.4.9-stable.tar.gz -C /usr/src/
cd /usr/src/libevent-1.4.9-stable/
./configure --prefix=/usr/local/libevent
make && make install

安裝Memcached

tar -zxvf memcached-1.2.6.tar.gz -C /usr/src/
cd /usr/src/memcached-1.2.6/
./configure --prefix=/usr/local/memcached --with-libevent=/usr/local/libevent

選項:
--with-libevent:指定libevent事件庫位置

make && make install
echo "PATH=$PATH:/usr/local/memcached/bin">>/etc/profile
source /etc/profile
vim /etc/ld.so.conf             //打開系統額外加載庫定義文件
/usr/local/libevent/lib         //增加libevent事件庫文件夾路徑
ldconfig                            //重新讀取/etc/ld.so.conf文件內容

3.啟動Memcached服務(Memcached_2)

memcached -d -m 1 -u root -l 192.168.1.200 -p 11211
netstat -utpln |grep 11211

Magent_1(Client)

1.環境準備(Magent_1)

vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0                             //網卡名稱
TYPE=Ethernet                           //網卡類型為以太網
ONBOOT=yes                          //開機自啟該網卡
NM_CONTROLLED=no                        //關閉NetworkManager
BOOTPROTO=static                        //網卡設置為靜態方式
IPADDR=192.168.1.10                     //IP地址配置
NETMASK=255.255.255.0                   //子網掩碼配置
cp /etc/sysconfig/network-scripts/ifcfg-eth0 /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1                             //網卡名稱
TYPE=Ethernet                           //網卡類型為以太網
ONBOOT=yes                          //開機自啟該網卡
NM_CONTROLLED=no                        //關閉NetworkManager
BOOTPROTO=dhcp                      //網卡設置為動態方式
/etc/init.d/network restart     //重啟網絡服務

2.依賴安裝(Magent_1)

yum clean all && yum repolist           //清除YUM緩存並重新生成
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
yum -y install libevent-devel

3.安裝Magent(Magent1)

mkdir /usr/src/magent-0.5           //創建源碼解壓目錄
tar -zxvf magent-0.5.tar.gz -C /usr/src/magent-0.5
cd /usr/src/magent-0.5
ls -l /usr/src/magent-0.5

註:Magent軟件為源碼程序,源碼中默認已經執行.configure並生成一個Makefile文件,用戶只需按需修改頭部和Makefile文件,然後直接make即可

報錯一:未尋找到event.h
技術分享圖片

由於編譯編譯libevent指定自定義安裝路徑,而軟件一般尋找.h頭文件搜尋是在/usr/include或者/usr/local/include的頭文件目錄中,所以找不到自定義的event.h頭文件,只需將自定義路徑下的event.h軟鏈接或拷貝到/usr/include或者/usr/local/include的頭文件目錄即可

scp [email protected]:/usr/local/libevent/include/* /usr/local/include/

報錯二:未尋找到event-config.h、evutil.h
技術分享圖片

報錯原因與解決方案如上,不再闡述

scp [email protected]:/usr/local/libevent/include/* /usr/local/include/

報錯三:未聲明SSIZE_MAX函數
技術分享圖片

這是由於程序中需要調用SSIZE_MAX常量,而文件中未定義該常量,所以在聲明文件中定義該常量,並設置值即可

vim ketama.h
#ifndef SSIZE_MAX           //測試SSIZE_MAX是否被宏定義過
#define SSIZE_MAX 32767     //如果沒有被宏定義過,定義並編譯
#endif          //如已經定義,則忽視define內容,繼續執行文件剩余內容
        ...                         //上面三行在文件開頭增加

註:編輯文件時,會有兩個同名的ketama文件,但後綴不同,ketama.c一般存儲具體功能的實現、ketama.h稱為頭文件,一般存儲類型的定義,函數的聲明等(當然兩個文件本質沒有區別,只是方便開發人員識別),所以應該編輯的是ketama.h,不要編輯錯了

報錯四:未定義undefined函數
技術分享圖片

floor是數學庫裏提供的函數,默認gcc不會自動鏈接math庫(數學庫),因此需要手動在Makefile文件中指定-lm,編譯程序時需使用數學庫中函數

vim Makefile
        LIBS = -levent -lm                  //在原選項後增加新參數
make                                //編譯成功後,在源碼目錄生成可執行文件
cp magent /usr/bin                  //將可執行程序拷貝到PATH搜索路徑下

安裝Keepalived(Magent_1)

yum -y install keepalived               //YUM安裝Keepalived軟件包
vim /etc/keepalived/keepalived.conf
global_defs {
//配置故障發生時的通知對象以及機器標識
router_id MASTER    
//標識本節點的字條串,通常為hostname
}
vrrp_script magent {
//健康檢查(防止腦裂)
script "/opt/magent.sh"
//檢查執行的腳本或命令,這裏主要判斷keepalived狀態,正常則啟動Magent
interval 1
//腳本運行間隔
weight -10
//當檢測腳本執行失敗,priority的優先級會減少10個點;不設置從節點也可搶占
}
vrrp_instance VI_1 {
//定義對外提供服務的VIP區域及其相關屬性
state MASTER
//可以是MASTER或BACKUP,不過當其他節點keepalived啟動時會將priority比較大的節點選舉為MASTER,因此該項其實沒有實質用途
interface eth0
//節點固有IP的網卡,用來發VRRP包
virtual_router_id 51
//取值在0-255之間,用於區分多個instance(節點)的VRRP組播
priority 100
//選舉master,要成為master,那麽這個選項的值最好高於其他機器50個點,該項取值範圍是1-255(在此範圍之外會被識別成默認值100)
advert_int 1
//發VRRP包的時間間隔,即多久進行一次master選舉(可以認為是健康查檢時間間隔)
authentication {
//認證區域,認證類型有PASS和HA(IPSEC),推薦使用PASS(密碼只識別前8位)
auth_type PASS
//指定認證類型為PASS
auth_pass 1111
//指定認證密碼,多個節點密鑰相當
}
track_script {
//定義需要追蹤執行的腳本
magent
//執行的腳本名
}
virtual_ipaddress {
//VIP地址定義
192.168.1.254
//指定使用的VIP
}
}

編寫magent 監測腳本(Magent_1)

vim /opt/magent.sh
#!/bin/bash
//定義Shell解釋器
KEEPALIVED=`ps -ef |grep keepalived |grep -v grep |wc -l`
//定義變量,用於統計當前主機keepalived服務進程數量
if [ $KEEPALIVED -gt 0 ];then
//判斷,如KEEPALIVED變量值大於KEEPALIVED=`ps -ef |grep keepalived |grep -v grep |wc -l`0,則表示已產生keepalived進程、服務已經狀態開啟
magent -u root -n 51200 -l 192.168.1.254 -p 12000 -s 192.168.1.100:11211 -b 192.168.1.200:11211
//當Keepalived服務開啟時,啟動magent進程,指定群集IP地址及端口,並定義後端主Memcached和從Memcached服務器節點及端口,當前主機開始提供服務
else
//如KEEPALIVED變量值小於0,則表示Keppalived停止或未運行
pkill -9 magent
//殺死magent進程(如果之前啟動過的話),以讓從節點啟動magent並繼續提供服務
fi
chmod +x /opt/magent.sh
/etc/init.d/keepalived start
ip a
ps aux | grep magent

Magent_2

1.環境準備(Magent_2)

vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0                             //網卡名稱
TYPE=Ethernet                           //網卡類型為以太網
ONBOOT=yes                          //開機自啟該網卡
NM_CONTROLLED=no                        //關閉NetworkManager
BOOTPROTO=static                        //網卡設置為靜態方式
IPADDR=192.168.1.200                    //IP地址配置
NETMASK=255.255.255.0                   //子網掩碼配置
cp /etc/sysconfig/network-scripts/ifcfg-eth0  /etc/sysconfig/network-scripts/ifcfg-eth1
DEVICE=eth1                             //網卡名稱
TYPE=Ethernet                           //網卡類型為以太網
ONBOOT=yes                          //開機自啟該網卡
NM_CONTROLLED=no                        //關閉NetworkManager
BOOTPROTO=dhcp                      //網卡設置為動態方式
/etc/init.d/network restart     //重啟網絡服務

2.依賴安裝(Magent_2)

yum clean all && yum repolist           //清除YUM緩存並重新生成
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo
yum -y install libevent-devel

3.安裝Magent(Magent_2)
由於Magent_1主機已經安裝並生成了magent命令,因此Magent_2只需拷貝命令到本地PATH路徑即可

scp [email protected]:/usr/bin/magent /usr/bin/

註:註意檢查兩邊主機是否安裝openssh-clients軟件包

安裝Keepalived(Magent_2)

yum -y install keepalived               //YUM安裝Keepalived軟件包

一樣,由於Magent_1的Keepalived已經配置好,這裏只需拷貝到本地,修改即可使用

scp [email protected]:/etc/keepalived/keepalived.conf /etc/keepalived/
vim /etc/keepalived/keepalived.conf

技術分享圖片
編寫magent監控腳本(Magent_2)

vim /opt/magent.sh
#!/bin/bash
//定義Shell解釋器
VIP=$(ip a |grep 192.168.1.254 | wc -l)
//定義變量,用於查看當前是否存在VIP(有即代表主故障,VIP轉移到從主機)
if [ $VIP -gt 0 ];then
//判斷,如VIP變量值大於0,則表示VIP已經轉移,當前主機繼續提供服務
magent -u root -n 51200 -l 192.168.1.254 -p 12000 -s 192.168.1.100:11211 -b 192.168.1.200:11211
//當VIP監聽時,啟動magent進程,指定群集IP地址及端口,並定義後端主Memcached和從Memcached服務器節點及端口,當前主機開始提供服務
else
//如VIP變量值小於0,則表示VIP未監聽,主節點依然正常工作著
pkill -9 magent
//殺死magent進程(如果之前啟動過的話),以讓主節點啟動magent並繼續提供服務
fi
chmod +x /opt/magent.sh
/etc/init.d/keepalived start

測試

1.測試高可用

/etc/init.d/keepalived stop                 //停止主節點Keepalived,VIP轉移
ip a                                    //主節點故障,VIP自動轉移到從節點

2.環境準備(測試機)

vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0                             //網卡名稱
TYPE=Ethernet                           //網卡類型為以太網
ONBOOT=yes                          //開機自啟該網卡
NM_CONTROLLED=no                        //關閉NetworkManager
BOOTPROTO=static                        //網卡設置為靜態方式
IPADDR=192.168.1.111                    //IP地址配置
NETMASK=255.255.255.0                   //子網掩碼配置
/etc/init.d/network restart     //重啟網絡服務

3.緩存測試

yum clean all && yum repolist           //清除YUM緩存並重新生成
mount /dev/cdrom /mnt/              //掛載光盤到/mnt/目錄
yum -y install telnet                   //安裝遠程登陸軟件

4.VIP測試

telnet 192.168.1.254 12000          //連接Magent的VIP及端口
        Trying 192.168.1.254...
        Connected to 192.168.1.254.
        Escape character is ‘^]‘.
set test 0 0 4              //新建鍵值test,長度4位                
hehe                            //test鍵值數據內容
        STORED
quit                                //退出
        Connection closed by foreign host.
telnet 192.168.1.254 12000          //再次連接Magent的VIP及端口
        Trying 192.168.1.254...
        Connected to 192.168.1.254.
        Escape character is ‘^]‘.
get test                            //查看剛插入test鍵值內容
VALUE test 0 4
hehe
        END
quit                                //退出
        Connection closed by foreign host.

5.主節點測試

telnet 192.168.1.100 11211                  //連接主節點及端口
        Trying 192.168.1.100...
        Connected to 192.168.1.100.
        Escape character is ‘^]‘.
get test                            //查看主節點是否能得到數據
VALUE test 0 4
hehe
        END
quit                                //退出
        Connection closed by foreign host.

6.從節點測試

telnet 192.168.1.200 11211                  //連接從節點及端口
        Trying 192.168.1.200...
        Connected to 192.168.1.200.
        Escape character is ‘^]‘.
get test                            //查看從節點是否能得到數據
VALUE test 0 4
hehe
        END
quit                                //退出
        Connection closed by foreign host.

註:可以看見,往VIP插入的數據,主、備緩存節點都有了手動插入的值
模擬主節點故障

 pkill memcached                        //殺死主節點Memcached進程
telnet 192.168.1.100 12000          //連接Magent的VIP及端口
        Trying 192.168.1.100...
        Connected to 192.168.1.100.
        Escape character is ‘^]‘.
get test                            //驗證VIP是否還能查詢到數據
VALUE test 0 4
hehe
        END
quit                                //退出
        Connection closed by foreign host.
    以上說明 memcached 單節點故障,緩存依然存在

註意:如果將故障的memcached節點修復後,緩存是不會再通過到已修復的節點上的,如果是magent指定的主節點故障,那麽主節點的緩存數據會丟失,修復後不能立刻重啟
memcached服務,如果重啟,客戶端會去查詢主節點的數據,並發高的網站會拖死數據庫;
因此,建議一般業務低峰期的時候再啟動memcached主節點服務,然後通過magent再指
定主緩存節點和備緩存節點

Magent+keepalived+Memcached緩存高可用群集