kafaka

1.1? Kafka的特性:

- 高吞吐量、低延遲:kafka每秒可以處理幾十萬(wàn)條消息,它的延遲最低只有幾毫秒,每個(gè)topic可以分多個(gè)partition, consumer group 對(duì)partition進(jìn)行consume操作。

- 可擴(kuò)展性:kafka集群支持熱擴(kuò)展

- 持久性、可靠性:消息被持久化到本地磁盤,并且支持?jǐn)?shù)據(jù)備份防止數(shù)據(jù)丟失

- 容錯(cuò)性:允許集群中節(jié)點(diǎn)失敗(若副本數(shù)量為n,則允許n-1個(gè)節(jié)點(diǎn)失敗)

- 高并發(fā):支持?jǐn)?shù)千個(gè)客戶端同時(shí)讀寫

1.2? Kafka的使用場(chǎng)景:

- 日志收集:一個(gè)公司可以用Kafka可以收集各種服務(wù)的log,通過(guò)kafka以統(tǒng)一接口服務(wù)的方式開放給各種consumer,例如hadoop、Hbase、Solr等。

- 消息系統(tǒng):解耦和生產(chǎn)者和消費(fèi)者、緩存消息等。

- 用戶活動(dòng)跟蹤:Kafka經(jīng)常被用來(lái)記錄web用戶或者app用戶的各種活動(dòng),如瀏覽網(wǎng)頁(yè)、搜索、點(diǎn)擊等活動(dòng),這些活動(dòng)信息被各個(gè)服務(wù)器發(fā)布到kafka的topic中,然后訂閱者通過(guò)訂閱這些topic來(lái)做實(shí)時(shí)的監(jiān)控分析,或者裝載到hadoop、數(shù)據(jù)倉(cāng)庫(kù)中做離線分析和挖掘。

- 運(yùn)營(yíng)指標(biāo):Kafka也經(jīng)常用來(lái)記錄運(yùn)營(yíng)監(jiān)控?cái)?shù)據(jù)。包括收集各種分布式應(yīng)用的數(shù)據(jù),生產(chǎn)各種操作的集中反饋,比如報(bào)警和報(bào)告。

- 流式處理:比如spark streaming和storm

- 事件源

1.3? Kakfa的設(shè)計(jì)思想

- Kakfa Broker Leader的選舉:Kakfa Broker集群受Zookeeper管理。所有的Kafka Broker節(jié)點(diǎn)一起去Zookeeper上注冊(cè)一個(gè)臨時(shí)節(jié)點(diǎn),因?yàn)橹挥幸粋€(gè)Kafka Broker會(huì)注冊(cè)成功,其他的都會(huì)失敗,所以這個(gè)成功在Zookeeper上注冊(cè)臨時(shí)節(jié)點(diǎn)的這個(gè)Kafka Broker會(huì)成為Kafka Broker Controller,其他的Kafka broker叫Kafka Broker follower。(這個(gè)過(guò)程叫Controller在ZooKeeper注冊(cè)Watch)。這個(gè)Controller會(huì)監(jiān)聽其他的Kafka Broker的所有信息,如果這個(gè)kafka broker controller宕機(jī)了,在zookeeper上面的那個(gè)臨時(shí)節(jié)點(diǎn)就會(huì)消失,此時(shí)所有的kafka broker又會(huì)一起去Zookeeper上注冊(cè)一個(gè)臨時(shí)節(jié)點(diǎn),因?yàn)橹挥幸粋€(gè)Kafka Broker會(huì)注冊(cè)成功,其他的都會(huì)失敗,所以這個(gè)成功在Zookeeper上注冊(cè)臨時(shí)節(jié)點(diǎn)的這個(gè)Kafka Broker會(huì)成為Kafka Broker Controller,其他的Kafka broker叫Kafka Broker follower。例如:一旦有一個(gè)broker宕機(jī)了,這個(gè)kafka broker controller會(huì)讀取該宕機(jī)broker上所有的partition在zookeeper上的狀態(tài),并選取ISR列表中的一個(gè)replica作為partition leader(如果ISR列表中的replica全掛,選一個(gè)幸存的replica作為leader; 如果該partition的所有的replica都宕機(jī)了,則將新的leader設(shè)置為-1,等待恢復(fù),等待ISR中的任一個(gè)Replica“活”過(guò)來(lái),并且選它作為L(zhǎng)eader;或選擇第一個(gè)“活”過(guò)來(lái)的Replica(不一定是ISR中的)作為L(zhǎng)eader),這個(gè)broker宕機(jī)的事情,kafka controller也會(huì)通知zookeeper,zookeeper就會(huì)通知其他的kafka broker。

