目錄
消息隊列
一、為什么使用消息隊列?消息隊列有什么優點/缺點?介紹下Kafka、ActiveMQ、RabbitMQ、RocketMQ有什么優點缺點,如何取舍?
1.公司業務場景是什么,這個業務場景有什么挑戰,如果不用MQ有什么麻煩,現在用了MQ有什么好處
2.消息隊列優點:
解耦(擔心掛)
異步
削峰
3.消息隊列缺點:
整個系統可用性降低(外部依賴變多,MQ掛了,系統掛了);復雜度變高(需要注意消息重復,消息遺漏,消息順序);引入了一致性問題(A系統完成返回成功,用戶以為成功,但B/C/D系統哪里某個失敗了,那就數據不一致了)
系統復雜度提高,可用性下降,還需要保證一致性
所以需要額外的架構來規避上述問題
4.Kafka、ActiveMQ、RabbitMQ、RocketMQ有什么優點缺點,如何取舍?
中小型公司用rabbitmq,社區活躍,基本滿足需求;大型公司研發能力雄厚,可用rocketmq;大數據實時領域用kafka很標準;
二、如何保證消息隊列的高可用性?
RabbitMQ(主從架構)
鏡像集群模式,是每個節點上都有queue和數據。寫消息到queue時,會自動把消息同步到多個實例的queue上。
Kafka(切分消息+replica副本機制)
broker,topic,partition,repilication
三、如何保證消息不被重復消費?如何保證消費消息的冪等性?(全局唯一標識ack /offset)
1.消息自己該有全局唯一標識,rabbitmq是ack,kafka是offset,記錄下來每次消費到哪個號碼了
2.結合業務,避免重復消費產生影響。比如數據庫的唯一鍵/主鍵,比如搭配redis
四、如何保證消息不會丟失?
三個可能性,生產者發送給MQ時丟失了;MQ自己丟失了;MQ發給消費者丟失了
生產端弄丟了數據(事務機制 offset)
MQ弄丟了數據(元數據持久化+confirmed機制)
消費端弄丟了數據(關閉自動提交offset)
關閉自動提交offset,重復消費保證冪等性
brocker宕機,重新選舉partition的leader,但其他follower還沒同步好數據,就會有數據丟失的問題
五、如何保證消息的順序性?(寫入的順序、讀取的順序)
消息是順序性有兩個方面,一個是寫入消息的順序,一個是讀取的順序
寫入時要保證順序,key來確認分配到哪個partition,一個partition對應一個消費者,
rabbitmq? ?queue
?kafka??一個topic,一個partition,一個consumer,內部單線程消費,這種吞吐低。
六、消息如果延時了或者處理過慢或者積壓了幾百萬消息或者過期了怎么解決
七、如果讓你寫一個消息隊列如何進行架構設計?
系統可拓展性
數據落地磁盤
mq的高可用性
數據0丟失
Kafka
基本概念
角色術語
Broker
Topic
Record
Partition
Offset
Replica
Producer
Consumer
Consumer Offset
Consumer Group
Rebalance
ISR
HW
LEO
拓撲架構
Topic、Partition、Segment、.log、.index、Message
Kafka分布式集群構建
核心設計原理
消息隊列
-
一、為什么使用消息隊列?消息隊列有什么優點/缺點?介紹下Kafka、ActiveMQ、RabbitMQ、RocketMQ有什么優點缺點,如何取舍?
-
1.公司業務場景是什么,這個業務場景有什么挑戰,如果不用MQ有什么麻煩,現在用了MQ有什么好處
- 進行投后業務場景后端從sqlServer無感知切花u你Mysql其中的數據校驗。這個業務場景的挑戰點就在于如何在真實場景中驗證業務邏輯(寫操作)的正確性,并保證不影響運營數據的維護,確保上線無問題。這就需要一套前端,一個操作,觸發兩個請求,一個是原有sqlserver 的請求,另一個是對Mysql數據庫操作,主要利用了消息隊列實現了雙寫操作,確保了原有運營數據的正常維護并且后端人員能在最真實最全面的待上線系統中實時進行數據對比
-
2.消息隊列優點:
-
解耦(擔心掛)
- 通過發布訂閱消息這個模型,使系統與系統之間解耦,掛了也不影響整體,
-
異步
- Mysql雙寫
-
削峰
- 有些時間段業務繁忙,但實際并不需要非常快速響應,可以利用消息隊列實現均勻處理消息,保證節點不會掛
-
-
3.消息隊列缺點:
-
整個系統可用性降低(外部依賴變多,MQ掛了,系統掛了);復雜度變高(需要注意消息重復,消息遺漏,消息順序);引入了一致性問題(A系統完成返回成功,用戶以為成功,但B/C/D系統哪里某個失敗了,那就數據不一致了)
-
系統復雜度提高,可用性下降,還需要保證一致性
-
所以需要額外的架構來規避上述問題
-
-
4.Kafka、ActiveMQ、RabbitMQ、RocketMQ有什么優點缺點,如何取舍?
-
? -
-
中小型公司用rabbitmq,社區活躍,基本滿足需求;大型公司研發能力雄厚,可用rocketmq;大數據實時領域用kafka很標準;
-
-
-
二、如何保證消息隊列的高可用性?
-
RabbitMQ(主從架構)
- 有幾種模式,第一種普通集群模式,是一個元數據queue存儲信息,消費者拉數據訪問到其他節點時,其他節點到queue所在節點拉數據,復制到其他節點再返回。
-
鏡像集群模式,是每個節點上都有queue和數據。寫消息到queue時,會自動把消息同步到多個實例的queue上。
- 網絡傳輸開銷大;而且這樣對于大消息是存儲不了的,存儲方面有瓶頸
-
Kafka(切分消息+replica副本機制)
-
broker,topic,partition,repilication
-
- kafka由多個broker構成,每個broker是一個節點;一個topic可以劃分為多個partition,每個partition可以存在于不同的broker上,每個partition就放一部分數據。(切分消息了,真正的分布式)
- kafka0.8以后,多了replica(復制品)副本機制。每個partition的數據都會同步到其他broker上,并且選舉leader,leader負責同步data到follower;生產和消費都只跟leader溝通,保證數據一致性。
- 寫數據時,生產者寫leader,leader將數據落入本地磁盤,接著其他follower自己主動到leader來Pull數據,一旦所有follower同步好數據,就會發送ack給leader,leader收到所有follower的ack后,就會返回寫成功的消息給生產者。
- 讀數據時,讀leader,leader如果掛了,就重新選舉leader,讀新leader;但是只有當一個消息已經被所有follower都同步成功返回ack的時候,才會被消費者讀到。
-
-
-
三、如何保證消息不被重復消費?如何保證消費消息的冪等性?(全局唯一標識ack /offset)
-
1.消息自己該有全局唯一標識,rabbitmq是ack,kafka是offset,記錄下來每次消費到哪個號碼了
-
2.結合業務,避免重復消費產生影響。比如數據庫的唯一鍵/主鍵,比如搭配redis
-
-
四、如何保證消息不會丟失?
-
三個可能性,生產者發送給MQ時丟失了;MQ自己丟失了;MQ發給消費者丟失了
-
生產端弄丟了數據(事務機制 offset)
- rabbitmq(事務機制)
- 生產者開啟事務機制,得到確認才commit,否則rollback(同步的)
- 吞吐量下來,耗性能
- 生產者開啟confirmed機制,每個消息有唯一id,一段時間沒有得到ack就重發該消息。(異步的)
- 生產者開啟事務機制,得到確認才commit,否則rollback(同步的)
- kafka
- offset,發送到哪記錄下
- rabbitmq(事務機制)
-
MQ弄丟了數據(元數據持久化+confirmed機制)
- rabbitmq
- 開啟rabbitmq元數據queue的持久化和消息的持久化,持久化到磁盤
- confirmed機制和持久化搭配起來,只有消息被持久化到磁盤,才發送ack通知生產者
- rabbitmq
-
消費端弄丟了數據(關閉自動提交offset)
- kafka
-
關閉自動提交offset,重復消費保證冪等性
-
brocker宕機,重新選舉partition的leader,但其他follower還沒同步好數據,就會有數據丟失的問題
- 1.給topic的partition設置副本數要大于等于2
- 2.在producer端設置acks=all,要求每條數據必須寫入所有replica后,才能認為是寫成功了
- acks=0,1,all 分別代表的情況
- 3.在producer端設置reties=MAX,要求一旦寫入失敗則無限充實
- 4.給kafka服務端設置min.insync.replicas>=1,要求一個leader感知到治沙一個follower還跟自己保持聯系沒掉隊,這樣才能確保Leader掛了還有一個follower
-
- kafka
-
-
五、如何保證消息的順序性?(寫入的順序、讀取的順序)
-
消息是順序性有兩個方面,一個是寫入消息的順序,一個是讀取的順序
-
寫入時要保證順序,key來確認分配到哪個partition,一個partition對應一個消費者,
-
rabbitmq? ?queue
- 拆分為多個queue,每個queue對應一個consumer;或者就一個queue,一個consumer,該consumer內部用內存隊列排隊,分發給不同的worker來處理
-
?kafka??一個topic,一個partition,一個consumer,內部單線程消費,這種吞吐低。
- 一個topic,一個partition,一個consumer,內部單線程消費,這種吞吐低。
- 寫N個內存queue,具有相同key的數據都到同一個內存queue,但是對于N個線程,每個線程分別消費一個內存queue即可。(多個queue,多個線程,但是queue與線程1V1)
-
-
六、消息如果延時了或者處理過慢或者積壓了幾百萬消息或者過期了怎么解決
-
1.解決消費端報錯,回復consumer消費速度
- 2.征用機器,擴大partition到十倍,consumer到十倍,十倍速度進行快速消費(臨時分發數據的consumer程序中,消費之后不做耗時處理,直接均勻輪詢寫入臨時建立好的10倍數量的的queue)
- 3.快速消費后,恢復原先部署的架構
- 過期:設置過期實踐ttl;寫代碼撈丟失的數據
- 快寫滿了:先用1,2,3進行快速消費數據,然后晚上再補撈數據
-
-
七、如果讓你寫一個消息隊列如何進行架構設計?
-
系統可拓展性
- 分布式的,便于快速拓展,數據切分,數據副本機制
- kafka的設計理念:broker->topic->partition,每個partition存放一個機器,存一部分數據,資源不夠,給topic增加partition,做數據遷移,增加機器
-
數據落地磁盤
- 順序寫,避免磁盤隨機讀寫的尋址開銷。磁盤順序讀寫的性能高
-
mq的高可用性
- replica副本機制->leader&follewer->broker掛了重新選舉Leader即可對外服務
- 消費端Rebalance,某消費者實例掛掉后,再均衡分配實例
-
數據0丟失
- 數據多了怎么辦,大了怎么辦,丟了怎么辦,重復消費了怎么辦,過期了怎么辦,保證順序怎么辦
-
-
Kafka
-
基本概念
- 高吞吐的分布式發布/訂閱消息系統,即 為不同系統之間傳遞消息的
- 存儲系統,得益于 其消息持久化功能和多副本機制
- 分布式流處理平臺,有完整的流式處理類庫
-
角色術語
-
Broker
- 數據存儲中心。每個kafka集群包含一個或多個服務器,每個服務器被稱為broker
-
Topic
- 每條發布到Kafka集群的消息都有個分類,類別即為Topic(主題),用來區分具體業務
-
Record
- 消息
-
Partition
- 每個Topic包含一個或多個Partition,每個Partition都是有序不變的隊列,Partition中的每條消息都會被分配一個唯一ID (稱為offset)
-
Offset
- 每條消息的位置信息,單調遞增且不變的量
-
Replica
- 副本,數據冗余,高可用
-
Producer
- 消息的生產者,負責發布消息push到kafka broker
-
Consumer
- 消息的消費者,負責到broker去pull消息來消費
-
Consumer Offset
- 消費者位移,代表消費進度
-
Consumer Group
- 消費者組,可以給每個consumer指定消費者組,若不指定,則為默認的group。同時消費多個Partition以實現高吞吐
-
Rebalance
- 再平衡。消費者組內某個消費實例掛掉后,其他消費者實例自動重新分配訂閱主題分區的過程。Rebalance是Kafka消費者端實現高可用的重要手段。
-
ISR
- In-Sync Replica Set.ISR集合代表每個分區的一組同步集合,處于 ISR 集合中的副本,意味著 follower 副本與 leader 副本保持同步狀態,只有處于 ISR 集合中的副本才有資格被選舉為 leader
-
HW
- HightWatermark,水位線,指的是消費者能見到的最大的offset,ISR隊列中最小的LEO
-
LEO
- Log End Offset, 指的是每個副本最大的offset;
-
- Log End Offset, 指的是每個副本最大的offset;
-
-
拓撲架構
- 多個producer,多個broker,多個 consumer group,外加一個zookeeper。zookeeper來進行管理集群配置,選舉Leader,在Consumer Group發生變化時進行rebalance。
- Producer push 消息 發布到broker,consumer使用pull模式從broker訂閱并消費消息。
- 生產者將消息分布到不同broker上的不同partition上,消費者可以消費集群中多個節點的多個partition。
- 寫消息時,允許多個生產者寫道同一個partition中
- 但讀消息時,一個partition只能被一個消費者組的一個消費者讀,但是可以同時被其他消費組讀取。(消費者組內的消費者讀partition互斥)
- 支持消息持久化存儲。持久化數據存儲在log日志文件中。(先緩存在內存,到達一定閾值再統一寫入磁盤,減少磁盤IO調用次數)
- 消息寫入Partition,是順序寫入磁盤的,避免隨機讀寫的 “尋頭”磁頭不停移動(磁盤的性能瓶頸之一,SSD例外)
-
Topic、Partition、Segment、.log、.index、Message
- topic的partition數字決定了組成topic的log的數量,>=同時運行的consumer,>集群broker的數量,盡可能均勻分布在broker中
- kafka是基于文件存儲的,partition可用來拆分topic,將大量消息分成多批寫到不同節點上,均衡負載。
- 每個partition對應一個文件夾,存儲該partition的消息,以大小相等的segment文件夾為單位,內容為 消息索引(.index)和消息數據(.log)。partition命名為topic+序號(0,1,...)
-
- Partition文件夾的命名,Segment文件夾的命名,.index 和 .log的切分和命名
-
- Message的物理結構
-
-
Kafka分布式集群構建
- kafka2.8.0版本中移除了對Zookeeper的依賴,通過KRaft進行自己的集群管理。
- 一些配置參數:
- brocker.id
- 若服務器ip地址變化時,只要brocker.id沒有變,就不會影響consumer的消費
- log.dirs
- 配置kafka保存數據的位置
- num.partitions
- topic的分區數,過小會影響性能
- logs.segment.bytes
- 配置每個segment數據文件的大小,默認是1G,超過這個大小會自動創建一個新的segment
- delete.topic.enable
- 在0.8.2版本之后,kafka提供的刪除topic 的功能,但是默認不會物理刪除topic數據。如果需要物理刪除,設為true
- acks
- 指定必須多少個分區副本收到消息,生產者才會認為寫入消息是成功的。(對消息丟失的可能性有重大影響)
- acks=0:寫入消息之前不會等待任何來自服務器的響應,容易丟消息,但是吞吐量高
- aks=1(leader):只要集群的leader節點收到消息,生產者就會收到來自服務器的成功響應。可靠性中等,leader如果發生問題,follower未來得及同步,就會丟失部分數據
- acks=-1(all):只有當所有參與復制的節點都收到消息,生產者才會收到一個來自服務器的成功響應。延遲高。
- 指定必須多少個分區副本收到消息,生產者才會認為寫入消息是成功的。(對消息丟失的可能性有重大影響)
- brocker.id
-
核心設計原理
- 存儲機制
- 備份和副本機制
- 日志設計
- Controller控制器
- Rebalance
- 可靠性設計
- 延遲、死信、重試隊列等
-