簡(jiǎn)介

 

Kafka擅長(zhǎng)于做什么?

它被用于兩大類(lèi)應(yīng)用:

  1. 在應(yīng)用間構(gòu)建實(shí)時(shí)的數(shù)據(jù)流通道

  2. 構(gòu)建傳輸或處理數(shù)據(jù)流的實(shí)時(shí)流式應(yīng)用

幾個(gè)概念:

  • Kafka以集群模式運(yùn)行在1或多臺(tái)服務(wù)器上

  • Kafka以topics的形式存儲(chǔ)數(shù)據(jù)流

  • 每一個(gè)記錄包含一個(gè)key、一個(gè)value和一個(gè)timestamp

Kafka有4個(gè)核心API:

  • Producer API:用于應(yīng)用程序?qū)?shù)據(jù)流發(fā)送到一個(gè)或多個(gè)Kafka topics

  • Consumer API:用于應(yīng)用程序訂閱一個(gè)或多個(gè)topics并處理被發(fā)送到這些topics中的數(shù)據(jù)

  • Streams API:允許應(yīng)用程序作為流處理器,處理來(lái)自一個(gè)或多個(gè)topics的數(shù)據(jù)并將處理結(jié)果發(fā)送到一個(gè)或多個(gè)topics中,有效的將輸入流轉(zhuǎn)化為輸出流

  • Connector API:用于構(gòu)建和運(yùn)行將Kafka topics和現(xiàn)有應(yīng)用或數(shù)據(jù)系統(tǒng)連接的可重用的produers和consumers。例如,如鏈接到關(guān)系數(shù)據(jù)庫(kù)的連接器可能會(huì)捕獲某個(gè)表所有的變更

Kafka客戶(hù)端和服務(wù)端之間的通信是建立在簡(jiǎn)單的、高效的、語(yǔ)言無(wú)關(guān)的TCP協(xié)議上的。此協(xié)議帶有版本且向后兼容。我們?yōu)镵afka提供了Java客戶(hù)端,但是客戶(hù)端可以使用多種語(yǔ)言。

Topics and Logs

Topic是發(fā)布記錄的類(lèi)別。Kafka中的Topics一般是多訂閱者的,也就是一個(gè)Topic可以有0個(gè)或多個(gè)Consumer訂閱它的數(shù)據(jù)。

對(duì)于每個(gè)主題,Kafka會(huì)會(huì)維護(hù)一個(gè)如下所示的分區(qū)日志:

每個(gè)分區(qū)是一個(gè)有序的,以不可變的記錄順序追加的Commit Log。分區(qū)中的每個(gè)記錄都有一個(gè)連續(xù)的ID,稱(chēng)為Offset,唯一標(biāo)識(shí)分區(qū)內(nèi)的記錄。

Kafka集群使用記錄保存時(shí)間的配置來(lái)保存所有已發(fā)布的記錄(無(wú)論他們是否被消費(fèi))。例如,配置策略為兩天,那么在一條記錄發(fā)布兩天內(nèi),這條記錄是可以被消費(fèi)的,之后將被丟棄以騰出空間。Kafka的性能和數(shù)據(jù)量無(wú)關(guān),所以存儲(chǔ)長(zhǎng)時(shí)間的數(shù)據(jù)并不會(huì)成為問(wèn)題。

實(shí)際上唯一需要保存的元數(shù)據(jù)是消費(fèi)者的消費(fèi)進(jìn)度,即消費(fèi)日志的偏移量(Offset)。這個(gè)Offset是由Consumer控制的:通常消費(fèi)者會(huì)在讀取記錄時(shí)以線性方式提升Offset,但是事實(shí)上,由于Offset由Consumer控制,因此它可以以任何順序消費(fèi)記錄。例如一個(gè)Consumer可以通過(guò)重置Offset來(lái)處理過(guò)去的數(shù)據(jù)或者跳過(guò)部分?jǐn)?shù)據(jù)。

這個(gè)特征意味著Kafka的Consumer可以消費(fèi)“過(guò)去”和“將來(lái)”的數(shù)據(jù)而不對(duì)集群和其他Consumer不造成太大的影響。例如,可以使用命令行工具tail來(lái)獲取Topic尾部的內(nèi)容而不對(duì)已經(jīng)在消費(fèi)Consumer造成影響。

