kafka是一種高吞吐量的分布式發(fā)布訂閱消息系統(tǒng),有如下特性:

1. 通過(guò)O(1)的磁盤數(shù)據(jù)結(jié)構(gòu)提供消息的持久化,這種結(jié)構(gòu)對(duì)于即使數(shù)以TB的消息存儲(chǔ)也能夠保持長(zhǎng)時(shí)間的穩(wěn)定性能。

2 .高吞吐量:即使是非常普通的硬件kafka也可以支持每秒數(shù)十萬(wàn)的消息。

3 .支持通過(guò)kafka服務(wù)器和消費(fèi)機(jī)集群來(lái)分區(qū)消息。

4 .支持Hadoop并行數(shù)據(jù)加載。

 本篇屬于大數(shù)據(jù)技術(shù)-> kafka 系列的開(kāi)篇,本文從以下幾個(gè)基礎(chǔ)層面概述Kafka的知識(shí)點(diǎn),后續(xù)在針對(duì)于單個(gè)的技術(shù)點(diǎn)擴(kuò)展每篇博文。

  • Kafka背景介紹

  • Kafka基本架構(gòu)組件

  • Kafka設(shè)計(jì)原理

  • Kafka用途


一:Kafka背景介紹

Kafka是一種高吞吐量的,分布式,快速、可擴(kuò)展的,分區(qū)和可復(fù)制,基于發(fā)布/訂閱模式的消息系統(tǒng),由Linkedin開(kāi)發(fā),之后成為Apache項(xiàng)目的一部分。使用Scala語(yǔ)言編寫(xiě),目前已被廣泛應(yīng)用于各行業(yè)各類型的數(shù)據(jù)管道和消息系統(tǒng)中。

kafka的設(shè)計(jì)目的是提供一個(gè)發(fā)布訂閱解決方案,它可以處理消費(fèi)者規(guī)模的網(wǎng)站中的所有動(dòng)作流數(shù)據(jù)。 這種動(dòng)作(網(wǎng)頁(yè)瀏覽,搜索和其他用戶的行動(dòng))是在現(xiàn)代網(wǎng)絡(luò)上的許多社會(huì)功能的一個(gè)關(guān)鍵因素。 這些數(shù)據(jù)通常是由于吞吐量的要求而通過(guò)處理日志和日志聚合來(lái)解決。

Kafka分布式發(fā)布訂閱設(shè)計(jì)圖

二 :Kafka基本架構(gòu)組件

1. Broker :[中間者,代理者]

   Kafka集群包含多臺(tái)服務(wù)器,一臺(tái)Kafka服務(wù)器就是一個(gè)Broker,一個(gè)集群由多個(gè)broker組成,一個(gè)broker可以有多個(gè)topic。broker承擔(dān)著中間緩存和分發(fā)的作用,broker將producer發(fā)送的數(shù)據(jù)分發(fā)到注冊(cè)consumer中

2. Topic :

  topic[主題,類別,話題],我們可以理解為是一種隊(duì)列,每條發(fā)送消息都從屬于一種類別,這種類別在kafka中被設(shè)計(jì)為一個(gè)topic,比如:用戶信息類的消息的topic,我們定義為user-topic,那么凡是用戶信息類的消息都將發(fā)送到這個(gè)topic中,從而我們所要處理用戶信息類的消費(fèi)者就可以從這topic中拉取。

3. Producer :

  producer是生產(chǎn)者,意在向Topic中發(fā)送消息的一方

4. Consumer  :

  consumer是消費(fèi)者,意在向Topic中拉?。M(fèi)消息的一方

Kafka拓?fù)浣Y(jié)構(gòu)

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

如上圖所示,一個(gè)典型的Kafka集群中包含若干Producer,若干broker(Kafka支持水平擴(kuò)展,一般broker數(shù)量越多,集群吞吐率越高),若干Consumer Group,以及一個(gè)Zookeeper集群。Kafka通過(guò)Zookeeper管理集群配置,選舉leader,以及在Consumer Group發(fā)生變化時(shí)進(jìn)行rebalance。Producer使用push模式將消息發(fā)布到broker,Consumer使用pull模式從broker訂閱并消費(fèi)消息。

