從石杉碼農課程整理而來面試
如何保證消息隊列的高可用啊?網絡
若是有人問到你MQ的知識,高可用是必問的,由於MQ的缺點,我剛纔已經說過了,有好多,致使系統可用性下降,等等。因此只要你用了MQ,接下來問的一些要點確定就是圍繞着MQ的那些缺點怎麼來解決了。架構
要是你傻乎乎的就幹用了一個MQ,各類問題歷來沒考慮過,那你就杯具了,面試官對你的印象就是,只會簡單實用一些技術,沒任何思考,立刻對你的印象就不太好了。這樣的同窗招進來要是作個20k薪資之內的普通小弟還湊合。若是招進來作薪資20多k的高工,那就慘了,讓你設計個系統,裏面確定一堆坑,出了事故公司受損失,團隊一塊兒背鍋。分佈式
去年的事兒,很是大的互聯網公司,很是核心的系統,就是疏忽了MQ,沒考慮MQ如何保證高可用,若是MQ掛了怎麼辦,致使幾個小時系統不可用,公司損失幾千萬,team背鍋,你鬧的禍,你老大幫你一塊兒背鍋性能
這個問題這麼問是很好的,由於不能問你kafka的高可用性怎麼保證啊?ActiveMQ的高可用性怎麼保證啊?一個面試官要是這麼問就顯得很沒水平,人家可能用的就是RabbitMQ,沒用過Kafka,你上來問人家kafka幹什麼?這不是擺明了刁難人麼。學習
因此有水平的面試官,問的是MQ的高可用性怎麼保證?這樣就是你用過哪一個MQ,你就說說你對那個MQ的高可用性的理解。設計
RabbitMQ是比較有表明性的,由於是基於主從作高可用性的,咱們就以他爲例子講解第一種MQ的高可用性怎麼實現。cdn
rabbitmq有三種模式:單機模式,普通集羣模式,鏡像集羣模式blog
就是demo級別的,通常就是你本地啓動了玩玩兒的,沒人生產用單機模式rabbitmq
意思就是在多臺機器上啓動多個rabbitmq實例,每一個機器啓動一個。可是你建立的queue,只會放在一個rabbtimq實例上,可是每一個實例都同步queue的元數據。完了你消費的時候,實際上若是鏈接到了另一個實例,那麼那個實例會從queue所在實例上拉取數據過來。
這種方式確實很麻煩,也不怎麼好,沒作到所謂的分佈式,就是個普通集羣。由於這致使你要麼消費者每次隨機鏈接一個實例而後拉取數據,要麼固定鏈接那個queue所在實例消費數據,前者有數據拉取的開銷,後者致使單實例性能瓶頸。
並且若是那個放queue的實例宕機了,會致使接下來其餘實例就沒法從那個實例拉取,若是你開啓了消息持久化,讓rabbitmq落地存儲消息的話,消息不必定會丟,得等這個實例恢復了,而後才能夠繼續從這個queue拉取數據。
因此這個事兒就比較尷尬了,這就沒有什麼所謂的高可用性可言了,這方案主要是提升吞吐量的,就是說讓集羣中多個節點來服務某個queue的讀寫操做。
這種模式,纔是所謂的rabbitmq的高可用模式,跟普通集羣模式不同的是,你建立的queue,不管元數據仍是queue裏的消息都會存在於多個實例上,而後每次你寫消息到queue的時候,都會自動把消息到多個實例的queue裏進行消息同步。
這樣的話,好處在於,你任何一個機器宕機了,沒事兒,別的機器均可以用。壞處在於,第一,這個性能開銷也太大了吧,消息同步全部機器,致使網絡帶寬壓力和消耗很重!第二,這麼玩兒,就沒有擴展性可言了,若是某個queue負載很重,你加機器,新增的機器也包含了這個queue的全部數據,並沒有辦法線性擴展你的queue
那麼怎麼開啓這個鏡像集羣模式呢?我這裏簡單說一下,避免面試人家問你你不知道,其實很簡單rabbitmq有很好的管理控制檯,就是在後臺新增一個策略,這個策略是鏡像集羣模式的策略,指定的時候能夠要求數據同步到全部節點的,也能夠要求就同步到指定數量的節點,而後你再次建立queue的時候,應用這個策略,就會自動將數據同步到其餘的節點上去了。
kafka一個最基本的架構認識:多個broker組成,每一個broker是一個節點;你建立一個topic,這個topic能夠劃分爲多個partition,每一個partition能夠存在於不一樣的broker上,每一個partition就放一部分數據。
這就是自然的分佈式消息隊列,就是說一個topic的數據,是分散放在多個機器上的,每一個機器就放一部分數據。
實際上rabbitmq之類的,並非分佈式消息隊列,他就是傳統的消息隊列,只不過提供了一些集羣、HA的機制而已,由於不管怎麼玩兒,rabbitmq一個queue的數據都是放在一個節點裏的,鏡像集羣下,也是每一個節點都放這個queue的完整數據。
kafka 0.8之前,是沒有HA機制的,就是任何一個broker宕機了,那個broker上的partition就廢了,無法寫也無法讀,沒有什麼高可用性可言。
kafka 0.8之後,提供了HA機制,就是replica副本機制。每一個partition的數據都會同步到其餘機器上,造成本身的多個replica副本。而後全部replica會選舉一個leader出來,那麼生產和消費都跟這個leader打交道,而後其餘replica就是follower。寫的時候,leader會負責把數據同步到全部follower上去,讀的時候就直接讀leader上數據便可。只能讀寫leader?很簡單,要是你能夠隨意讀寫每一個follower,那麼就要care數據一致性的問題,系統複雜度過高,很容易出問題。kafka會均勻的將一個partition的全部replica分佈在不一樣的機器上,這樣才能夠提升容錯性。
這麼搞,就有所謂的高可用性了,由於若是某個broker宕機了,沒事兒,那個broker上面的partition在其餘機器上都有副本的,若是這上面有某個partition的leader,那麼此時會從新選舉一個新的leader出來,你們繼續讀寫那個新的leader便可。這就有所謂的高可用性了。
寫數據的時候,生產者就寫leader,而後leader將數據落地寫本地磁盤,接着其餘follower本身主動從leader來pull數據。一旦全部follower同步好數據了,就會發送ack給leader,leader收到全部follower的ack以後,就會返回寫成功的消息給生產者。(固然,這只是其中一種模式,還能夠適當調整這個行爲)
消費的時候,只會從leader去讀,可是隻有一個消息已經被全部follower都同步成功返回ack的時候,這個消息纔會被消費者讀到。
實際上這塊機制,講深了,是能夠很是之深刻的,可是我仍是回到咱們這個課程的主題和定位,聚焦面試,至少你聽到這裏大體明白了kafka是如何保證高可用機制的了,對吧?不至於一無所知,現場還能給面試官畫畫圖。要趕上面試官確實是kafka高手,深挖了問,那你只能說很差意思,太深刻的你沒研究過。
可是你們必定要明白,這個事情是要權衡的,你如今是要快速突擊常見面試題體系,而不是要深刻學習kafka,要深刻學習kafka,你是沒那麼多時間的。你只能確保,你以前也許壓根兒不知道這塊,可是如今你知道了,面試被問到,你大概能夠說一說。而後不少其餘的候選人,也許還不如你,沒看過這個,被問到了壓根兒答不出來,相比之下,你還能說點出來,大概就是這個意思了。