這里曾經(jīng)發(fā)生過(guò)一個(gè)bug,TalkingData使用Kafka0.8.1的時(shí)候,kafka controller在Zookeeper上注冊(cè)成功后,它和Zookeeper通信的timeout時(shí)間是6s,也就是如果kafka controller如果有6s中沒(méi)有和Zookeeper做心跳,那么Zookeeper就認(rèn)為這個(gè)kafka controller已經(jīng)死了,就會(huì)在Zookeeper上把這個(gè)臨時(shí)節(jié)點(diǎn)刪掉,那么其他Kafka就會(huì)認(rèn)為controller已經(jīng)沒(méi)了,就會(huì)再次搶著注冊(cè)臨時(shí)節(jié)點(diǎn),注冊(cè)成功的那個(gè)kafka broker成為controller,然后,之前的那個(gè)kafka controller就需要各種shut down去關(guān)閉各種節(jié)點(diǎn)和事件的監(jiān)聽。但是當(dāng)kafka的讀寫流量都非常巨大的時(shí)候,TalkingData的一個(gè)bug是,由于網(wǎng)絡(luò)等原因,kafka controller和Zookeeper有6s中沒(méi)有通信,于是重新選舉出了一個(gè)新的kafka controller,但是原來(lái)的controller在shut down的時(shí)候總是不成功,這個(gè)時(shí)候producer進(jìn)來(lái)的message由于Kafka集群中存在兩個(gè)kafka controller而無(wú)法落地。導(dǎo)致數(shù)據(jù)淤積。

這里曾經(jīng)還有一個(gè)bug,TalkingData使用Kafka0.8.1的時(shí)候,當(dāng)ack=0的時(shí)候,表示producer發(fā)送出去message,只要對(duì)應(yīng)的kafka broker topic partition leader接收到的這條message,producer就返回成功,不管partition leader 是否真的成功把message真正存到kafka。當(dāng)ack=1的時(shí)候,表示producer發(fā)送出去message,同步的把message存到對(duì)應(yīng)topic的partition的leader上,然后producer就返回成功,partition leader異步的把message同步到其他partition replica上。當(dāng)ack=all或-1,表示producer發(fā)送出去message,同步的把message存到對(duì)應(yīng)topic的partition的leader和對(duì)應(yīng)的replica上之后,才返回成功。但是如果某個(gè)kafka controller 切換的時(shí)候,會(huì)導(dǎo)致partition leader的切換(老的 kafka controller上面的partition leader會(huì)選舉到其他的kafka broker上),但是這樣就會(huì)導(dǎo)致丟數(shù)據(jù)。

-? Consumergroup:各個(gè)consumer(consumer 線程)可以組成一個(gè)組(Consumer group ),partition中的每個(gè)message只能被組(Consumer group )中的一個(gè)consumer(consumer 線程)消費(fèi),如果一個(gè)message可以被多個(gè)consumer(consumer 線程)消費(fèi)的話,那么這些consumer必須在不同的組。Kafka不支持一個(gè)partition中的message由兩個(gè)或兩個(gè)以上的同一個(gè)consumer group下的consumer thread來(lái)處理,除非再啟動(dòng)一個(gè)新的consumer group。所以如果想同時(shí)對(duì)一個(gè)topic做消費(fèi)的話,啟動(dòng)多個(gè)consumer group就可以了,但是要注意的是,這里的多個(gè)consumer的消費(fèi)都必須是順序讀取partition里面的message,新啟動(dòng)的consumer默認(rèn)從partition隊(duì)列最頭端最新的地方開始阻塞的讀message。它不能像AMQ那樣可以多個(gè)BET作為consumer去互斥的(for update悲觀鎖)并發(fā)處理message,這是因?yàn)槎鄠€(gè)BET去消費(fèi)一個(gè)Queue中的數(shù)據(jù)的時(shí)候,由于要保證不能多個(gè)線程拿同一條message,所以就需要行級(jí)別悲觀所(for update),這就導(dǎo)致了consume的性能下降,吞吐量不夠。而kafka為了保證吞吐量,只允許同一個(gè)consumer group下的一個(gè)consumer線程去訪問(wèn)一個(gè)partition。如果覺(jué)得效率不高的時(shí)候,可以加partition的數(shù)量來(lái)橫向擴(kuò)展,那么再加新的consumer thread去消費(fèi)。如果想多個(gè)不同的業(yè)務(wù)都需要這個(gè)topic的數(shù)據(jù),起多個(gè)consumer group就好了,大家都是順序的讀取message,offsite的值互不影響。這樣沒(méi)有鎖競(jìng)爭(zhēng),充分發(fā)揮了橫向的擴(kuò)展性,吞吐量極高。這也就形成了分布式消費(fèi)的概念。