5. Replications:

  分區(qū)的備份,以便容錯(cuò),分布在其他broker上,每個(gè)broker上只能有0個(gè)或者1個(gè)replications

6. Consumer Group :

  消費(fèi)者群組,是有若干個(gè)消費(fèi)者組成的集體,每個(gè)consumer屬于一個(gè)特定的consumer group,kafka采用將Consumer分組的方式實(shí)現(xiàn)一個(gè)主題(topic)的消息和廣播(發(fā)給所有的consumer)和單播(發(fā)給單個(gè)的consumer) 

7. Partition :

  Kafka內(nèi)在就是分布式的,一個(gè)broker中可以有多個(gè)topic,一個(gè)topic可以設(shè)置多個(gè)partition(分區(qū)),每個(gè)Partition在物理上都對(duì)應(yīng)一個(gè)文件夾,該文件夾存儲(chǔ)這個(gè)Partition的所有消息和索引文件。Partition中的消息都會(huì)被分配為一個(gè)有序的ID(offset),一個(gè)partition對(duì)應(yīng)多個(gè)Segment,每個(gè)Segment對(duì)應(yīng)一個(gè)文件,Segment由一個(gè)個(gè)的不可變記錄組成,該記錄只會(huì)append到Segment中,不會(huì)單獨(dú)的修改或者刪除,可以設(shè)置Segment根據(jù)時(shí)間或者大小來(lái)定時(shí)刪除文件。默認(rèn)是根據(jù)大小128MB,當(dāng)segment大小達(dá)到128MB時(shí),則會(huì)刪除一些Segment文件(這里有一點(diǎn),刪除的時(shí)候,會(huì)選擇一個(gè)或者多個(gè)Segment來(lái)刪除,也就是說(shuō)刪除三個(gè)Segment大小可能大于128MB,但是不會(huì)是小于128MB)

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

8.offset :偏移

  在每個(gè)partition分區(qū)下的消息都是順序保存的,kakfa使用一個(gè)唯一的標(biāo)識(shí)來(lái)記錄它們?cè)谠摲謪^(qū)下的位置,這個(gè)位置標(biāo)識(shí)被稱為offset(位移),位移是順序遞增的,一旦確定下來(lái)之后就不能修改。Kafka會(huì)維護(hù)分區(qū)下的消息順序,但是不會(huì)維護(hù)跨partition(分區(qū))間的順序(假如,我們往topic1分別發(fā)送三條消息1,2,3 那么,1和3發(fā)送到了partition1中,2發(fā)送到了partition2中,那么kafka consumer在消費(fèi)時(shí),會(huì)按照1 然后 3的順序消息,但是不保證 2 會(huì)在消費(fèi)1之后在消費(fèi) )

那么我們知道了topic,partition和offset信息,我們就能唯一定位一條消息。所以說(shuō)每條Kafka的消息本質(zhì)上都是一個(gè)三元組(tuple):<topic, partition, offset>。我們可以稱該三元組為消息的元數(shù)據(jù)(message metadata)。它們之間的關(guān)系如下圖所示:

  大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

三 :Kafka設(shè)計(jì)原理

We designed Kafka to be able to act as a unified platform for handling all the real-time data feeds a large company might have. To do this we had to think through a fairly broad set of use cases.

Kafka是一個(gè)消息引擎(messaging system),Kafka本身提供了用于消息傳遞的一套完整功能及接口,而不僅僅是提供消息的表示。大型系統(tǒng)之間數(shù)據(jù)交互基本上都需要這樣的消息引擎。作為一個(gè)基礎(chǔ)設(shè)施,Kafka即扮演了這樣的角色。

1  . 持久化(Persistence) 

Kafka是高度依賴文件系統(tǒng)和緩存的,Kafka對(duì)磁盤時(shí)append操作,磁盤檢索的開(kāi)支是較少的,同時(shí)為了減少磁盤寫(xiě)入的次數(shù),broker會(huì)將消息暫時(shí)buffer起來(lái),當(dāng)消息的數(shù)量(offset)達(dá)到一定閥值時(shí)(可配置 offset可以設(shè)置為自動(dòng)提交或者手動(dòng)提交),再flush到磁盤中,這樣減少了磁盤的開(kāi)銷。