分區(qū)日志有幾個(gè)目的。第一,使服務(wù)器能承載日志的大小,每個(gè)分區(qū)的日志必須可以被保存在單個(gè)服務(wù)器上,但是一個(gè)Topic可以擁有多個(gè)分區(qū),那么它可以處理任意大小的數(shù)據(jù)量。第二,它們作為并行度的單位(更多的是這點(diǎn)的考慮)。

Distribution

分區(qū)日志分布在集群中服務(wù)器中,每個(gè)服務(wù)器處理一部分分區(qū)的數(shù)據(jù)和請(qǐng)求。每個(gè)分區(qū)可以配置分布的服務(wù)器,以實(shí)現(xiàn)容錯(cuò)。

每個(gè)分區(qū)擁有一個(gè)Leader節(jié)點(diǎn),和零或多個(gè)Follower。Leader處理該分區(qū)所有的讀寫(xiě)請(qǐng)求,F(xiàn)ollower復(fù)制Leader數(shù)據(jù)。如果Leader節(jié)點(diǎn)宕機(jī),將會(huì)有一個(gè)Follower節(jié)點(diǎn)自動(dòng)的轉(zhuǎn)化為L(zhǎng)eader。每個(gè)節(jié)點(diǎn)成為其部分分區(qū)的Leader,并成為剩余分區(qū)的Follower,這樣整個(gè)集群的負(fù)載將比較均衡。

Producers

Producer發(fā)送數(shù)據(jù)到它選擇的Topic。Producer負(fù)責(zé)決定將數(shù)據(jù)發(fā)送到Topic的那個(gè)分區(qū)上。這可以通過(guò)簡(jiǎn)單的循環(huán)方式來(lái)平衡負(fù)載,或則可以根據(jù)某些語(yǔ)義來(lái)決定分區(qū)(例如基于數(shù)據(jù)中一些關(guān)鍵字)。

Consumers

Consumer使用一個(gè)group name來(lái)標(biāo)識(shí)自己的身份,每條被發(fā)送到一個(gè)Topic的消息都將被分發(fā)到屬于同一個(gè)group的Consumer的一個(gè)實(shí)例中(group name相同的Consumer屬于一個(gè)組,一個(gè)Topic的一條消息會(huì)被這個(gè)組中的一個(gè)Consumer實(shí)例消費(fèi))。Consumer實(shí)例可以在單獨(dú)的進(jìn)程中或者單獨(dú)的機(jī)器上。

如果所有的Consumer實(shí)例都是屬于一個(gè)group的,那么所有的消息將被均衡的分發(fā)給每個(gè)實(shí)例。

如果所有的Consumer都屬于不同的group,那么每條消息將被廣播給所有的Consumer。

(上圖)一個(gè)包含兩個(gè)Server的Kafka集群,擁有四個(gè)分區(qū)(P0-P3),有兩個(gè)Consumer group:Group A和Group B。Group有C1、C2兩個(gè)Consumer,GroupB有C3、C4、C5、C6四個(gè)Consumer。

更常見(jiàn)的是,Topic有少量的Consumer group,每一個(gè)都是“一個(gè)邏輯上的訂閱者”。每個(gè)group包含多個(gè)Consumer實(shí)例,為了可伸縮性和容錯(cuò)性。這就是一個(gè)發(fā)布-訂閱模式,只是訂閱方是一個(gè)集群。

Kafka中消費(fèi)的實(shí)現(xiàn)方式是“公平”的將分區(qū)分配給Consumer,每一個(gè)時(shí)刻分區(qū)都擁有它唯一的消費(fèi)者。Consumer成員關(guān)系有Kafka程度動(dòng)態(tài)維護(hù)。如果新的Consumer加入了分區(qū),那么它會(huì)從這個(gè)分區(qū)其他的Consumer中分配走一部分分區(qū);如果部分Consumer實(shí)例宕機(jī),它的分區(qū)會(huì)被其他Consumer實(shí)例接管。

Kafka只保證同一個(gè)分區(qū)內(nèi)記錄的順序,而不是同一個(gè)Topic的不同分區(qū)間數(shù)據(jù)的順序。每個(gè)分區(qū)順序結(jié)合按Key分配分區(qū)的能力,能滿(mǎn)足大多數(shù)程序的需求。如果需要全局的順序,可以使用只有一個(gè)分區(qū)的Topic,這意味著每個(gè)group只能有一個(gè)Consumer實(shí)例(因?yàn)橐粋€(gè)分區(qū)同一時(shí)刻只能被一份Consumer消費(fèi)——多加的Consumer只能用于容錯(cuò))。

