三大優(yōu)點(diǎn):
1.架構(gòu)解耦
2.流量控制
3.異步處理
缺點(diǎn):
1.消息丟失
2.消息重復(fù)
3.消息亂序
4.消息堆積
kafka如何解決這些問題
1.消息丟失。
日志場(chǎng)景,偶爾某條消息丟失也沒關(guān)系。要求消息一定不丟失,從三個(gè)方面設(shè)置:
a.生產(chǎn)者端,必須等消息的成功確認(rèn)。kafka端有ack=all選項(xiàng)。
b.broker端,消息落盤再回復(fù)成功。而且replica數(shù)一定要大于1,保證每個(gè)分區(qū)有多個(gè)副本.
c.消費(fèi)者端,必須要等消息處理完畢再提交。
2.消息重復(fù)
消息重復(fù)的問題是由于生產(chǎn)者端可能由于某種原因沒有收到broker端的成功確認(rèn),然后重復(fù)發(fā)送消息導(dǎo)致的。
如果生產(chǎn)者端不要求消息不丟失,那么只發(fā)送不管發(fā)送結(jié)果,就不會(huì)產(chǎn)生消息重復(fù)問題。
要保證消息不丟失,broker端必定會(huì)產(chǎn)生消息重復(fù)問題。
要避免這個(gè)問題,只能從消費(fèi)者端解決。簡(jiǎn)而言之,就是保證消費(fèi)端消費(fèi)的冪等性。
保證消費(fèi)端的消費(fèi)冪等性,有如下幾個(gè)方法:
1.每個(gè)消息給一個(gè)全局id,消費(fèi)端消費(fèi)后將id寫到redis。每次消費(fèi)時(shí)需要先去redis查一遍全局消息id
2.mysql插入數(shù)據(jù),先查一下主鍵。有就update。
3.數(shù)據(jù)庫設(shè)置唯一鍵。
3.消息亂序
kafka多分區(qū)之間數(shù)據(jù)可能是不是有序的。只有單個(gè)分區(qū)內(nèi)的數(shù)據(jù)可以保證唯一性。
要保證唯一數(shù)據(jù)有序,唯一的辦法只能是單topic單分區(qū)。生產(chǎn)端發(fā)送數(shù)據(jù)的時(shí)候指定key,這樣數(shù)據(jù)就會(huì)被發(fā)送到同一個(gè)分區(qū)。
消費(fèi)者端分兩個(gè)步驟:消費(fèi)+處理。一般處理比較耗時(shí)。我們可以采用一個(gè)線程專門消費(fèi),然后對(duì)clientId進(jìn)行哈希,將消息分別哈希到N個(gè)內(nèi)存消息隊(duì)列,每個(gè)內(nèi)存消息隊(duì)列再用一個(gè)線程去處理。4C32G的機(jī)器,一般可以達(dá)到1000的qps。

4.消息擠壓
消息擠壓的原因無非是消費(fèi)能力與生產(chǎn)能力不匹配。
先從業(yè)務(wù)邏輯上優(yōu)化,能批量執(zhí)行的,則先批量執(zhí)行。優(yōu)化后還是沒法提高,只能水平擴(kuò)容。
假如沒消費(fèi)完,mq快爆炸了,那么可以先用一個(gè)服務(wù)將消息快速消費(fèi)后存放到一個(gè)臨時(shí)的mq,然后再慢慢消費(fèi)。