? ? 當(dāng)啟動(dòng)一個(gè)consumer group去消費(fèi)一個(gè)topic的時(shí)候,無(wú)論topic里面有多個(gè)少個(gè)partition,無(wú)論我們consumer group里面配置了多少個(gè)consumer thread,這個(gè)consumer group下面的所有consumer thread一定會(huì)消費(fèi)全部的partition;即便這個(gè)consumer group下只有一個(gè)consumer thread,那么這個(gè)consumer thread也會(huì)去消費(fèi)所有的partition。因此,最優(yōu)的設(shè)計(jì)就是,consumer group下的consumer thread的數(shù)量等于partition數(shù)量,這樣效率是最高的。

? ? 同一partition的一條message只能被同一個(gè)Consumer Group內(nèi)的一個(gè)Consumer消費(fèi)。不能夠一個(gè)consumer group的多個(gè)consumer同時(shí)消費(fèi)一個(gè)partition。

? ? 一個(gè)consumer group下,無(wú)論有多少個(gè)consumer,這個(gè)consumer group一定回去把這個(gè)topic下所有的partition都消費(fèi)了。當(dāng)consumer group里面的consumer數(shù)量小于這個(gè)topic下的partition數(shù)量的時(shí)候,如下圖groupA,groupB,就會(huì)出現(xiàn)一個(gè)conusmer thread消費(fèi)多個(gè)partition的情況,總之是這個(gè)topic下的partition都會(huì)被消費(fèi)。如果consumer group里面的consumer數(shù)量等于這個(gè)topic下的partition數(shù)量的時(shí)候,如下圖groupC,此時(shí)效率是最高的,每個(gè)partition都有一個(gè)consumer thread去消費(fèi)。當(dāng)consumer group里面的consumer數(shù)量大于這個(gè)topic下的partition數(shù)量的時(shí)候,如下圖GroupD,就會(huì)有一個(gè)consumer thread空閑。因此,我們?cè)谠O(shè)定consumer group的時(shí)候,只需要指明里面有幾個(gè)consumer數(shù)量即可,無(wú)需指定對(duì)應(yīng)的消費(fèi)partition序號(hào),consumer會(huì)自動(dòng)進(jìn)行rebalance。

? ? 多個(gè)Consumer Group下的consumer可以消費(fèi)同一條message,但是這種消費(fèi)也是以o(1)的方式順序的讀取message去消費(fèi),,所以一定會(huì)重復(fù)消費(fèi)這批message的,不能向AMQ那樣多個(gè)BET作為consumer消費(fèi)(對(duì)message加鎖,消費(fèi)的時(shí)候不能重復(fù)消費(fèi)message)

- Consumer Rebalance的觸發(fā)條件:(1)Consumer增加或刪除會(huì)觸發(fā) Consumer Group的Rebalance(2)Broker的增加或者減少都會(huì)觸發(fā) Consumer Rebalance

- Consumer: Consumer處理partition里面的message的時(shí)候是o(1)順序讀取的。所以必須維護(hù)著上一次讀到哪里的offsite信息。high level API,offset存于Zookeeper中,low level API的offset由自己維護(hù)。一般來(lái)說(shuō)都是使用high level api的。Consumer的delivery gurarantee,默認(rèn)是讀完message先commmit再處理message,autocommit默認(rèn)是true,這時(shí)候先commit就會(huì)更新offsite+1,一旦處理失敗,offsite已經(jīng)+1,這個(gè)時(shí)候就會(huì)丟message;也可以配置成讀完消息處理再commit,這種情況下consumer端的響應(yīng)就會(huì)比較慢的,需要等處理完才行。