Guarantees

Kafka高級(jí)API中提供一些能力:

被一個(gè)Producer發(fā)送到特定Topic分區(qū)的消息將按照他們的發(fā)送順序被添加到日志中。這意味著,如果M1、M2是被同一個(gè)Producer發(fā)送出來(lái)的,且M1先發(fā)送,那么M1擁有更小的Offset,在日志中的位置更靠前。

Consumer按照消息的存儲(chǔ)順序在日志文件中查找消息。

對(duì)于復(fù)制配置參數(shù)為N的Topic,我們能容忍N(yùn)-1的服務(wù)器故障,而不會(huì)丟失已經(jīng)Commit的數(shù)據(jù)。有關(guān)這些保證更詳細(xì)的信息,參見(jiàn)文檔的設(shè)計(jì)部分。

Kafka as a Messaging System

Kafka的流模式和傳統(tǒng)的消息系統(tǒng)有什么區(qū)別?

消息傳統(tǒng)上有兩種模式:隊(duì)列和發(fā)布-訂閱。在隊(duì)列中,一群Consumer從一個(gè)Server讀取數(shù)據(jù),每條消息被其中一個(gè)Consumer讀取。在發(fā)布-訂閱中,消息被廣播給所有的Consumer。這兩種模式有各自的優(yōu)缺點(diǎn)。隊(duì)列模式的優(yōu)點(diǎn)是你可以在多個(gè)消費(fèi)者實(shí)例上分配數(shù)據(jù)處理,從而允許你對(duì)程序進(jìn)行“伸縮”。確定是隊(duì)列不是多用戶(hù)的,一旦消息被一個(gè)Consumer讀取就不會(huì)再給其他Consumer。發(fā)布訂閱模式允許廣播數(shù)據(jù)到多個(gè)Consumer,那么就沒(méi)辦法對(duì)單個(gè)Consumer進(jìn)行伸縮。

Kafka的Consumer group包含兩個(gè)概念。與隊(duì)列一樣,消費(fèi)組允許通過(guò)一些進(jìn)程來(lái)劃分處理(每個(gè)進(jìn)程處理一部分)。與發(fā)布訂閱一樣,Kafka允許廣播消息到不同的Consumer group。

Kafka模式的優(yōu)勢(shì)是每個(gè)Topic都擁有隊(duì)列和發(fā)布-訂閱兩種模式。

Kafka比傳統(tǒng)的消息系統(tǒng)有更強(qiáng)的順序保證。

傳統(tǒng)的消息系統(tǒng)在服務(wù)器上按順序保存消息,如果多個(gè)Consumer從隊(duì)列中消費(fèi)消息,服務(wù)器按照存儲(chǔ)的順序輸出消息。然后服務(wù)器雖然按照順序輸出消息,但是消息將被異步的傳遞給Consumer,所以他們將以不確定的順序到達(dá)Consumer。這意味著在并行消費(fèi)中將丟失消息順序。傳統(tǒng)消息系統(tǒng)通常采用“唯一消費(fèi)者”的概念只讓一個(gè)Consumer進(jìn)行消費(fèi),但這就丟失了并行處理的能力。

Kafka做的更好一些。通過(guò)提供分區(qū)的概念,Kafka能提供消費(fèi)集群順序和負(fù)載的平衡。這是通過(guò)將分區(qū)分配個(gè)一個(gè)Consumer group中唯一的一個(gè)Consumer而實(shí)現(xiàn)的,一個(gè)分區(qū)只會(huì)被一個(gè)分組中的一個(gè)Consumer進(jìn)行消費(fèi)。通過(guò)這么實(shí)現(xiàn),能讓一個(gè)Consumer消費(fèi)一個(gè)分區(qū)并按照順序處理消息。因?yàn)榇嬖诙鄠€(gè)分區(qū),所有可以在多個(gè)Consumer實(shí)例上實(shí)現(xiàn)負(fù)載均衡。注意,一個(gè)分組內(nèi)的Consumer實(shí)例數(shù)不能超過(guò)分區(qū)數(shù)。

Kafka as a Storage System