2 . 生產(chǎn)者(producer)

producer用于往broker中發(fā)送/生產(chǎn)消息,每一個(gè)broker中可以有多個(gè)topic,每個(gè)topic下面又會(huì)有多個(gè)partition,在負(fù)載均衡的情況,如果均衡的將消息發(fā)送到指定的partition中.(對(duì)于具體的producer在以后會(huì)有詳細(xì)的介紹)

   異步處理:將多條消息存儲(chǔ)在buffer中,之后,批量的提交到broker中,從而提高了網(wǎng)絡(luò)IO,但是也有一點(diǎn),采用異步發(fā)送機(jī)制如果producer異?;蛘邔?shí)效,那么消息將會(huì)丟失。

3 .消費(fèi)者(Consumer)

  Consumer通過(guò)鏈接broker,采用pull方式來(lái)拉取broker中的數(shù)據(jù),consumer根據(jù)自己的消費(fèi)能力,去消費(fèi)信息。那么這里為什么采用pull而不是push呢?因?yàn)閜ull模式中1:broker是不需要感知有多少個(gè)consumer。2:如果采用push模式一旦消息量級(jí)超過(guò)consumer的承受范圍,會(huì)壓垮consumer。

前面我們說(shuō)過(guò),topic屬于一個(gè)類別,topic由多個(gè)有序的partition序列組成,每個(gè)partition在同一時(shí)刻只會(huì)被一個(gè)consumer進(jìn)行消費(fèi),同時(shí)會(huì)更新offset的index,記錄消費(fèi)到的位置,在consumer每消費(fèi)完一條信息之后,kafka會(huì)自動(dòng)的提交offset,當(dāng)然我們也可以設(shè)置為手動(dòng)提交,當(dāng)我們?cè)谙M(fèi)100000條消息之后,offset存儲(chǔ)在一個(gè)list中,達(dá)到一定的消息量之后,提交這個(gè)offset list。

4 .常量時(shí)間存儲(chǔ)能力

  一個(gè)實(shí)現(xiàn)了數(shù)據(jù)持久化的隊(duì)列,提供簡(jiǎn)單的數(shù)據(jù)讀和數(shù)據(jù)追加寫(xiě)到文件末尾,例如在一個(gè)日志管理系統(tǒng)中。這種數(shù)據(jù)結(jié)構(gòu)的最大優(yōu)勢(shì)是所有操作的算法復(fù)雜度都是O(1),磁盤讀、寫(xiě)也不會(huì)互相阻塞。這使得Kafka具有了一個(gè)顯著的性能優(yōu)勢(shì),因?yàn)樵谶@里性能與數(shù)據(jù)量實(shí)現(xiàn)了完全得解耦。一臺(tái)服務(wù)器現(xiàn)在可以輕松利用到一組廉價(jià)的低轉(zhuǎn)速、大容量(1+TB)磁盤能夠提供的各種優(yōu)勢(shì),雖然這些磁盤只有可憐的尋道速度但仍然能夠基于大塊數(shù)據(jù)的讀、寫(xiě)提供可以接受的性能。這些磁盤普遍只有SAS磁盤價(jià)格的1/3和3倍以上的容量。

       擁有訪問(wèn)幾乎無(wú)限的磁盤空間的能力,卻不會(huì)有任何性能懲罰,這意味著我們可以基于Kafka實(shí)現(xiàn)一些在傳統(tǒng)消息中間件中很少看到的特性。例如,在傳統(tǒng)消息中間件系統(tǒng)中往往會(huì)在消息一旦被獲取后立即嘗試刪除該消息數(shù)據(jù),而Kafka能夠?yàn)橄?shù)據(jù)保留一個(gè)相對(duì)來(lái)說(shuō)很長(zhǎng)的時(shí)間(如一周)。僅這一個(gè)特性,就為消息消費(fèi)端提供了大量的靈活性。 

5 .消費(fèi)分發(fā)機(jī)制

  1. At most once 消息可能會(huì)丟,但絕不會(huì)重復(fù)傳輸

  2. At least one 消息絕不會(huì)丟,但可能會(huì)重復(fù)傳輸

  3. Exactly once 每條消息肯定會(huì)被傳輸一次且僅傳輸一次,很多時(shí)候這是用戶所想要的