一般情況下,一定是一個(gè)consumer group處理一個(gè)topic的message。Best Practice是這個(gè)consumer group里面consumer的數(shù)量等于topic里面partition的數(shù)量,這樣效率是最高的,一個(gè)consumer thread處理一個(gè)partition。如果這個(gè)consumer group里面consumer的數(shù)量小于topic里面partition的數(shù)量,就會(huì)有consumer thread同時(shí)處理多個(gè)partition(這個(gè)是kafka自動(dòng)的機(jī)制,我們不用指定),但是總之這個(gè)topic里面的所有partition都會(huì)被處理到的。。如果這個(gè)consumer group里面consumer的數(shù)量大于topic里面partition的數(shù)量,多出的consumer thread就會(huì)閑著啥也不干,剩下的是一個(gè)consumer thread處理一個(gè)partition,這就造成了資源的浪費(fèi),因?yàn)橐粋€(gè)partition不可能被兩個(gè)consumer thread去處理。所以我們線上的分布式多個(gè)service服務(wù),每個(gè)service里面的kafka consumer數(shù)量都小于對(duì)應(yīng)的topic的partition數(shù)量,但是所有服務(wù)的consumer數(shù)量只和等于partition的數(shù)量,這是因?yàn)榉植际絪ervice服務(wù)的所有consumer都來(lái)自一個(gè)consumer group,如果來(lái)自不同的consumer group就會(huì)處理重復(fù)的message了(同一個(gè)consumer group下的consumer不能處理同一個(gè)partition,不同的consumer group可以處理同一個(gè)topic,那么都是順序處理message,一定會(huì)處理重復(fù)的。一般這種情況都是兩個(gè)不同的業(yè)務(wù)邏輯,才會(huì)啟動(dòng)兩個(gè)consumer group來(lái)處理一個(gè)topic)。

如果producer的流量增大,當(dāng)前的topic的parition數(shù)量=consumer數(shù)量,這時(shí)候的應(yīng)對(duì)方式就是很想擴(kuò)展:增加topic下的partition,同時(shí)增加這個(gè)consumer group下的consumer。

? ? ? ? ? ? ? ?

- Delivery Mode : Kafka producer 發(fā)送message不用維護(hù)message的offsite信息,因?yàn)檫@個(gè)時(shí)候,offsite就相當(dāng)于一個(gè)自增id,producer就盡管發(fā)送message就好了。而且Kafka與AMQ不同,AMQ大都用在處理業(yè)務(wù)邏輯上,而Kafka大都是日志,所以Kafka的producer一般都是大批量的batch發(fā)送message,向這個(gè)topic一次性發(fā)送一大批message,load balance到一個(gè)partition上,一起插進(jìn)去,offsite作為自增id自己增加就好。但是Consumer端是需要維護(hù)這個(gè)partition當(dāng)前消費(fèi)到哪個(gè)message的offsite信息的,這個(gè)offsite信息,high level api是維護(hù)在Zookeeper上,low level api是自己的程序維護(hù)。(Kafka管理界面上只能顯示high level api的consumer部分,因?yàn)閘ow level api的partition offsite信息是程序自己維護(hù),kafka是不知道的,無(wú)法在管理界面上展示 )當(dāng)使用high level api的時(shí)候,先拿message處理,再定時(shí)自動(dòng)commit offsite+1(也可以改成手動(dòng)), 并且kakfa處理message是沒(méi)有鎖操作的。因此如果處理message失敗,此時(shí)還沒(méi)有commit offsite+1,當(dāng)consumer thread重啟后會(huì)重復(fù)消費(fèi)這個(gè)message。但是作為高吞吐量高并發(fā)的實(shí)時(shí)處理系統(tǒng),at least once的情況下,至少一次會(huì)被處理到,是可以容忍的。如果無(wú)法容忍,就得使用low level api來(lái)自己程序維護(hù)這個(gè)offsite信息,那么想什么時(shí)候commit offsite+1就自己搞定了。

