天天看點

ActiveMQ的高可用性實作

一,ActiveMQ高可用性的架構

ActiveMQ的高可用性架構是基于Master/Slave 模型的。ActiveMQ總共提供了四種配置方案來配置HA,其中Shared Nothing Master/Slave 在5.8版本之後不再使用了,并在ActiveMQ5.9版本中引入了基于Zookeeper的Replicated LevelDB Store HA方案。

官網提示:

ActiveMQ的高可用性實作

(其實官方推薦還是使用目前activeMQ内嵌的KahaDB資料庫。)

二,Master/Slave架構的配置解釋

①Shared Nothing Master/Slave  

該架構最大的特點是:

1)Master 和 Slave各自都單獨存儲持久化的消息,它們不共享資料。

2)Master收到持久化消息時,需要先同步(sync)給Slave之後,才向Producer發送ACK确認。

3)隻有Master負責Client的請求,Slave不接收Client請求。Slave連接配接到Master,負責備份消息。

4)Master出現故障,Slave有兩種處理方式:❶自己成為Master;❷關閉(停服務)---根據具體配置而定。

5)Master 與 Slave之間可能會出現“Split Brain”現象。比如:Master本身是正常的,但是Master與Slave之間的網絡出現故障,網絡故障導緻Slave認為Master已經當機,因為它自己會成為Master(根據配置:shutdownOnMasterFailure)。此時,對Client而言,就會存在兩個Master。

6)Slave 隻能同步它連接配接到Master之後的消息。在Slave連接配接到Master之前Producer向Master發送的消息将不會同步給Slave,這可以通過配置(waitForSlave)參數,隻有當Slave也啟動之後,Master才開始初始化TransportConnector接受Client的請求(Producer的請求)

7)如果Master 或者 Slave其中之一當機,它們之間不同步的消息 無法 自動進行同步,此時隻能手動恢複不同步的消息了。也就是說:“ActiveMQ沒有提供任何有效的手段,能夠讓master與slave在故障恢複期間,自動進行資料同步”

8)對于非持久化消息,并不會同步給Slave。是以,Master當機,非持久化消息會丢失。

ActiveMQ的高可用性實作

關于ShareNothing 高可用配置的一點了解:

❶由上面的第2)步可知:Producer向Master發消息之後,Master需要将消息同步給Slave之後,才向Producer傳回确認ACK。是以,對Producer的響應有一定的延時。

如果為了保證快速響應,即Producer給Master發消息之後,Master收到了消息立即給Producer回複,然後再在背景把消息同步給Slave。這又會造成資料不一緻性問題。

因為,如果Master收到了消息立即給Producer回複之後,Master還未來得及向Slave同步就當機了,如果此條消息還在Master記憶體中,則Master當機後消息就丢失了。如果Master收到Producer的消息,先寫入磁盤,然後再向Producer傳回确認ACK,然後再在背景與Slave同步,那麼Master就需要标記每條消息是否已經成功同步到了Slave,若消息還未同步到Slave,則Master重新開機恢複後,需要立即同步Slave。隻有當Slave成功同步了所有的Master上的消息之後,才能上線。這也無法實作 automatic failover。

關于一個很好的高可靠性解決方案:可參考 Hadoop HA中的QJM機制。其核心就是:1)采用叢集,能容忍不超過大多數機器的失效;2)資料隻寫大多數機器就傳回确認,保證Client快速的響應能力;3)資料在背景在異步同步到叢集所有的機器,進而保證高可用。

❷這裡的Master--Slave機制中,隻有一台Slave,并不是Slave叢集(見上面結構圖)。Master當機,或者Slave當機後,都會給整個服務造成極大的風險,并沒有像Hadoop HA中的那樣能夠容忍“不超過大多數機器失效”的保證,即沒有做到真正的高可用性。

❸還可能出現“雙主”問題。即上面提到的“Split Brian”現象。

②Shared Database Master/Slave

 這是很常用的一種架構。“共享存儲”,意味着Master與Slave之間的資料是共享的。

那如何避免沖突呢?通過争奪資料庫表的排他鎖,隻有Master有鎖,未獲得鎖的自動成為Slave。

ActiveMQ Message Broker uses a relational database, it grabs an exclusive lock on a table 
ensuring that no other ActiveMQ broker can access the database at the same time       

對于“共享存儲”而言,隻會“共享”持久化消息。對于非持久化消息,它們是在記憶體中儲存的。可以通過配置(forcePersistencyModeBrokerPlugin persistenceFlag)屬性強制所有的消息都持久化。

當Master當機後,Slave可自動接管服務成為Master。由于資料是共享的,是以Master和Slave之間不需要進行資料的複制與同步。Slave之間通過競争鎖來決定誰是Master。

③Shared File system Master/Slave

這種方式和共享資料庫存儲原理基本一樣,(檔案系統也有檔案鎖),故不詳細介紹。

④最近的 Replicated LevelDB Store

 1)這種方式使用Zookeeper選舉Master。要進行選舉,則需要多數派的“參與者”。因為Replicated LevelDB Store中有多個Broker,從多個Broker中選舉出一個成為Master,其他的則成為Slave。隻有Master接收Client的連接配接,Slave負責連接配接到Master,并 接收( 同步方式、異步方式)Master上的資料。

The elected master broker node starts and accepts client connections. 
The other nodes go into slave mode and connect the the master and synchronize their persistent state /w it.      

以上也表明:每個Broker都是單獨存儲資料的。因為Master要把新的資料複制到Slave上。從這個角度看:稱這種方式為“Share Storage”有點不合适。

2)Quorum機制的又一應用

假設有3個Broker,那麼選舉時至少需要兩個Broker同意(大多數)之後,才能選出Master。此外,隻需要當新消息複制到大多數Broker上時,就可以給Producer傳回ACK。其他少數Broker則可以在背景以異步方式複制新的消息。

All messaging operations which require a sync to disk will wait for the update to be replicated to a quorum of the nodes before completing. 
So if you configure the store with replicas="3" then the quorum size is (3/2+1)=2. 
The master will store the update locally and wait for 1 other slave to store the update before reporting success.      

比如說:一共有3個Broker,一個Master,二個Slave。當新消息到達Master時,Master需要将消息同步到其中一台Slave之後,才能向Producer發送ACK确認此次消息成功發送。

而剩下的另一台Slave,則可以在背景以異步方式複制這個新消息。此外,還能容忍一台Slave當機。(能容忍不超過大多數的Broker當機)

這種設計要求,可以保證叢集中消息的可靠性,隻有當(replicas/2 + 1)個節點實體故障,才會有丢失消息的風險。另外,也提高了一定的響應性,因為它不需要将消息同步到所有的Slave上,而隻需要同步到大多數Broker上。

3)以何種标準判斷誰是Master,誰是Slave呢?

【選舉将會根據“消息日志的版本戳”、“權重"的大小決定,即“版本戳”越大(資料最新)、權重越高的broker優先成為master,其他broker作為slave并跟随master。】

部落格參考:https://blog.csdn.net/weixin_33896069/article/details/85820560