MQ常問的問題-rabbitMQ和kafka

MQ的優點:

解耦:如果不用mq,系統之間各種調用,很複雜,需要依賴被調用方的jar包,需要考慮新假如接口,系統宕機,調用超時等情況,但是使用mq之後,調用方不用再假如代碼,而且只需要將消息發送到mq中,其他的不用關心。

異步:要延時場景。就是一個系統如果同步調用,會耗時很長,但是是如果改成異步的,比如說a系統可以發送3個消息到對應的3個隊列中,那麼這三個隊列相當於是並行進行。

削峯:高峯期請求量太大,直接打到系統,可能會造成下游的被調用方或者是數據庫直接死掉,那麼就需要把請都放到mq中,然後又下游服務或者是數據庫每秒最大處理速度進行處理。而積壓下來的消息再高分期過了之後再慢慢的消化掉。

 

MQ的缺點:

加入mq的複雜性增加了,可用性差了。其實我們在寫程序的時候,應該遵循一個標準,在合理的設計的時候,儘量不引入第三方框架,因爲引入之後,系統的複雜性在原來的基礎上是增加的,所以,需要保證mq的高可用,消息的不丟失,不重複,順序性等等問題。

一致性問題。系統a用mq調用其他的系統bcd,但是如果bcd其中有一個系統出問題,那麼就會導致後臺執行失敗,但可能返回給客戶的是正確的。

 

mq的高可用:

rabbitmq有倆種高可用模式,一種是普通的模式,比如說3太機器,我們創建的queue會隨機在一臺機器上存在,在這臺機器上會保存queue的元數據和消息數據。但是其他倆臺機器只會保存他的元素據,當有請求發送到其他倆太機器的時候,機器會從存在消息數據的機器上獲取數據,並且返回,那麼這裏其實存在問題,數據傳輸佔用的網絡帶寬,實例機器掛掉,導致集羣不能使用,和磁盤空間滿了的情況。

rabbitmq另一種模式叫做鏡像模式,還是3臺機器,但是每一臺 機器中都保存者完整數據的鏡像,每次訪問任意一臺機器,就可以,省區了網絡開銷。但他的集羣模型任然不是分佈式的,因爲如果磁盤滿了的話,是沒法做出有效解決的。 鏡像模式模式的設置在rabbitmq的管理界面中設置,就是設置隊列同步數據的機器臺數策略,是全部同步。

kafka的分佈式高可用:

 

kafka的消息類型可以用topic的分類,比如說訂單的消息作爲一個topic,並且爲這個topic分配了3個broker,每一個broker就是一個kafka的實例,每臺broker上作爲一個topic的partition,叫做partition的副本,並且爲了保證高可用,給每個partition副本設置一個replica的副本,主副本和raplica的消息是一執的,可以說主的副本的relica組成了領導者和追隨者的結構,這裏無論是消息的寫入和消費者的消費都是從主partition完成的,raplica只是作爲他的一個消息備份。當一個主partition掛掉之後,kafka會從其他的replica中選舉出副本。

而一條消息從生產者生產出來,只能進入一個topic的一個partion中,且他在partition中的順序永offset來標識。

 

mq中存在重複數據(或者保證消息消費的冪等性):

kafka中,每一條消息的在partition中中都有唯一的offset的,消費者消費也是按照offset的順序進行消費的,且消費者每次在消費了一批消息的時候,會將offset序號返回給zk,kafka從zk中就可以知道消費者消費到哪裏了,但是這裏有一個問題,就是假如消費者在消費了幾條消息後,沒來的急將offset回傳給zk,那麼下次重啓之後,就會造成kafka重複的將消息發送給消費者,早着消息重複。所以,要保證冪等性。總體思路就是,每次將消息存儲到一個都可以訪問到的公共區域,然後每條消息進來之後都會詢問在公共區域是否存在同樣的消息,如果存在,說明這條消息重複了,那麼就不能消費;基於此,我們可以將消息存儲到map中,redis中,或者數據庫中,利用唯一鍵來標識。

 

消息丟失:

rabbitmq中,導致消息丟失的地方總共有三處,第一處是生產者發送給rabbimq過程中丟失;第二處是rabbitmq在服務器中丟失;第三種是rabbitmq發送給消費者造成數據丟失;