- Topic & Partition:Topic相當(dāng)于傳統(tǒng)消息系統(tǒng)MQ中的一個(gè)隊(duì)列queue,producer端發(fā)送的message必須指定是發(fā)送到哪個(gè)topic,但是不需要指定topic下的哪個(gè)partition,因?yàn)閗afka會(huì)把收到的message進(jìn)行l(wèi)oad balance,均勻的分布在這個(gè)topic下的不同的partition上( hash(message) % [broker數(shù)量]? )。物理上存儲(chǔ)上,這個(gè)topic會(huì)分成一個(gè)或多個(gè)partition,每個(gè)partiton相當(dāng)于是一個(gè)子queue。在物理結(jié)構(gòu)上,每個(gè)partition對(duì)應(yīng)一個(gè)物理的目錄(文件夾),文件夾命名是[topicname]_[partition]_[序號(hào)],一個(gè)topic可以有無(wú)數(shù)多的partition,根據(jù)業(yè)務(wù)需求和數(shù)據(jù)量來(lái)設(shè)置。在kafka配置文件中可隨時(shí)更高num.partitions參數(shù)來(lái)配置更改topic的partition數(shù)量,在創(chuàng)建Topic時(shí)通過(guò)參數(shù)指定parittion數(shù)量。Topic創(chuàng)建之后通過(guò)Kafka提供的工具也可以修改partiton數(shù)量。

? 一般來(lái)說(shuō),(1)一個(gè)Topic的Partition數(shù)量大于等于Broker的數(shù)量,可以提高吞吐率。(2)同一個(gè)Partition的Replica盡量分散到不同的機(jī)器,高可用。

? 當(dāng)add a new partition的時(shí)候,partition里面的message不會(huì)重新進(jìn)行分配,原來(lái)的partition里面的message數(shù)據(jù)不會(huì)變,新加的這個(gè)partition剛開始是空的,隨后進(jìn)入這個(gè)topic的message就會(huì)重新參與所有partition的load balance

- Partition Replica:每個(gè)partition可以在其他的kafka broker節(jié)點(diǎn)上存副本,以便某個(gè)kafka broker節(jié)點(diǎn)宕機(jī)不會(huì)影響這個(gè)kafka集群。存replica副本的方式是按照kafka broker的順序存。例如有5個(gè)kafka broker節(jié)點(diǎn),某個(gè)topic有3個(gè)partition,每個(gè)partition存2個(gè)副本,那么partition1存broker1,broker2,partition2存broker2,broker3。。。以此類推(replica副本數(shù)目不能大于kafka broker節(jié)點(diǎn)的數(shù)目,否則報(bào)錯(cuò)。這里的replica數(shù)其實(shí)就是partition的副本總數(shù),其中包括一個(gè)leader,其他的就是copy副本)。這樣如果某個(gè)broker宕機(jī),其實(shí)整個(gè)kafka內(nèi)數(shù)據(jù)依然是完整的。但是,replica副本數(shù)越高,系統(tǒng)雖然越穩(wěn)定,但是回來(lái)帶資源和性能上的下降;replica副本少的話,也會(huì)造成系統(tǒng)丟數(shù)據(jù)的風(fēng)險(xiǎn)。

? (1)怎樣傳送消息:producer先把message發(fā)送到partition leader,再由leader發(fā)送給其他partition follower。(如果讓producer發(fā)送給每個(gè)replica那就太慢了)

? (2)在向Producer發(fā)送ACK前需要保證有多少個(gè)Replica已經(jīng)收到該消息:根據(jù)ack配的個(gè)數(shù)而定

? (3)怎樣處理某個(gè)Replica不工作的情況:如果這個(gè)部工作的partition replica不在ack列表中,就是producer在發(fā)送消息到partition leader上,partition leader向partition follower發(fā)送message沒(méi)有響應(yīng)而已,這個(gè)不會(huì)影響整個(gè)系統(tǒng),也不會(huì)有什么問(wèn)題。如果這個(gè)不工作的partition replica在ack列表中的話,producer發(fā)送的message的時(shí)候會(huì)等待這個(gè)不工作的partition replca寫message成功,但是會(huì)等到time out,然后返回失敗因?yàn)槟硞€(gè)ack列表中的partition replica沒(méi)有響應(yīng),此時(shí)kafka會(huì)自動(dòng)的把這個(gè)部工作的partition replica從ack列表中移除,以后的producer發(fā)送message的時(shí)候就不會(huì)有這個(gè)ack列表下的這個(gè)部工作的partition replica了。

