kafka 是一個(gè)分布式的,分區(qū)的,復(fù)制的提交日志服務(wù)
分布式:kafka可以提供集群服務(wù),它是由一個(gè)或者多個(gè)broker組成,每個(gè)broker都可以響應(yīng)客戶端請(qǐng)求
分區(qū):體現(xiàn)在kafka消息中,topic代表著一類消息,一個(gè)topic有多個(gè)分區(qū),并且按照一定的規(guī)則分布在broker集群中
復(fù)制:一個(gè)topic 的分區(qū)有多個(gè)副本,按照一定的規(guī)則分布在broker集群中,副本可分為leader和follow,leader所在broker負(fù)責(zé)響應(yīng)客戶端的讀寫請(qǐng)求,follow周期性地同步leader數(shù)據(jù),已防止leader故障后消息丟失
提交日志:kafka的消息是以日志的方式進(jìn)行存儲(chǔ)的
kafka 組件由生產(chǎn)者,消費(fèi)者,代理服務(wù)器broker 和zk 組成
生產(chǎn)者負(fù)責(zé)往broker上寫消息,由于topic消息是分區(qū)的,因此生產(chǎn)者可以同時(shí)往broker上同時(shí)發(fā)起寫請(qǐng)求,從而提高寫吞吐量

消費(fèi)者負(fù)責(zé)往broker拉取消息,消費(fèi)者是以組的形式消費(fèi)消息的,一個(gè)消費(fèi)者組由多個(gè)消費(fèi)者組成,broker 按照分配策略將topic 的分區(qū)分配給消費(fèi)者,topic 的一個(gè)分區(qū)只能分配給消費(fèi)者組的一個(gè)消費(fèi)者,因此保證了一個(gè)分區(qū)的消息是順序消費(fèi)的。也保證了topic 將消息廣播給消費(fèi)者組,而一個(gè)消費(fèi)者組消費(fèi)消息保證了點(diǎn)對(duì)點(diǎn)消費(fèi)

