一、kafka結構
kafka對外使用topic概念,生產者往topic寫消息,消費者從topic讀消息。爲了作到水平擴展一個topic實際由多個partition組成,經過增長partition數量來進行橫向擴容。kafka會爲partition選出一個leader,以後全部該partition請求實際操做都是leader,而後再同步到其餘follower,當一個broker歇菜後,全部leader在該broker上的partition都會從新選舉,選出一個leader緩存
消費偏移量保存:一個消費組消費partition,須要保存offset記錄消費到哪,0.10以前offset保存在zk中,0.10以後offset保存在_consumeroffsets topic的topic中。寫進消息的key由groupid、topic、partition組成,value是偏移量offset。每一個key的offset都是緩存在內存中,查詢時候不用遍歷partition,若是沒有緩存第一次會遍歷partition創建緩存,而後查詢返回。肯定consumer group位移信息寫入_consumers_offsets的那個partition計算公式:spa
__consumers_offsets partition =
Math.abs(groupId.hashCode() % groupMetadataTopicPartitionCount) //groupMetadataTopicPartitionCount由offsets.topic.num.partitions指定,默認是50個分區。
二、kafka多播消費
kafka同一個topic消息只能被同一個consumer group內其中一個consumer消費,而不能被全部消費者消費,故稱爲多播,但多個consumer group可同時消費這一消息。線程
對比rocketmq,同一個topic消息能夠被同一個comsumer group內全部consumer消費(採用MessageModel.BROADCASTING方式)code
對比rabbitmq,同一個queue內消息只能被一個消費實例消費;採用廣播(fanout)方式exchange能夠將消息廣播到全部綁定的queue中。blog
kafka若是實現廣播,只要每一個consumer有一個獨立的group便可;若是實現單播消費,只要全部consumer在同一個group裏rabbitmq
三、kafka順序消息
針對部分消息有序(message.key相同的message要保證消費順序),能夠在producer往kafka插入數據時控制,同一個key分發到同一個partition上,由於每一個partition是固定分配給某個消費者線程進行消費的。因此對於同一個分區的消息來講是嚴格有序的;內存
消息producer在發送消息時,對於一個有着前後順序的消息A、B,正常狀況下應該是A先發送完成後再發送B,可是在異常狀況下,在A發送失敗的狀況下,B發送成功,而A因爲重試機制在B發送完成以後重試發送成功了,這時對於自己順序爲AB的消息順序變成了BA。 爲解決此問題,嚴格的消費須要支持參數:max.in.flight.requests.per.connection,該參數含義:在發送阻塞前對於每一個鏈接,正在發送可是發送狀態未知的最大消息數量。若是設置大於1,那麼就有可能存在有發送失敗的狀況下,由於重試發送致使的消息亂序問題。因此咱們應該將其設置爲1,保證在後一條消息發送前,前一條的消息狀態已是可知的。kafka
rocketmq支持順序消費方式:message.key相同的message發往同一個queue上同步
rabbitmq支持順序消費:exchange不採用廣播方式,消息只發送到一條queue上requests