? (4)怎樣處理Failed Replica恢復(fù)回來(lái)的情況:如果這個(gè)partition replica之前不在ack列表中,那么啟動(dòng)后重新受Zookeeper管理即可,之后producer發(fā)送message的時(shí)候,partition leader會(huì)繼續(xù)發(fā)送message到這個(gè)partition follower上。如果這個(gè)partition replica之前在ack列表中,此時(shí)重啟后,需要把這個(gè)partition replica再手動(dòng)加到ack列表中。(ack列表是手動(dòng)添加的,出現(xiàn)某個(gè)部工作的partition replica的時(shí)候自動(dòng)從ack列表中移除的)

- Partition leader與follower:partition也有l(wèi)eader和follower之分。leader是主partition,producer寫kafka的時(shí)候先寫partition leader,再由partition leader push給其他的partition follower。partition leader與follower的信息受Zookeeper控制,一旦partition leader所在的broker節(jié)點(diǎn)宕機(jī),zookeeper會(huì)沖其他的broker的partition follower上選擇follower變?yōu)閜arition leader。

- Topic分配partition和partition replica的算法:(1)將Broker(size=n)和待分配的Partition排序。(2)將第i個(gè)Partition分配到第(i%n)個(gè)Broker上。(3)將第i個(gè)Partition的第j個(gè)Replica分配到第((i + j) % n)個(gè)Broker上

- 消息投遞可靠性

一個(gè)消息如何算投遞成功,Kafka提供了三種模式:

- 第一種是啥都不管,發(fā)送出去就當(dāng)作成功,這種情況當(dāng)然不能保證消息成功投遞到broker;

- 第二種是Master-Slave模型,只有當(dāng)Master和所有Slave都接收到消息時(shí),才算投遞成功,這種模型提供了最高的投遞可靠性,但是損傷了性能;

- 第三種模型,即只要Master確認(rèn)收到消息就算投遞成功;實(shí)際使用時(shí),根據(jù)應(yīng)用特性選擇,絕大多數(shù)情況下都會(huì)中和可靠性和性能選擇第三種模型

? 消息在broker上的可靠性,因?yàn)橄?huì)持久化到磁盤上,所以如果正常stop一個(gè)broker,其上的數(shù)據(jù)不會(huì)丟失;但是如果不正常stop,可能會(huì)使存在頁(yè)面緩存來(lái)不及寫入磁盤的消息丟失,這可以通過(guò)配置flush頁(yè)面緩存的周期、閾值緩解,但是同樣會(huì)頻繁的寫磁盤會(huì)影響性能,又是一個(gè)選擇題,根據(jù)實(shí)際情況配置。

? 消息消費(fèi)的可靠性,Kafka提供的是“At least once”模型,因?yàn)橄⒌淖x取進(jìn)度由offset提供,offset可以由消費(fèi)者自己維護(hù)也可以維護(hù)在zookeeper里,但是當(dāng)消息消費(fèi)后consumer掛掉,offset沒(méi)有即時(shí)寫回,就有可能發(fā)生重復(fù)讀的情況,這種情況同樣可以通過(guò)調(diào)整commit offset周期、閾值緩解,甚至消費(fèi)者自己把消費(fèi)和commit offset做成一個(gè)事務(wù)解決,但是如果你的應(yīng)用不在乎重復(fù)消費(fèi),那就干脆不要解決,以換取最大的性能。

- Partition ack:當(dāng)ack=1,表示producer寫partition leader成功后,broker就返回成功,無(wú)論其他的partition follower是否寫成功。當(dāng)ack=2,表示producer寫partition leader和其他一個(gè)follower成功的時(shí)候,broker就返回成功,無(wú)論其他的partition follower是否寫成功。當(dāng)ack=-1[parition的數(shù)量]的時(shí)候,表示只有producer全部寫成功的時(shí)候,才算成功,kafka broker才返回成功信息。這里需要注意的是,如果ack=1的時(shí)候,一旦有個(gè)broker宕機(jī)導(dǎo)致partition的follower和leader切換,會(huì)導(dǎo)致丟數(shù)據(jù)。

?

- message狀態(tài):在Kafka中,消息的狀態(tài)被保存在consumer中,broker不會(huì)關(guān)心哪個(gè)消息被消費(fèi)了被誰(shuí)消費(fèi)了,只記錄一個(gè)offset值(指向partition中下一個(gè)要被消費(fèi)的消息位置),這就意味著如果consumer處理不好的話,broker上的一個(gè)消息可能會(huì)被消費(fèi)多次。

