保證MQ的高可用性,主要是解決MQ的缺點--系統復雜性變高--帶來的問題
主要說一下 rabbitMQ 和 kafka 的高可用性
一、rabbitMQ的高可用性
rabbitMQ是基於主從做高可用性的,主要有三種模式:單機模式(不推薦)、普通集群模式(不推薦)、鏡像集群模式(推薦)
1、單機模式:demo級別,本地啟動,個人練習使用的,生產環境一般不用
2、普通集群模式:
多台機器上啟動多個rabbitMQ實例,但是你創建的queue(元數據+實際數據)只會放在一個rabbitMQ實例 A 上,其他實例都會同步queue的元數據(元數據可以理解為queue的位置、信息,便於其他實例拉取數據的)。如果消費者消費信息的時候,實際連接的是另一個實例 B ,那個B會根據元數據去到A上拉取數據過來。
缺點是:沒做到所謂的分布式,就是個普通集群。
消費者每次隨機連接一個實例拉取數據(增加了拉取數據的開銷),
要么就是消費者固定連接到那個queue所在的實例消費數據(導致單實例性能瓶頸)。
若A宕機了(丟失數據),則其他實例無法拉取數據。即使開啟了消息持久化,讓rabbitMQ落地存儲消息,消息不一定會丟,得等A恢復了才能繼續拉取數據。
總結:並沒有高可用性可言。該方案主要是提高吞吐量,讓集群中多個節點來服務某個queue的讀寫操作。
3、鏡像集群模式:rabbitMQ的高可用實現
創建一個queue(元數據+實際數據),無論是queue的元數據還是消息,都存在於多個實例上。每次寫消息到queue時,都會自動把消息同步到多個實例的queue里。
好處是不擔心宕機,因為所有實例的數據都是一樣的。
壞處是(1)性能開銷大,消息同步所有機器導致網絡帶寬壓力和消耗很重;
(2)無擴展性可言,若某queue負載很重,你再加機器,新增的機器也包含了這個queue的所有數據,並沒有辦法線性拓展你的queue(非分布式的);
另:如何開啟鏡像集群模式?rabbitMQ管理控制台上新增一個鏡像集群模式的策略,指定的時候可以要求數據同步到所有節點,也可以要求同步到指定數量的節點,然后在創建queue時應用這個策略,就會自動將數據同步到其他節點上。
二、kafka 的高可用性
分布式消息隊列
架構認識: 由多個broker組成,每個broker是一個節點。你創建一個topic,這個topic可以划分成多個partition,每個partition可以存在於不同的broker上,每個partition就放一部分數據。也就是說一個topic的數據,是分散放在多個機器上的,每個機器就放一部分數據。
kafka0.8之前是沒有HA模式的(high access),就是replica副本機制
每個partition的數據都會同步到其他機器上,形成自己的多個replica副本,所有replica會選舉出一個leader出來,那么生產者和消費者都是跟這個leader打交道,其他replica就是follower。
寫的時候,leader會負責把數據同步到所有follower上去,讀的時候直接讀leader上數據即可。
高可用性在於:kafka會均勻的將一個partition的所有replica分布在不同的機器上,提高容錯性。若某個broker宕機了,剛好其上有某個partition的leader,那么此時kafka會自動重新選舉出一個新leader,繼續讀寫那個新leader即可。
如何保證所有follower數據跟leader一樣?寫數據的時候,生產者就是leader,將數據落地寫入本地磁盤,接着其他follower主動從leader來拉數據。一旦所有follower同步好數據,會發送ack給leader,leader收到所有follower的ack后,會返回寫成功的消息給生產者。
消費的時候,只會從leader讀,但是只有一個消息已經被所有follower都同步成功返回ack的時候,這個消息才會被讀到,即leader和所有follower上都有了這個消息。