當(dāng)Producer向broker發(fā)送消息時(shí),一旦這條消息被commit,因數(shù)replication的存在,它就不會(huì)丟。但是如果Producer發(fā)送數(shù)據(jù)給broker后,遇到網(wǎng)絡(luò)問(wèn)題而造成通信中斷,那Producer就無(wú)法判斷該條消息是否已經(jīng)commit。雖然Kafka無(wú)法確定網(wǎng)絡(luò)故障期間發(fā)生了什么,但是Producer可以生成一種類似于主鍵的東西,發(fā)生故障時(shí)冪等性的重試多次,這樣就做到了Exactly once。

Consumer在從broker讀取消息后,可以選擇commit,該操作會(huì)在Zookeeper中保存該Consumer在該P(yáng)artition中讀取的消息的offset。該Consumer下一次再讀該P(yáng)artition時(shí)會(huì)從下一條開(kāi)始讀取。如未commit,下一次讀取的開(kāi)始位置會(huì)跟上一次commit之后的開(kāi)始位置相同。當(dāng)然可以將Consumer設(shè)置為autocommit,即Consumer一旦讀到數(shù)據(jù)立即自動(dòng)commit。如果只討論這一讀取消息的過(guò)程,那Kafka是確保了Exactly once。但實(shí)際使用中應(yīng)用程序并非在Consumer讀取完數(shù)據(jù)就結(jié)束了,而是要進(jìn)行進(jìn)一步處理,而數(shù)據(jù)處理與commit的順序在很大程度上決定了消息從broker和consumer的delivery guarantee semantic。

  • 讀完消息先commit再處理消息。這種模式下,如果Consumer在commit后還沒(méi)來(lái)得及處理消息就crash了,下次重新開(kāi)始工作后就無(wú)法讀到剛剛已提交而未處理的消息,這就對(duì)應(yīng)于At most once

  • 讀完消息先處理再commit。這種模式下,如果在處理完消息之后commit之前Consumer crash了,下次重新開(kāi)始工作時(shí)還會(huì)處理剛剛未commit的消息,實(shí)際上該消息已經(jīng)被處理過(guò)了。這就對(duì)應(yīng)于At least once。在很多使用場(chǎng)景下,消息都有一個(gè)主鍵,所以消息的處理往往具有冪等性,即多次處理這一條消息跟只處理一次是等效的,那就可以認(rèn)為是Exactly once。(筆者認(rèn)為這種說(shuō)法比較牽強(qiáng),畢竟它不是Kafka本身提供的機(jī)制,主鍵本身也并不能完全保證操作的冪等性。而且實(shí)際上我們說(shuō)delivery guarantee 語(yǔ)義是討論被處理多少次,而非處理結(jié)果怎樣,因?yàn)樘幚矸绞蕉喾N多樣,我們不應(yīng)該把處理過(guò)程的特性——如是否冪等性,當(dāng)成Kafka本身的Feature)

  • 如果一定要做到Exactly once,就需要協(xié)調(diào)offset和實(shí)際操作的輸出。精典的做法是引入兩階段提交。如果能讓offset和操作輸入存在同一個(gè)地方,會(huì)更簡(jiǎn)潔和通用。這種方式可能更好,因?yàn)樵S多輸出系統(tǒng)可能不支持兩階段提交。比如,Consumer拿到數(shù)據(jù)后可能把數(shù)據(jù)放到HDFS,如果把最新的offset和數(shù)據(jù)本身一起寫(xiě)到HDFS,那就可以保證數(shù)據(jù)的輸出和offset的更新要么都完成,要么都不完成,間接實(shí)現(xiàn)Exactly once。(目前就high level API而言,offset是存于Zookeeper中的,無(wú)法存于HDFS,而low level API的offset是由自己去維護(hù)的,可以將之存于HDFS中)

 6 .復(fù)制 Replication

  kafka將每個(gè)partition數(shù)據(jù)復(fù)制到多個(gè)server上,任何一個(gè)partition有一個(gè)leader和多個(gè)follower(可以沒(méi)有)。備份的個(gè)數(shù)可以通過(guò)broker配置文件來(lái)設(shè)定,Kafka自動(dòng)維護(hù)leader和follower的失效轉(zhuǎn)移。leader處理所有的read-write請(qǐng)求,follower需要和leader保持同步。Follower和consumer一樣,消費(fèi)消息并保存在本地日志中。leader負(fù)責(zé)跟蹤所有的follower狀態(tài),如果follower"落后"太多或者失效,leader將會(huì)把它從replicas同步列表中刪除。當(dāng)所有的follower都將一條消息保存成功,此消息才被認(rèn)為是"committed",此時(shí)consumer才能消費(fèi)它。即使只有一個(gè)replicas實(shí)例存活,仍然可以保證消息的正常發(fā)送和接收,只要zookeeper集群存活即可(不同于其他分布式存儲(chǔ),比如Hbase需要"多數(shù)派"存活才行)。當(dāng)然了,在Producer端是可以通過(guò)參數(shù)”request.required.acks”來(lái)控制自己是否要等待消息返回”committed”的響應(yīng)。

        當(dāng)leader失效時(shí),需在followers中選取出新的leader,當(dāng)然了只有處于”in-sync”狀態(tài)的followers才有參選資格。可能此時(shí)follower落后于leader,因此需要選擇一個(gè)"up-to-date"的follower。選擇follower時(shí)需要兼顧一個(gè)問(wèn)題就是新leader server上所已經(jīng)承載的partition leader的個(gè)數(shù)。如果一個(gè)server上有過(guò)多的partition leader,意味著此server將承受著更多的IO壓力。在選舉新leader時(shí)需要考慮到"負(fù)載均衡"。Follower需要能夠維護(hù)和ZooKeeper之間一個(gè)有效的會(huì)話,否則也會(huì)被判定為”unalive”。一個(gè)配置參數(shù)”replica.lag.time.max.ms”控制著一個(gè)follower數(shù)據(jù)同步滯后所能允許的最大延時(shí)。 