- message持久化:Kafka中會(huì)把消息持久化到本地文件系統(tǒng)中,并且保持o(1)極高的效率。我們眾所周知IO讀取是非常耗資源的性能也是最慢的,這就是為了數(shù)據(jù)庫(kù)的瓶頸經(jīng)常在IO上,需要換SSD硬盤的原因。但是Kafka作為吞吐量極高的MQ,卻可以非常高效的message持久化到文件。這是因?yàn)镵afka是順序?qū)懭雘(1)的時(shí)間復(fù)雜度,速度非常快。也是高吞吐量的原因。由于message的寫入持久化是順序?qū)懭氲模虼薽essage在被消費(fèi)的時(shí)候也是按順序被消費(fèi)的,保證partition的message是順序消費(fèi)的。一般的機(jī)器,單機(jī)每秒100k條數(shù)據(jù)。

- message有效期:Kafka會(huì)長(zhǎng)久保留其中的消息,以便consumer可以多次消費(fèi),當(dāng)然其中很多細(xì)節(jié)是可配置的。

- Produer : Producer向Topic發(fā)送message,不需要指定partition,直接發(fā)送就好了。kafka通過(guò)partition ack來(lái)控制是否發(fā)送成功并把信息返回給producer,producer可以有任意多的thread,這些kafka服務(wù)器端是不care的。Producer端的delivery guarantee默認(rèn)是At least once的。也可以設(shè)置Producer異步發(fā)送實(shí)現(xiàn)At most once。Producer可以用主鍵冪等性實(shí)現(xiàn)Exactly once

- Kafka高吞吐量: Kafka的高吞吐量體現(xiàn)在讀寫上,分布式并發(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)行順序讀。

- Kafka delivery guarantee(message傳送保證):(1)At most once消息可能會(huì)丟,絕對(duì)不會(huì)重復(fù)傳輸;(2)At least once 消息絕對(duì)不會(huì)丟,但是可能會(huì)重復(fù)傳輸;(3)Exactly once每條信息肯定會(huì)被傳輸一次且僅傳輸一次,這是用戶想要的。

- 批量發(fā)送:Kafka支持以消息集合為單位進(jìn)行批量發(fā)送,以提高push效率。

- push-and-pull : Kafka中的Producer和consumer采用的是push-and-pull模式,即Producer只管向broker push消息,consumer只管從broker pull消息,兩者對(duì)消息的生產(chǎn)和消費(fèi)是異步的。

- Kafka集群中broker之間的關(guān)系:不是主從關(guān)系,各個(gè)broker在集群中地位一樣,我們可以隨意的增加或刪除任何一個(gè)broker節(jié)點(diǎn)。

- 負(fù)載均衡方面: Kafka提供了一個(gè) metadata API來(lái)管理broker之間的負(fù)載(對(duì)Kafka0.8.x而言,對(duì)于0.7.x主要靠zookeeper來(lái)實(shí)現(xiàn)負(fù)載均衡)。

- 同步異步:Producer采用異步push方式,極大提高Kafka系統(tǒng)的吞吐率(可以通過(guò)參數(shù)控制是采用同步還是異步方式)。

- 分區(qū)機(jī)制partition:Kafka的broker端支持消息分區(qū)partition,Producer可以決定把消息發(fā)到哪個(gè)partition,在一個(gè)partition 中message的順序就是Producer發(fā)送消息的順序,一個(gè)topic中可以有多個(gè)partition,具體partition的數(shù)量是可配置的。partition的概念使得kafka作為MQ可以橫向擴(kuò)展,吞吐量巨大。partition可以設(shè)置replica副本,replica副本存在不同的kafka broker節(jié)點(diǎn)上,第一個(gè)partition是leader,其他的是follower,message先寫到partition leader上,再由partition leader push到parition follower上。所以說(shuō)kafka可以水平擴(kuò)展,也就是擴(kuò)展partition。

- 離線數(shù)據(jù)裝載:Kafka由于對(duì)可拓展的數(shù)據(jù)持久化的支持,它也非常適合向Hadoop或者數(shù)據(jù)倉(cāng)庫(kù)中進(jìn)行數(shù)據(jù)裝載。