zk:負(fù)責(zé)管理broker 集群
producer:
發(fā)送位置:producer 按topic 發(fā)送消息,消息是以kv的格式進(jìn)行發(fā)送的,如果key 為null,那producer 將消息輪詢的發(fā)送到各個(gè)分區(qū)中,如果key不為null,producer默認(rèn)按hash的方式將消息發(fā)送到各個(gè)分區(qū)中。 producer 在發(fā)送之前,就會(huì)將消息按分區(qū)進(jìn)行分組,然后按分區(qū)所在的節(jié)點(diǎn)進(jìn)行分組構(gòu)建發(fā)送請(qǐng)求。
發(fā)送方式:producer 發(fā)送消息可分為同步發(fā)送和異步發(fā)送。通過(guò)配置acks 控制,當(dāng)acks 為 0時(shí),producer 發(fā)送消息將不會(huì)等待leader分區(qū)以及follow 分區(qū)所在broker確認(rèn)直接返回(不能保證消息以及被服務(wù)器接收到),acks 為 1時(shí),producer 將會(huì)等待leader分區(qū)的確認(rèn)并返回。為-1或?yàn)閍ll時(shí),producer 會(huì)等待leader確認(rèn)以及配置文件??in-sync replicas 配置的follow個(gè)數(shù)確認(rèn)后返回。
調(diào)優(yōu)點(diǎn):
1.acks設(shè)置:設(shè)置0時(shí),寫吞吐量最高,但不能保證消息發(fā)送的準(zhǔn)確性。為1時(shí),一種折衷方案,但如果leader所在broker掛且副本還沒(méi)有同步消息,那么消息仍會(huì)丟失。為-1時(shí),消息可靠性最高,但寫吞吐量最低。這得根據(jù)實(shí)際的業(yè)務(wù)場(chǎng)景去設(shè)置。
2.batch.size 設(shè)置:producer 發(fā)送消息是按batch發(fā)送的,當(dāng)batch達(dá)到設(shè)置大小后,producer 就會(huì)將該batch發(fā)送到服務(wù)器去。單位為byte ,推薦大小為512k
3.linger.ms 設(shè)置:延遲發(fā)送的實(shí)際,單位為秒,producer將消息根據(jù)配置的延遲時(shí)間延遲發(fā)送,如果到了延遲的時(shí)間,batch消息沒(méi)滿,那么producer 也會(huì)將該batch發(fā)送到服務(wù)器中去
4.buffer.memory 設(shè)置:?jiǎn)挝粸閎yte,kafka為將所有batch 存儲(chǔ)在buffer中,如果buffer滿載,那么producer 會(huì)發(fā)生阻塞。
5.可以利用多線程創(chuàng)建多個(gè)producer 發(fā)送消息
consumer:
分區(qū)分配策略:當(dāng)一個(gè)消費(fèi)組有多個(gè)消費(fèi)者時(shí),kafka提供三種策略將topic的分區(qū)分配給消費(fèi)者,策略分別是range,roundrobin和Sticky
range:kafka 會(huì)將topic 的分區(qū)按照序號(hào)排序,消費(fèi)者會(huì)按照字母順序進(jìn)行排序,然后將分區(qū)總數(shù)除以消費(fèi)者總數(shù)來(lái)確定每個(gè)消費(fèi)者線程消費(fèi)幾個(gè)分區(qū)。如果除不盡,序號(hào)為前面幾個(gè)的消費(fèi)者會(huì)多消費(fèi)一個(gè)分區(qū)。例如:
排序過(guò)的分區(qū)序號(hào)為 0 1 2 3 排序過(guò)的消費(fèi)者線程為:c-0 c-1 c-2 最后的分配結(jié)果為:
c-0 p(0,3)
c-1 p(1)
c-2 p(2)
如果分區(qū)序號(hào)為 0 1 2 3 4? 消費(fèi)者線程為 c-0 c-1 c-2 結(jié)果為:
c-0 p(0,3)
c-1 p(1,4)
c-2 p(2)
缺點(diǎn):如果在多個(gè)topic 和多個(gè)分區(qū)的情況下,前面的消費(fèi)者會(huì)多消費(fèi)多個(gè)分區(qū),造成消息消費(fèi)不均,影響性能。
roundrobin:將所有主題的所有分區(qū)放置到TopicAndPartition列表中,并對(duì)該列表進(jìn)行hash 排序,在將消費(fèi)者按字母進(jìn)行排序,將排序號(hào)的列表總數(shù)除于消費(fèi)者總數(shù)確定消費(fèi)者所消費(fèi)的分區(qū)個(gè)數(shù)。如果除不進(jìn),前面的消費(fèi)者就多消費(fèi)一個(gè)分區(qū)。
假如按照 hashCode 排序完的topic-partitions組依次為T1-5, T1-3, T1-0, T1-8, T1-2, T1-1, T1-4, T1-7, T1-6, T1-9,我們的消費(fèi)者線程排序?yàn)镃1-0, C1-1, C2-0, C2-1,最后分區(qū)分配的結(jié)果為:
C1-0 將消費(fèi) T1-5, T1-2, T1-6 分區(qū);
C1-1 將消費(fèi) T1-3, T1-1, T1-9 分區(qū);
C2-0 將消費(fèi) T1-0, T1-4 分區(qū);
C2-1 將消費(fèi) T1-8, T1-7 分區(qū);
roundrobin是將所有的topic 的所有分區(qū)進(jìn)行hash排序,最后按照range的方式進(jìn)行分區(qū)。
使用RoundRobin策略有兩個(gè)前提條件必須滿足:
同一個(gè)Consumer Group里面的所有消費(fèi)者的num.streams必須相等;
每個(gè)消費(fèi)者訂閱的主題必須相同。
sticky:
分區(qū)的分配要盡可能的均勻;
分區(qū)的分配盡可能的與上次分配的保持相同。
當(dāng)兩者發(fā)生沖突時(shí),第一個(gè)目標(biāo)優(yōu)先于第二個(gè)目標(biāo)。鑒于這兩個(gè)目標(biāo),StickyAssignor策略的具體實(shí)現(xiàn)要比RangeAssignor和RoundRobinAssignor這兩種分配策略要復(fù)雜很多。我們舉例來(lái)看一下StickyAssignor策略的實(shí)際效果。
消費(fèi)語(yǔ)義:kafka 提供三種消費(fèi)語(yǔ)義,分別是 至少一次 至多一次 和正好一次。
至少一次:消費(fèi)者在接收消息并處理完成時(shí),再通知服務(wù)端將該消息標(biāo)記為已消費(fèi)。如果在提交到服務(wù)器時(shí)發(fā)送了故障,那么下次再消費(fèi)消息時(shí),會(huì)重復(fù)消費(fèi)消息。
至多一次:消費(fèi)者在接收到消息時(shí),就向服務(wù)端將該消息標(biāo)記為已消費(fèi)。最后才對(duì)消息進(jìn)行處理。如果在處理之前或處理中的時(shí)候發(fā)送了故障,那么該消息會(huì)丟失。
正好一次:關(guān)閉消費(fèi)者自動(dòng)提交偏移量,將消費(fèi)者消費(fèi)的偏移量存儲(chǔ)在外部存儲(chǔ)系統(tǒng)中,在消費(fèi)者消費(fèi)開始消費(fèi)消息時(shí),從存儲(chǔ)系統(tǒng)中獲取偏移量,并從該偏移量開始消費(fèi)消息。消息處理完后再將偏移量提交到外部存儲(chǔ)系統(tǒng)中。這其中的操作要保證原子性。
消費(fèi)者再平衡條件:1.消費(fèi)者組新增或移除消費(fèi)者 2.broker 宕機(jī)?