四 :kafka應(yīng)用場(chǎng)景

1 :消息系統(tǒng)

    kafka本身作為一個(gè)消息發(fā)布訂閱系統(tǒng),具有很好的容錯(cuò)性以及可擴(kuò)展性并且能夠支撐高并發(fā)的數(shù)據(jù)量,kafka使用了多種效率的優(yōu)化機(jī)制,采用來(lái)push/pull架構(gòu)模式,更適合于異構(gòu)集群。和大多數(shù)的消息系統(tǒng)相比,kafka具有更好的吞吐量,內(nèi)置分區(qū),復(fù)制和容錯(cuò),這使得它成為一個(gè)大規(guī)模的消息處理應(yīng)用程序。

 消息的使用往往是相對(duì)較低的吞吐量,但可能需要低終端到終端的延遲,往往依賴于強(qiáng)大的耐用性。

在這一領(lǐng)域的卡夫卡與傳統(tǒng)的消息傳遞系統(tǒng)如ActiveMQ和RabbitMQ。

3 :監(jiān)控

    Kafka通常被用于可操作的監(jiān)控?cái)?shù)據(jù)。這包括從分布式應(yīng)用程序來(lái)的聚合統(tǒng)計(jì)用來(lái)生產(chǎn)集中的運(yùn)營(yíng)數(shù)據(jù)提要。

4 :日志聚合

kafka的特性決定它非常適合作為"日志收集中心";application可以將操作日志"批量""異步"的發(fā)送到kafka集群中,而不是保存在本地或者DB中;kafka可以批量提交消息/壓縮消息等,這對(duì)producer端而言,幾乎感覺(jué)不到性能的開(kāi)支.此時(shí)consumer端可以使Hadoop等其他系統(tǒng)化的存儲(chǔ)和分析系統(tǒng)

 

 

 

參考資料 :

 

http://kafka.apache.org/0100/documentation.html

http://www.jasongj.com/2015/03/10/KafkaColumn1/

 

 

作者:劉彬

出處:http://www.cnblogs.com/Albin/

如果您覺(jué)得閱讀本文對(duì)您有幫助,請(qǐng)點(diǎn)一下“推薦”按鈕,您的“推薦”將是我最大的寫(xiě)作動(dòng)力!本文版權(quán)歸作者和博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面

http://www.cnblogs.com/DeepLearing/p/6417076.html