第一處丟失,倆種對策,第一種,按照rabbitmq的事務來處理,發送消息之前開啓事務,同步等待消息反饋,如果報錯,執行rollback,並且再次發送消息;第二種,將channel設置成爲confirm模式,如果消息發送成功,會異步回調ack方法,如果失敗會回調nack方法;

第二處丟失,是需要將消息在服務器做持久化。第一種是需要將queue設置爲持久化(drable爲true),那麼rabbitmq會將隊列的元素據做持久化,然後需要將deliveryMode設置爲2,rabbitmq會將消息數據持久化到磁盤空間,保證服務器宕機之後重啓,會重新加載磁盤的數據。

第三處丟失,其實只有一種可能,就是把消費者反饋rabbitmq的機制設置爲autoACK了。原因就是rabbitmq將消息發送到消費者,消費者自動返回給rabbitmq消費成功,但是在消費者處理消息過程中宕機了,那麼就會造成數據丟失,所以,其實就需要將autoACK關閉,然後再消息消費完成後,執行手動ack;

kafka中:同樣有三處,原理是一樣的額,第三處,如果kafka的消費者消息丟失了,那麼其實也需要將自動反饋zk的機制關閉,然後設置爲手動關閉。

第二處,kafka服務器會丟失。原因可能即使消息發送到了patition,但是沒有同步到replica的時候,partition掛掉了,造成數據丟失。對於此,kafka中需要設置4個參數,topic的replicatioin.factor至少爲大於1,保證副本數; 設置min.insync.replicas大於1,保證至少有一個raplica和partitioin保持數據同步; 再producer端設置acks=all,標識所有的副本同時數據成功之後,生產者才認爲是消息發送成功; 再producer設置retries設置爲一個很大的值,保證給如果同步不成功,生產者會重複發送很多次的消息,保證重試次數。

 

消息的順序性:

rabbitmq保證需要有序處理的處理進入到容易個消費者中即可;

 

mq延遲過期怎麼解決,消費隊列滿了,或者隊列中有幾百萬的消息:

消息有積壓了,怎麼辦? 簡單倆說,就是加機器加速消費,等消費隊額差不多了,把機器撤了;這幾個機器的增加,不僅僅是需要增加mq服務器,也需要增加消費者;第一將原來的消費者修改一下,把消息重發到一個新建的臨時mq中,然後增加消費者對這個新建的mq的消息進行消費,等到消息積壓下去之後,再把新增的機器撤走,把代碼該回去;

但是假如設置了過期時間?這個一般不推薦設置,但是如果出現了,那麼丟失的數據,就只能再線下將數據找出來,然後重新發送到mq中進行消費。

 

kafka基礎知識:

topic: 主題;可以根據業務劃分,每個業務分爲一個主題。

實例時Broker:

高可用Replication:

副本Replica:Leader Replica: Follower Replica:代替master-slave;

 

生產者想領導副本寫,消費者從領導者副本讀;追隨者副本不提供服務,只是追隨領導者副本,完整內容複製;

分區Partitioning: 一個topic可以分爲多個分區,分區從0開始;每個分區是有序的消息日誌;生產者的消息只能被髮到一個分區中。每個分區可以有若干個副本,其中一個是領導者副本,剩下的都是追隨者副本;消息在每一個分區的位置叫做位移(有的地方叫做便宜量)offset,也是從0開始;

 

kafka分層:

第一層主題層;每個主題層可以有m個分區,每個分區有n個副本;

第二層是分區層;每個分區n個副本;這些副本中只能有一個是領導者副本,其他都是追隨者副本;

第三層是消息層;在副本中,每個消息又對應該的位移。

客戶端只能和分區中的領導者副本做交互;

 

kafka的持久化:

kafka的持久化利用日誌來實現,且只提供追加寫的方式(append-only),可減少io操作;

 

kafka磁盤大小選擇:

每條消息預估大小;

每天新增消息預估數量;

數據留存時間;

備份份數;

消息大小 * 預估條數 - 》 換算成Gb * 1.1 * 備份份數 * 預留時間 * 0.75

 

消息縮影數等等 佔 所需 大小的 10%;

消息壓縮率是 0.75;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章