高可用,重復消費,冪等,可靠性傳輸,消息丟失
1、 kafka,rabbitMQ,activemq,rocketMQ使用場景及區別技術選型
吞吐量、topic數量對吞吐量的影響、時效性、可用性、可靠性、核心特點、優劣勢總結
activemq:吞吐量萬級 非常成熟,功能比較強大,大量的公司再項目中有應用 偶爾會有低概消息丟失,近些年應用越來越少 官方社區維護越來越少,而且確實主要基於解耦和異步來用的,較少在大規模吞吐的場景下使用
rabbitMQ: 吞吐量萬級 跟服務器有關系 基於erlang開發,性能較好 延時低,而且提供開源的管理界面 社區比較活躍,近些年互聯網公司用rabbitmq的比較多,因為基於erlang語言 不懂源碼,比較難進行定制和掌控;
rocketMQ:單機吞吐量10w,topic可以達到幾百或者上千級別 topic越多吞吐量會有較小幅度的下降,阿里大規模使用,比較可靠、日處理消息上百億、拓展方便、社區維護可以,只會復雜MQ業務場景
kafka:功能簡單,主要支持簡單的mq功能,ms級延遲 極高的可用性和可靠性不過有消息重復消費 在大數據領域的實時計算以及日志采集被大規模使用。
中小型公司:rabbitMQ,技術實力一般 挑戰不是很高 社區比較活躍;
大型公司:rocketMQ 基礎架構研發實力較強
如果是大數據領域的實時計算、日志采集等場景 用kafka是業內標准的,社區活躍度比較高,絕對不會黃,更何況是全世界這個領域的實時性規范;
2. 消息隊列的使用場景,為什么使用消息隊列
系統之間解耦 通過發布訂閱模型 不同系統之間進行解耦,比如B系統以來A系統中某一消息,A系統只用負責往消息隊列中發送消息,B只管消費,如果新增C,D等消費者A不用關注;
削峰 當系統A突然有大量數據,如果通過A系統RPC進行調用入庫,A系統很可能將系統打掛,因此可以通過MQ進行削峰,然后由A系統慢慢消費;
異步 比如:A需要向C,D,E,F等多個系統依賴A系統中某一個消息或者通知,可以通過消息隊列的方式,不需要同步調用rpc方式進行調用;
缺點:增加系統復雜性,如果MQ掛了整個系統都會掛掉,MQ引起的問題(消息丟失,消息順序性,消息重復發送 無法保證消息)
3、RabbitMQ的高可用和kafka的考可用
不是分布式的,是集群
三種模式:單機模式、集群模式和鏡像模式
集群模式:在多台機器上啟動多個rabbitmq實例,每個機器啟動一個。但是你創建的queue,只會放到一個rabbitmq實例上,但是每個實例都同步queue的元數據;待消費的時候 實際上如果連接到了另外一個實例
那么那個實例會從queue所在實例上拉取數據過來。 因此 這種模式模式不可靠,如果存儲數據的queue所在實例掛了數據就丟失了,另外如果數據量太大 兩個實例之間傳輸數據量太大;
鏡像集群模式:高可用模式,每個節點上都有這個queue的一個完整鏡像(元數據和消息內容),然后每次寫消息到queue的時候,都會自動把消息同步到多個實例的queue里面;
缺點:性能開銷太大,消息需要同步到所有機器上,導致網絡帶寬 增加機器負載 沒有辦法線性擴展queue;
開啟方式:從管理控制台 新增策略 (鏡像集群模式)同時可以指定 要求數據同步到所有節點 或者同步到指定數量的節點,再次創建queue時候 會使用該策略;
不是分布式的:意思是數據在單個集群節點上完整存儲
kafka分布式
broker進程就是kafka在每台機器上啟動的自己的一個進程,也可以認為是kafka集群中的一個節點;
kafka由多個broker組成 每個broker是一個節點; 創建topic 該topic可以划分到多個partition,每個分區可以存在於不同的broker上,每個partition就存放一部分數據;
kafka是天然的分布式消息隊列 也就是一個topic數據可以存儲到多個partition 每個partition可以分布在不同的broker上;
實際上rabbitmq 之類的並不是分布式消息隊列,他就是傳統的消息隊列 只不過提供了一些集群、HA的機制而已,因為無論怎么玩,rabbitMQ中的一個queue的數據都是放到一個節點下;
在鏡像集群下 也就是每個節點都存放了這個queue的完整數據;
HA機制:高可用機制 kafka通過副本機制 partition存在多個副本 副本中會選舉leader 其它的副本為fllower,寫入數據寫入到leader同步數據會同步到fllower中,客戶端連接連接到leader;
此時:一旦某一台機器宕機了,如果是leader沒有了,但是此時別的機器上還有fllower此時kafka會自動感知到leader死了,會將其它fllower進行選舉為leader節點;
4. 消息的重發,補充策略,如何保證消息不會被重復消費(如何保證冪等性)
rabbitMQ、rocketMQ、kafka等消息中間件都會出現消費者重復消費消息的問題,因為這個保證不應該是mq保證的,是消費端自己保證;
kafka重復消費:kafka上有一個offset的概念,就是每一個消息寫進去都會有一個offset,代表它的序號 然后消費者消費數據之后
原因:每隔一段時間會把自己消費過的消息的offset進行提交,代表已經消費過了; 基於zookeeper實現的,zk里面就記錄了消費者當前消費到offset的位置;
消費者不是消費完一條數據就立馬提交offset的,而是定時定期提交一次offset的; 如果客戶端掛了或者重啟了 導致offset未能及時提交 則再次進行消費時候會從上次開始消費的地方重復消費;
解決方式(保證冪等):結合業務
1)拿到數據進行寫庫,可以根據相應主鍵或者聯合主鍵進行保證,或者數據來了先查下數據庫(注意主從庫)建議查詢主庫進行過濾或者進行更新;
2)通過緩存標識或者分布式鎖 當然如果直接寫到redis中的set里面就沒有問題,畢竟是天然冪等;
3)復雜點的場景是 消息里面增加全局唯一標識,收到消息后先去redis里面進行查找,如果沒查到則進行消費然后記錄到redis中
????如果多個消費者是怎么處理的?在rabbitmq中是怎么處理的?
5. MQ 系統的數據如何保證不不丟失,就是數據一條不能多一條不能少
丟失原因:生產者過程中消息沒有寫到mq中、mq自己丟失、或者消費者在消費過程中丟失;
rabbitMQ: 消息沒有傳輸到rabbitmq中 就丟失了,或者rabbitmq中已經接收到消息但是還沒有來得及保存就出現問題了或者已經保存到內存但是沒有序列化到硬盤 ,消費者消費到了消息但是還沒有來得及處理就掛掉了 rabbitmq以為消費者已經消費成功了;
解決方式:
生產者可以開啟一個事務(會引起阻塞會使吞吐量下降)或者異步確認;
第一步創建queue設置其為持久化 保證rabbitmq中queue的元數據會序列化;第二部:發送消息時候將消息體設置為持久化即deliveyMode=2,來保證消息的持久化;
同時持久化機制跟生產者的confirm機制配合起來,保證只有消息體持久化????(這個是保存到內存還是保存到硬盤,如果保存到內存還會丟失 無法完全避免)完成后 才會通知生產者;
消費端關閉自動確認回復autoAck機制
kafka:
生產者:寫入失敗,設置重試次數 如果超過n次進行人工干預;如果設置為max
服務端丟失:在分區中的副本同步過程中,如果副本的leader剛收到生產者消息並且自己已經保存下來准備同步給副本時候 掛掉
解決方式:每個partition至少要有兩個副本 並且至少有一個副本始終跟leader保持連接 同時在生產者設置acks=all,要求寫入到所有副本 才算寫入成功;
消費端丟數據:消費到了消息,消費者自動提交了offset,但是客戶端處理過程中出現異常,服務端以為客戶端已經消費完畢,解決方式客戶端處理完畢后手動提交offset;
6. 如何保證消息的有序性 (生產者為binlog對一條數據進行增刪改,如果不保證順序性)
場景:1)rabbitMQ中一個queue多個consumer
2)kafka:一個topic,一個partition,一個consumer consumer中使用多線程處理
針對ActiveMQ:可以使用獨占消費者,並且是循環里面的當前消費者,或者沒有獨占消費者。則循環里面的當前消費者即被選中能夠消費該條消息。
rabbitMQ:拆分成多個queue,一個queue只有一個consumer或者總共一個queue但是對應一個consumer 然后consumer內部使用隊列進行存儲然后分發進行處理;
kafka:一個topic,一個partition,一個consumer 使用單線程消費 寫到N個內存queue中,然后N個線程共同消費同一個queue;(根據業務id進行hash分別交給對應的線程處理)
寫入一個partition中的數據一定有順序的,生產者在寫的時候可以指定一個key,這個key相關的數據一定會被寫到同一個partition中並且是有順序的;?????
???? 一個queue 如何配置為多個consumer或者只有一個consumer?
7、如果消息存在積壓如何處理?(消息隊列的延時以及過期失效問題?消息隊列滿了如何處理?有幾百萬消息持續積壓幾小時)
分析積壓原因:
1)如果消費者掛了,消費者重啟,增加消費者 但是需要監控數據存儲的瓶頸比如數據庫;
2)如果消費者正常,消費不過來,新建一個topic 設置10個partition 將接收到的topic發送到新的topic,然后讓原有消費者改下topic連接新的patition進行消費;
消息隊列的失效問題(過期時間引起):禁止消息隊里過期,如果數據丟失了,需要手動寫程序將丟失的數據通過程序補回來進行查找;
8、如何設計一個消息隊列系統
1) 支持可伸縮 快速擴容,增加吞吐量和容量, 可以參考kafka理念:broker->topic-->partition 每一個partition分一台機器,存放一部分數據;如果現有資源不夠了 給topitc增加partition,然后進行數據遷移,增加機器;
2) 數據持久化 持久化采用順序寫,就沒有磁盤隨機讀寫的尋址開銷了,磁盤順序讀寫的性能很高,借鑒kafka的思路;
3) 可用性 采用kafka的高可用保障機制 多副本機制,leader機制
4) 數據0丟失 可以采用kafka數據0丟失方案;
9. ⽤過哪些 MQ,和其他 mq 比較有什什么優缺點, MQ 的連接是線程安全的嗎,你們公司的MQ 服務架構怎樣的
7. kafka 吞吐量高的原因。
8. kafka 和其他消息隊列的區別, kafka 主從同步怎么實現
9. 利用 mq 怎么實現最終一致性
10. 使⽤ kafka 有沒有遇到什么問題,怎么解決的
11. MQ 有可能發生重復消費,如何避免,如何做到冪等
12. MQ 的消息延遲了怎么處理,消息可以設置過期時間么,過期了你們⼀般怎么處理
16,kafka,activemq,rabbitmq本質區別是啥
rabbitMQ: https://www.jianshu.com/p/787d155ff4e1