轉自:https://yq.aliyun.com/articles/73040?spm=5176.100240.searchblog.116.RcXYdlmysql
咱們知道RabbitMQ能夠配置成Queue作主從複製(按照官方的說法叫配置mirror queue),對master queue的寫操做會被複制到其餘slave上去(也就是複製到mirror queue上去)。這對rabbitmq的這個特性,有些人會問這樣的問題,rabbitmq的主從複製是同步的仍是異步的?sql
爲何有些人會問這個問題那?主要這些人每每是將rabbitmq這個主從複製過程和mysql的主從複製作類比。咱們知道mysql主從同步是支持同步、半同步、異步3種模式的。採用哪一種模式,決定了mysql的數據可靠性。若是是異步方式主從同步,client發請求給主,當主將數據寫入後,從就複製主上的這條的數據,與此同時,主就會告知客戶端數據保存成功,可是這時從可能尚未成功的存儲這條數據。若是這時主掛掉了,咱們進行主從切換就會丟數據。在要求保證數據可靠性的場景下,咱們不能採用異步模式,咱們須要採用同步模式或者半同步模式,這裏咱們就再也不展開同步模式和半同步模式了。這些人將mysql的分析方式放到了rabbitmq,用一樣的方式分析rabbitmq的數據可靠性,因此就提出了這樣的問題。異步
實際上,rabbitmq的主從複製是異步的,可是rabbitmq並不存在mysql這種場景的丟數據(這句話不是說rabbitmq保證不丟數據)。在這裏,咱們來分析一下RabbitMQ的副本複製的過程。spa
首先,咱們來講一下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就能夠繼續發下一條。server
接下來,咱們來講rabbitmq的主從複製過程。實際上,RabbitMQ主從之間的數據複製是異步的,可是在rabbitmq中不會出現mysql那種丟數據的狀況,這是由於rabbitmq的接口也是異步的,主收到一條消息寫入本地存儲,而後在發起寫入從的請求。當全部從寫入成功後,主纔會給client返回ack說此次寫入成功了。因此能夠看出,雖然rabbitmq的主從複製是異步的,可是而且不會出現mysql丟數據的場景。只要客戶端收到ack,就說明這條消息已經寫入主和從了。blog
因此須要強調的一點是,同步和異步並不是是決定數據可靠性的關鍵點。客戶端收到成功通知時,全部副本是否寫入成功纔是判斷數據可靠的關鍵點。由於mysql的接口是同步,因此才須要在主從複製同步仍是異步上作出選擇。rabbitmq的接口自己就是異步的接口,因此rabbitmq的主從複製就天然而然的是異步的方式。接口