任何將發(fā)送消息和消費(fèi)結(jié)構(gòu)的消息隊(duì)列都有效的用作一個(gè)消息的存儲(chǔ)系統(tǒng)。不同的是Kafka是一個(gè)更好的存儲(chǔ)系統(tǒng)。

被寫(xiě)入到Kafka的數(shù)據(jù)將被寫(xiě)入磁盤(pán)并復(fù)制以保證容錯(cuò)。Kafka允許Producer等待確定,以保證Producer可以確認(rèn)消息被成功持久化并復(fù)制完成。

Kafka使用的存儲(chǔ)結(jié)構(gòu),使其提供相同的能力,無(wú)論是存儲(chǔ)50KB或者50TB持久化數(shù)據(jù)。

因?yàn)樵试S客戶(hù)端控制讀取的位置,可以將Kafka視為高性能,低延遲的日志存儲(chǔ)、復(fù)制、傳播的分布式系統(tǒng)。

Kafka for Stream Processing

僅僅是讀寫(xiě)和存儲(chǔ)流數(shù)據(jù)是不夠的,Kafka的目標(biāo)是對(duì)流失數(shù)據(jù)的實(shí)時(shí)處理。

在Kafka中,Stream Producer從輸入的Topic中讀取數(shù)據(jù),執(zhí)行一些操作,生成輸出流到輸出的Topic中。

例如,零售的應(yīng)用程序?qū)⑹盏戒N(xiāo)售和出貨的輸入流,并輸出根據(jù)該數(shù)據(jù)計(jì)算的重排序和價(jià)格調(diào)整后的數(shù)據(jù)流。

可以使用Producer和Consumer實(shí)現(xiàn)簡(jiǎn)單的處理。對(duì)于更復(fù)雜的轉(zhuǎn)換,Kafka提供的完成的Stream API,允許構(gòu)建將流中數(shù)據(jù)聚合或?qū)⒘鬟B接到一起的應(yīng)用。

這用于解決以下的一些困難:處理無(wú)需的數(shù)據(jù),執(zhí)行有狀態(tài)的計(jì)算等。

Stream API基于Kafka的核心函數(shù)古劍:使用Producer和Consumer API用于輸入,使用Kafka作為有狀態(tài)的存儲(chǔ),使用group機(jī)制來(lái)實(shí)現(xiàn)Stream處理器的容錯(cuò)。

Putting the Pieces Together

消息、存儲(chǔ)和流處理這種組合看是不尋常,但是Kafka作為流式平臺(tái)這是必須的。

類(lèi)似HDFS的分布式文件系統(tǒng)存儲(chǔ)靜態(tài)的文件用于批處理。這種的系統(tǒng)允許存儲(chǔ)和處理歷史數(shù)據(jù)。

傳統(tǒng)的企業(yè)消息系統(tǒng)允許處理在你訂閱之后的未來(lái)的數(shù)據(jù)。以這種方式構(gòu)建的應(yīng)用程序在未來(lái)數(shù)據(jù)到達(dá)時(shí)進(jìn)行處理。

Kafka組合這些能力,并且組合這些對(duì)Kafka作為流應(yīng)用平臺(tái)和流數(shù)據(jù)通道至關(guān)重要。

通過(guò)組合存儲(chǔ)和低延遲的訂閱,流應(yīng)用程序能以相同的方式處理過(guò)去和未來(lái)的數(shù)據(jù)。一個(gè)單一的程序可以處理過(guò)去的歷史數(shù)據(jù),并且不會(huì)在達(dá)到一個(gè)位置時(shí)停止,而是能繼續(xù)處理將來(lái)到達(dá)的數(shù)據(jù)。這是一個(gè)廣泛的流處理的概念,其中包含批處理和消息驅(qū)動(dòng)的應(yīng)用程序。

同樣,對(duì)于數(shù)據(jù)流通道,組合訂閱機(jī)制和實(shí)時(shí)事件使Kafka成為非常低延遲的管道;數(shù)據(jù)的存儲(chǔ)能力使其能和可能會(huì)進(jìn)行停機(jī)維護(hù)的周期性處理數(shù)據(jù)的離線系統(tǒng)集成,或用于必須保證數(shù)據(jù)被確認(rèn)交付的場(chǎng)景。流處理程序可以在數(shù)據(jù)到達(dá)后進(jìn)行處理。

其他關(guān)閉Kafka提供的API、功能,參閱其他文檔。

http://www.cnblogs.com/hzmark/p/kafka_introduction.html