rabbitmq 集羣數據存儲與單點故障

rabbitmq每個節點記錄四類信息:交換機、隊列、綁定、vhost元數據。

集羣中的信息存儲

在rabbitmq2.6.0之前沒有鏡像隊列,數據存儲情況爲:

隊列所屬節點保存隊列全部信息(元數據、狀態、內容),其他節點擁有隊列元數據;所有節點保存exchange、bundling信息。好處有兩點:

    1.節約存儲空間,每個節點都有相同信息的拷貝,意味着磁盤空間成倍佔用;

    2.提升性能,數據在節點間同步佔用網絡資源,如果是持久化狀態,又會有大量I/O;

正常情況的工作原理:

集羣中有三個節點:rabbit、hare、hare1,隊列聲明在hare節點,向rabbit節點發消息,消息會轉發到hare節點,消費者連接hare1節點,則從hare節點讀取數據。

異常情況1(發送過程中故障):

向rabbit節點發送5條消息,第一條發送成功後,關掉hare節點

2017-11-16 12:05:07,015 [http-bio-8080-exec-1] 
[org.springframework.amqp.rabbit.core.RabbitTemplate]-[DEBUG] Publishing message (Body:'< publish
 message 內容爲:[ Thu Nov 16 12:05:07 CST 2017 ]>' MessageProperties [headers={}, 
contentType=text/plain, contentEncoding=UTF-8, contentLength=62, deliveryMode=PERSISTENT, priority=0, deliveryTag=0])on exchange [AMC_TMP_EXCHANGE], routingKey = [cluster.send]

控制檯顯示正常發送,實際上後面4條消息已經丟失

localhost:sbin zcjlq$ ./rabbitmqctl -n hare stop_app
Stopping rabbit application on node hare@localhost
localhost:sbin zcjlq$ ./rabbitmqctl -n rabbit -p zcjlq list_queues
Listing queues
AMC_TMP_QUEUE

hare節點重啓,只有第一條消息

localhost:sbin zcjlq$ ./rabbitmqctl -n hare start_app
Starting node hare@localhost
localhost:sbin zcjlq$ ./rabbitmqctl -n rabbit -p zcjlq list_queues
Listing queues
AMC_TMP_QUEUE	1

拓展:

如果使用publisher confirm機制,在回調函數RabbitTemplate.ConfirmCallback,你將拿到5個ack,RabbitTemplate.ReturnCallback不會被回調。


異常情況2(發送完畢故障):

假如我們連上任意節點,發送4條消息,先不消費,各個節點都能查到消息。

下面停掉隊列所屬節點hare

localhost:sbin zcjlq$ ./rabbitmqctl -n rabbit -p zcjlq list_queues
Listing queues
AMC_TMP_QUEUE	4
localhost:sbin zcjlq$ ./rabbitmqctl -n hare1 -p zcjlq list_queues
Listing queues
AMC_TMP_QUEUE	4
localhost:sbin zcjlq$ ./rabbitmqctl -n hare stop_app
Stopping rabbit application on node hare@localhost
localhost:sbin zcjlq$ ./rabbitmqctl -n hare1 -p zcjlq list_queues
Listing queues
AMC_TMP_QUEUE
localhost:sbin zcjlq$ ./rabbitmqctl -n rabbit -p zcjlq list_queues
Listing queues
AMC_TMP_QUEUE
localhost:sbin zcjlq$ ./rabbitmqctl -n hare start_app
Starting node hare@localhost
localhost:sbin zcjlq$ ./rabbitmqctl -n rabbit -p zcjlq list_queues
Listing queues
AMC_TMP_QUEUE	4
localhost:sbin zcjlq$ ./rabbitmqctl -n hare1 -p zcjlq list_queues
Listing queues
AMC_TMP_QUEUE	4

我們發現:停用hare節點後,在另外兩個節點查不到消息,hare節點重啓後,三個節點都能查到消息。

說明:本測試在單機上啓動三個節點(單機集羣搭建見後續文章)

rabbitmqctl -n參數指定節點名稱,-p指定vhost名稱,start_app啓動節點,stop_app關閉節點,

list_queues查看隊列列表和待消費消息。

異常情況3(故障期間重新聲明隊列):

在恢復hare節點前,我們嘗試通過其他節點重新創建隊列。出現以下錯誤

Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: 
#method<channel.close>(reply-code=404, reply-text=NOT_FOUND - home node 'hare@localhost' 
of durable queue 'AMC_TMP_QUEUE' in vhost 'zcjlq' is down or inaccessible, class-id=50, method-id=10)

 

節點類型

集羣中的節點有兩個類型:磁盤節點、內存節點。內存節點(ram)將所有的隊列、交換器、綁定、用戶、權限、vhost的元數據定義都僅存儲於內存中。磁盤節點(disc)將元數據存儲在磁盤中。

是磁盤節點還是內存節點?

在集羣中聲明隊列、交換器、綁定的時候,其他節點會得到元數據的同步,如果集羣中全都是磁盤節點,那麼你需要等到所有的節點都磁盤I/O後才完成工作,內存節點將會更快。

rabbitmq要求集羣中至少有一個磁盤節點。磁盤節點離開集羣時,集羣還可以進行部分工作,創建隊列、創建交換機、創建綁定、添加用戶、更改權限、添加或刪除集羣節點將不能使用。原理的磁盤節點重啓後,集羣可以正常工作。我們想要更安全一點:原磁盤節點重啓前,爲讓集羣正常工作,這時候可以考慮設置兩個集羣節點,當其中一個磁盤節點離開時,它會將該變更通知到至少一個磁盤節點。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章