kafka的基本概念
- kafka特點(diǎn)1:是基于發(fā)布訂閱模式,而非pear-pear模式,消費(fèi)者可以有多個(gè),實(shí)質(zhì)是一個(gè)生產(chǎn)者-消費(fèi)者模型鲸拥,用來處理數(shù)據(jù)流。
- kafka特點(diǎn)2:處理數(shù)據(jù)高效并實(shí)時(shí)
- kafka特點(diǎn)3:數(shù)據(jù)流在分布式集群中安全復(fù)制存儲(chǔ)
總之:kafka是用于構(gòu)建實(shí)時(shí)的數(shù)據(jù)管道和流應(yīng)用程序僧免。具備橫向擴(kuò)展刑赶,容錯(cuò)等優(yōu)點(diǎn)。
kafka名詞解釋
- Broker:一個(gè)kafka服務(wù)器節(jié)點(diǎn)就是一個(gè)Broker懂衩,消息被持久化到Broker上撞叨。broker只管數(shù)據(jù)存儲(chǔ)金踪,不管是誰生產(chǎn),不管是誰消費(fèi)谒所。在集群中每個(gè)broker都有一個(gè)唯一brokerid热康,不得重復(fù)。
- Topic:消息的一個(gè)主題劣领,每生產(chǎn)的一條消息都對(duì)應(yīng)一個(gè)Topic,這樣就可以將消息歸類姐军,消費(fèi)者就可以選擇性的消費(fèi)了。
- producer:消息生產(chǎn)者尖淘,有服務(wù)端console類型的奕锌,可以在控制臺(tái)輸入生產(chǎn)消息,也有和編程語言集成的API村生,可以在工程中生產(chǎn)消息惊暴。
- consumer:消費(fèi)者,和生產(chǎn)者類似趁桃,也有服務(wù)端console類型的辽话,可以在控制臺(tái)接收消息,也有API接口控制在項(xiàng)目中自己消費(fèi)消息卫病。一個(gè)消費(fèi)者是一個(gè)線程油啤。
- consumerGroup:消費(fèi)者組,消費(fèi)端消費(fèi)消息的時(shí)候是以group為單位消費(fèi)蟀苛,一個(gè)topic下的消息可以被不同的group消費(fèi)益咬。以group消費(fèi)是為了不同業(yè)務(wù)可以都消費(fèi)消息,而且當(dāng)有新增消費(fèi)需求的時(shí)候帜平,直接增加consumer group即可幽告。
consumerGroup組員之間不能重復(fù)消費(fèi)。
- partition:kafka是面對(duì)分布式系統(tǒng)的裆甩,同時(shí)一個(gè)topic對(duì)應(yīng)partition冗锁,一個(gè)partition有多個(gè)副本,會(huì)從所有的副本中選取一個(gè)leader出來。所有讀寫操作都是通過leader副本來進(jìn)行的淑掌。一個(gè)partition是個(gè)有序隊(duì)列蒿讥。
partition的目錄中有多個(gè)segment組合(index,log)一個(gè)Topic對(duì)應(yīng)多個(gè)partition[0,1,2,3],一個(gè)partition對(duì)應(yīng)多個(gè)segment組合抛腕。一個(gè)segment有默認(rèn)的大小是1G,消息都在segment上面存儲(chǔ)媒殉。
- partition中每個(gè)message只能被consumer group中的一個(gè)consumer消費(fèi)担敌。而且一個(gè)consumergroup里面的所有consumer都必須按順序讀取partition中的message,新啟動(dòng)的consumer默認(rèn)從partition隊(duì)列的頭開始阻塞得讀message.
- kafka吞吐量大的原因:
- kafka針對(duì)一個(gè)partition,不是通過多個(gè)consumer thread加悲觀鎖來防止重復(fù)消費(fèi)廷蓉,而是一個(gè)partition只能同時(shí)被一個(gè)consumer thread消費(fèi)全封,如果消息數(shù)量太大覺得效率不高要增大吞吐量马昙,直接橫向擴(kuò)展partition數(shù)量,同時(shí)增加一個(gè)consumer group下的consumer thread數(shù)量即可刹悴。這樣沒有鎖競爭行楞,充分發(fā)揮了橫向的擴(kuò)展性,吞吐量極高土匀。
- kafka分布式并發(fā)的讀和寫都非匙臃浚快,寫的性能體現(xiàn)在以o(1)的時(shí)間復(fù)雜度進(jìn)行順序?qū)懭刖驮Wx的性能體現(xiàn)在以o(1)的時(shí)間復(fù)雜度進(jìn)行順序讀取证杭, 對(duì)topic進(jìn)行partition分區(qū),consume group中的consume線程可以以很高能性能進(jìn)行順序讀妒御。
效率最優(yōu)配置:
consumer group下的consumer thread的數(shù)量等于partition數(shù)量解愤,這樣效率是最高的。
Consumer怎么消費(fèi)kafka的topic的所有的partition的message的呢乎莉?
kafka消息是順序讀取送讲,必須維護(hù)上一次讀到哪里的offset信息。維護(hù)offset有兩套機(jī)制惋啃,high level API的offset存于Zookeeper中哼鬓;low level API的offset由自己維護(hù)。
- 當(dāng)使用high level api的時(shí)候
offset是維護(hù)在Zookeeper上肥橙,先拿message處理魄宏,再定時(shí)自動(dòng)commit offsite+1(也可以改成手動(dòng)), 并且kakfa處理message是沒有鎖操作的。
因此如果處理message失敗存筏,此時(shí)還沒有commit offsite+1宠互,當(dāng)consumer thread重啟后會(huì)重復(fù)消費(fèi)這個(gè)message。
但是作為高吞吐量高并發(fā)的實(shí)時(shí)處理系統(tǒng)椭坚,at least once的情況下予跌,至少一次會(huì)被處理到,是可以容忍的善茎。 - 如果無法容忍券册,就得使用low level api來自己程序維護(hù)這個(gè)offsite信息,那么想什么時(shí)候commit offsite+1就自己搞定了垂涯。
- 消息生產(chǎn)端不用維護(hù)offset烁焙,因?yàn)橄ffset默認(rèn)是自增的。Kafka的producer一般都是大批量的batch發(fā)送message耕赘,向這個(gè)topic一次性發(fā)送一大批message骄蝇,load balance到一個(gè)partition上,一起插進(jìn)去操骡,offsite作為自增id自己增加就好九火。
At Least模型
因?yàn)橄⒌淖x取進(jìn)度由offset提供赚窃,offset可以由消費(fèi)者自己維護(hù)也可以維護(hù)在zookeeper里,但是當(dāng)消息消費(fèi)后consumer掛掉岔激,
offset沒有即時(shí)寫回勒极,就有可能發(fā)生重復(fù)讀的情況,這種情況同樣可以通過調(diào)整commit offset周期虑鼎、閾值緩解辱匿,甚至消費(fèi)者自己把消費(fèi)和commit offset做成一個(gè)事務(wù)解決,
但是如果你的應(yīng)用不在乎重復(fù)消費(fèi)震叙,那就干脆不要解決掀鹅,以換取最大的性能。
consumer API
Kafka提供了兩套consumer api媒楼,分為high-level api和sample-api乐尊。
- Sample-api 是一個(gè)底層的API,它維持了一個(gè)和單一broker的連接划址,并且這個(gè)API是完全無狀態(tài)的扔嵌,每次請求都需要指定offset值,因此夺颤,這套API也是最靈活的痢缎。
在kafka中,當(dāng)前讀到哪條消息的offset值是由consumer來維護(hù)的世澜,因此独旷,consumer可以自己決定如何讀取kafka中的數(shù)據(jù)
。比如寥裂,consumer可以通過重設(shè)offset值來重新消費(fèi)已消費(fèi)過的數(shù)據(jù)嵌洼。不管有沒有被消費(fèi),kafka會(huì)保存數(shù)據(jù)一段時(shí)間封恰,這個(gè)時(shí)間周期是可配置的麻养,只有到了過期時(shí)間,kafka才會(huì)刪除這些數(shù)據(jù).
- High-level API
High level api是consumer讀的partition的offsite是存在zookeeper上诺舔。High level api 會(huì)啟動(dòng)另外一個(gè)線程去每隔一段時(shí)間鳖昌,offsite自動(dòng)同步到zookeeper上。
換句話說低飒,如果使用了High level api许昨, 每個(gè)message只能被讀一次,一旦讀了這條message之后褥赊,無論我consumer的處理是否ok车要。
High level api的另外一個(gè)線程會(huì)自動(dòng)的把offiste+1同步到zookeeper上。如果consumer讀取數(shù)據(jù)出了問題崭倘,offsite也會(huì)在zookeeper上同步翼岁。
因此,如果consumer處理失敗了司光,會(huì)繼續(xù)執(zhí)行下一條琅坡。因此,Best Practice是一旦consumer處理失敗残家,直接讓整個(gè)conusmer group拋Exception終止
榆俺,但是最后讀的這一條數(shù)據(jù)是丟失了,因?yàn)樵趜ookeeper里面的offsite已經(jīng)+1了坞淮。
等再次啟動(dòng)conusmer group的時(shí)候茴晋,已經(jīng)從下一條開始讀取處理了。
- Low level API
consumer讀的partition的offsite在consumer自己的程序中維護(hù)回窘。不會(huì)同步到zookeeper上诺擅。
但是為了kafka manager能夠方便的監(jiān)控,一般也會(huì)手動(dòng)的同步到zookeeper上啡直。
kafka如何保證數(shù)據(jù)的完全生產(chǎn)
ack機(jī)制:broker表示發(fā)來的數(shù)據(jù)已確認(rèn)接收無誤烁涌,表示數(shù)據(jù)已經(jīng)保存到磁盤。
- 0:不等待broker返回確認(rèn)消息
- 1:等待topic中某個(gè)partition leader保存成功的狀態(tài)反饋
- -1:等待topic中某個(gè)partition 所有副本都保存成功的狀態(tài)反饋
kafka生產(chǎn)的Log
摘錄了一下大神的博客酒觅,如下:
kafka的選舉機(jī)制
- 首先Kafka會(huì)將接收到的消息分區(qū)(partition)撮执,每個(gè)主題(topic)的消息有不同的分區(qū)。
這樣一方面消息的存儲(chǔ)就不會(huì)受到單一服務(wù)器存儲(chǔ)空間大小的限制舷丹,另一方面消息的處理也可以在多個(gè)服務(wù)器上并行抒钱。 - 其次為了保證高可用,每個(gè)分區(qū)都會(huì)有一定數(shù)量的副本(replica)颜凯。這樣如果有部分服務(wù)器不可用谋币,副本所在的服務(wù)器就會(huì)接替上來,保證應(yīng)用的持續(xù)性装获。
但是瑞信,為了保證較高的處理效率,消息的讀寫都是在固定的一個(gè)副本上完成穴豫。這個(gè)副本就是所謂的Leader凡简,而其他副本則是Follower。而Follower則會(huì)定期地到Leader上同步數(shù)據(jù)精肃。