- 實(shí)時(shí)數(shù)據(jù)與離線數(shù)據(jù):kafka既支持離線數(shù)據(jù)也支持實(shí)時(shí)數(shù)據(jù),因?yàn)閗afka的message持久化到文件,并可以設(shè)置有效期,因此可以把kafka作為一個(gè)高效的存儲(chǔ)來(lái)使用,可以作為離線數(shù)據(jù)供后面的分析。當(dāng)然作為分布式實(shí)時(shí)消息系統(tǒng),大多數(shù)情況下還是用于實(shí)時(shí)的數(shù)據(jù)處理的,但是當(dāng)cosumer消費(fèi)能力下降的時(shí)候可以通過(guò)message的持久化在淤積數(shù)據(jù)在kafka。

- 插件支持:現(xiàn)在不少活躍的社區(qū)已經(jīng)開發(fā)出不少插件來(lái)拓展Kafka的功能,如用來(lái)配合Storm、Hadoop、flume相關(guān)的插件。

- 解耦:? 相當(dāng)于一個(gè)MQ,使得Producer和Consumer之間異步的操作,系統(tǒng)之間解耦

- 冗余:? replica有多個(gè)副本,保證一個(gè)broker node宕機(jī)后不會(huì)影響整個(gè)服務(wù)

- 擴(kuò)展性:? broker節(jié)點(diǎn)可以水平擴(kuò)展,partition也可以水平增加,partition replica也可以水平增加

- 峰值:? 在訪問(wèn)量劇增的情況下,kafka水平擴(kuò)展, 應(yīng)用仍然需要繼續(xù)發(fā)揮作用

- 可恢復(fù)性:? 系統(tǒng)的一部分組件失效時(shí),由于有partition的replica副本,不會(huì)影響到整個(gè)系統(tǒng)。

- 順序保證性:由于kafka的producer的寫message與consumer去讀message都是順序的讀寫,保證了高效的性能。

- 緩沖:由于producer那面可能業(yè)務(wù)很簡(jiǎn)單,而后端consumer業(yè)務(wù)會(huì)很復(fù)雜并有數(shù)據(jù)庫(kù)的操作,因此肯定是producer會(huì)比consumer處理速度快,如果沒(méi)有kafka,producer直接調(diào)用consumer,那么就會(huì)造成整個(gè)系統(tǒng)的處理速度慢,加一層kafka作為MQ,可以起到緩沖的作用。

- 異步通信:作為MQ,Producer與Consumer異步通信。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,333評(píng)論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,491評(píng)論 3 416
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,263評(píng)論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,946評(píng)論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 71,708評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,186評(píng)論 1 324
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,255評(píng)論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,409評(píng)論 0 288
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,939評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 40,774評(píng)論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 42,976評(píng)論 1 369
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,518評(píng)論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,209評(píng)論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,641評(píng)論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,872評(píng)論 1 286
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 51,650評(píng)論 3 391
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 47,958評(píng)論 2 373

推薦閱讀更多精彩內(nèi)容

  • 1. 概述 Kakfa起初是由LinkedIn公司開發(fā)的一個(gè)分布式的消息系統(tǒng),后成為Apache的一部分,它使用S...
    尼小摩閱讀 1,448評(píng)論 0 17
  • Kafka系列一- Kafka背景及架構(gòu)介紹 Kafka簡(jiǎn)介 Kafka是一種分布式的,基于發(fā)布/訂閱的消息系統(tǒng)。...
    raincoffee閱讀 2,220評(píng)論 0 22
  • 一、為什么需要消息系統(tǒng) 1.解耦:允許你獨(dú)立的擴(kuò)展或修改兩邊的處理過(guò)程,只要確保它們遵守同樣的接口約束。 2.冗余...
    為你變乖_09e6閱讀 873評(píng)論 0 8
  • 我知道,我已經(jīng)過(guò)了那個(gè)可以撒嬌賣萌的年紀(jì),現(xiàn)在的我,眼角有了細(xì)紋,眼睛不再清澈,臉上有了雀斑,皮膚有些松弛。我希望...
    蘭月涵閱讀 270評(píng)論 0 0
  • 福彩351期毒膽9次7 復(fù)式24789 形態(tài)。。。。組六。。。防組三 和差589 段組5---124789--03...
    冰風(fēng)_fb43閱讀 88評(píng)論 0 1