【RabbitMQ】7、RabbitMQ主備復制是異步還是同步?
轉自:https://yq.aliyun.com/articles/73040?spm=5176.100240.searchblog.116.RcXYdl
我們知道RabbitMQ可以配置成Queue做主從復制(按照官方的說法叫配置mirror queue),對master queue的寫操作會被復制到其他slave上去(也就是復制到mirror queue上去)。這對rabbitmq的這個特性,有些人會問這樣的問題,rabbitmq的主從復制是同步的還是異步的?
為什麽有些人會問這個問題那?主要這些人往往是將rabbitmq這個主從復制過程和mysql的主從復制做類比。我們知道mysql主從同步是支持同步、半同步、異步3種模式的。采用哪種模式,決定了mysql的數據可靠性。如果是異步方式主從同步,client發請求給主,當主將數據寫入後,從就復制主上的這條的數據,與此同時,主就會告知客戶端數據保存成功,但是這時從可能還沒有成功的存儲這條數據。如果這時主掛掉了,我們進行主從切換就會丟數據。在要求保證數據可靠性的場景下,我們不能采用異步模式,我們需要采用同步模式或者半同步模式,這裏我們就不再展開同步模式和半同步模式了。這些人將mysql的分析方式放到了rabbitmq,用同樣的方式分析rabbitmq的數據可靠性,所以就提出了這樣的問題。
實際上,rabbitmq的主從復制是異步的,但是rabbitmq並不存在mysql這種場景的丟數據(這句話不是說rabbitmq保證不丟數據)。在這裏,我們來分析一下RabbitMQ的副本復制的過程。
首先,我們來說一下mysql和rabbitmq的使用接口是不同的,這時很關鍵的一點。mysql是同步的接口,也就是說client將sql發給server,server處理sql後將結果返回給client,在server返回client結果前,client不能發起下一個sql的請求。對於rabbitmq來說,訪問接口是異步的。client(我們這裏說的是publisher)向rabbitmq server publish一條消息,在默認的情況下server是不返回成功還是失敗的,也就是說client在不到成功還是失敗的情況下就可以發起下一個請求。如果client關心server是否成功處理完這條消息,可以開啟confirm模式,server會異步的返回ack通知client消息投遞成功還是失敗。但是client仍然不必等待收到當前消息的ack就可以繼續發下一條。
接下來,我們來說rabbitmq的主從復制過程。實際上,RabbitMQ主從之間的數據復制是異步的,但是在rabbitmq中不會出現mysql那種丟數據的情況,這是因為rabbitmq的接口也是異步的,主收到一條消息寫入本地存儲,然後在發起寫入從的請求。當所有從寫入成功後,主才會給client返回ack說這次寫入成功了。所以可以看出,雖然rabbitmq的主從復制是異步的,但是並且不會出現mysql丟數據的場景。只要客戶端收到ack,就說明這條消息已經寫入主和從了。
所以需要強調的一點是,同步和異步並非是決定數據可靠性的關鍵點。客戶端收到成功通知時,所有副本是否寫入成功才是判斷數據可靠的關鍵點。因為mysql的接口是同步,所以才需要在主從復制同步還是異步上做出選擇。rabbitmq的接口本身就是異步的接口,所以rabbitmq的主從復制就自然而然的是異步的方式。
【RabbitMQ】7、RabbitMQ主備復制是異步還是同步?