1.1私蕾、簡介
ApacheKafka?是一個分布式流媒體平臺猎提。 這到底是什么意思呢?
- 它可以讓你發(fā)布和訂閱消息流寸五。 在這方面梳凛,它類似于消息隊(duì)列或企業(yè)消息傳遞系統(tǒng)。
- 它允許您以容錯方式存儲消息流梳杏。
- 它可以讓你處理產(chǎn)生的流式消息韧拒。
Kafka的優(yōu)勢在哪里?
- 在系統(tǒng)或應(yīng)用程序之間構(gòu)建可靠的實(shí)時數(shù)據(jù)流管道
- 構(gòu)建實(shí)時流應(yīng)用程序十性,可以轉(zhuǎn)換或響應(yīng)數(shù)據(jù)流
要理解kafka必須要了解一下概念:
- Kafka在一個或多個服務(wù)器上的集群運(yùn)行叛溢。
- Kafka集群以叫做主題(topic)的類別存儲記錄流。
- 每個記錄(消息)由一個鍵劲适,一個值和一個時間戳組成楷掉。
Kafka有四個核心API:
- Producer API允許應(yīng)用程序?qū)⒁唤M記錄發(fā)布到一個或多個Kafka主題。
- Consumer API允許應(yīng)用程序訂閱一個或多個主題并處理產(chǎn)生給他們的消息流霞势。
- Streams API允許應(yīng)用程序充當(dāng)流處理器烹植,從一個或多個主題中消費(fèi)輸入流,并將輸出流生成為一個或多個輸出主題愕贡,從而將輸入流有效地轉(zhuǎn)換為輸出流草雕。
- Connector API允許構(gòu)建和運(yùn)行可重復(fù)使用的生產(chǎn)者或消費(fèi)者,將Kafka主題連接到現(xiàn)有的應(yīng)用程序或數(shù)據(jù)系統(tǒng)固以。 例如促绵,連接到關(guān)系數(shù)據(jù)庫的連接器可能會捕獲對表的每個更改。
在Kafka中嘴纺,客戶端和服務(wù)器之間的通信是通過一個簡單的败晴,高性能的,與編程語言無關(guān)的TCP協(xié)議完成的栽渴。 這個協(xié)議是版本化的尖坤,并保持與舊版本的向后兼容性。 我們?yōu)镵afka提供了一個Java客戶端闲擦,但客戶端可以使用多種語言慢味。
主題和日志
讓我們先深入kafka為消息流提供的一個核心抽象- 主題(topic)。
Topic是消息發(fā)布到哪一個類別或者提要的名稱墅冷。Kafka的主題可以是多訂閱模式的纯路,也就是說一個主題可以有0個、1個或者多個消費(fèi)者去消費(fèi)寫入該主題的數(shù)據(jù)寞忿。
對于每個主題驰唬,Kafka集群維護(hù)一個分區(qū)日志,如下所示:
每個分區(qū)是一個有序的,不可變的消息序列叫编,不斷追加到結(jié)構(gòu)化的提交日志(文件)中辖佣。 分區(qū)中的每個消息分配一個連續(xù)的id號,稱為偏移量(offset)搓逾,用于唯一標(biāo)識分區(qū)內(nèi)的每條消息卷谈。
Kafka集群使用可配置的保留期限來保留所有已發(fā)布的消息(無論是否已被使用)。 例如霞篡,如果保留策略設(shè)置為兩天世蔗,則在消息發(fā)布后的兩天內(nèi),消息可以可供使用朗兵,之后將被丟棄以騰出空間凸郑。Kafka性能對數(shù)據(jù)大小不敏感,所以長時間存儲數(shù)據(jù)不成問題矛市。
實(shí)際上芙沥,以消費(fèi)者為單位保留的唯一元數(shù)據(jù)是消費(fèi)者在日志中的偏移或位置。這個偏移量是由消費(fèi)者控制的:消費(fèi)者通常會在讀取記錄時線性地推進(jìn)其偏移量浊吏,但事實(shí)上而昨,由于消費(fèi)者的位置是由消費(fèi)者控制的,所以它可以以任何喜歡的順序消費(fèi)記錄找田。例如歌憨,消費(fèi)者可以重置為較早的偏移量以重新處理過去的數(shù)據(jù),或者跳至最近的記錄并從“現(xiàn)在”開始消費(fèi)墩衙。
這些功能的組合意味著Kafka的消費(fèi)者非常輕便 - 他們可以來來去去务嫡,對集群或其他消費(fèi)者沒有太大的影響。例如漆改,您可以使用我們的命令行工具來“tail”任何主題的內(nèi)容心铃,而不會更改任何現(xiàn)有消費(fèi)者使用的內(nèi)容。
日志中的分區(qū)有幾個用途挫剑。 首先去扣,它們允許日志的大小超出適合單個服務(wù)器的存儲限制。 每個單獨(dú)的分區(qū)必須適合存放它的服務(wù)器樊破,但是一個主題可能有許多分區(qū)愉棱,因此它可以處理任意數(shù)量的數(shù)據(jù)。 其次哲戚,更重要的是奔滑,它們是作為并行處理的單位。
分布式
日志的所有有分區(qū)被分發(fā)到集群中的服務(wù)器上顺少,每個服務(wù)器處理全部分區(qū)中的部分分區(qū)數(shù)據(jù)和請求朋其。為了容錯王浴,每個分區(qū)都被復(fù)制到一定數(shù)量(可配置)的不同服務(wù)器上。
每個分區(qū)(有多個副本)都有一臺服務(wù)器作為“l(fā)eader”令宿,大于等于0臺服務(wù)器做為”followers”⊥罂”leader”服務(wù)器處理分區(qū)的所有讀寫操作粒没。”followers”服務(wù)器對當(dāng)前分區(qū)做為旁觀者簇爆,什么都不做癞松。當(dāng)”leader”服務(wù)器不可用時,那么”followers”中的一臺將自動成為”leader”入蛆。每臺服務(wù)器都即做為一些分區(qū)的”leader”响蓉,又做為其它分區(qū)的“followers”。
生產(chǎn)者
生產(chǎn)者向所選的主題發(fā)布數(shù)據(jù)哨毁。生產(chǎn)者負(fù)責(zé)選擇哪些消息應(yīng)該分配到主題內(nèi)的哪個分區(qū)枫甲。這種選擇分區(qū)方式,可以使用簡單的循環(huán)方式來負(fù)載均衡扼褪; 也可以通過一些語義分區(qū)函數(shù)實(shí)現(xiàn)(如:基于消息的key的hash等)想幻,更多的是第二種情況來使用分區(qū)。
消費(fèi)者
傳統(tǒng)的消息處理有兩種模型:隊(duì)列和發(fā)布訂閱话浇。隊(duì)列模式脏毯,消費(fèi)者池中的消費(fèi)者可以從一臺服務(wù)器讀數(shù)據(jù),并且每個消息只被其中一個消費(fèi)者消費(fèi)幔崖。發(fā)布訂閱模式食店,消息通過廣播方式發(fā)送給所有消費(fèi)者。kafka提供了一個單一的抽象概念赏寇,可以滿足這兩種(隊(duì)列吉嫩、發(fā)布訂閱)模式--消費(fèi)者組。
消費(fèi)者通過分組名(group name)標(biāo)識自己嗅定,每條消息被發(fā)布到主題率挣,并只會分發(fā)給消費(fèi)者組中的 唯一個 消費(fèi)者實(shí)例(即只被組中的一個消費(fèi)者消費(fèi))。這些消費(fèi)者即可以是同一臺服務(wù)器上不同的進(jìn)程露戒,也可以是位于不同服務(wù)器上進(jìn)程椒功。
如果所有的消費(fèi)者實(shí)例屬于同一分組(相同的分組名),那么這就是傳統(tǒng)的隊(duì)列模式(相同topic智什,只有一個消費(fèi)者能搶到消息)动漾。
如果所有的消費(fèi)者實(shí)例不屬于同一分組,那么這就是發(fā)布訂閱模式(每個消費(fèi)者都能收到消息)
兩個服務(wù)器Kafka集群管理四個分區(qū)(P0-P3)與兩個消費(fèi)者組荠锭。消費(fèi)者組A有兩個消費(fèi)者實(shí)例旱眯,而組B有四個消費(fèi)者實(shí)例。
然而,更普遍的是删豺,topic只有少量的消費(fèi)組共虑,每個“邏輯訂閱者”都有一個消費(fèi)組。每個組由許多消費(fèi)者實(shí)例組成呀页,具有可擴(kuò)展性和容錯性妈拌。這就是發(fā)布-訂閱模式,訂閱者是一群消費(fèi)者而不是一個進(jìn)程蓬蝶。
傳統(tǒng)隊(duì)列維護(hù)消息順序性尘分。如果多個消費(fèi)者從隊(duì)列中消費(fèi)消息,那么服務(wù)器以存儲的順序分發(fā)消息丸氛。雖然消息從服務(wù)器出隊(duì)列是按順序的培愁,但是被分發(fā)給消費(fèi)者時,是通過異步的方式缓窜,因此消息到達(dá)不同消費(fèi)者時可能是亂序的定续。這意味者并發(fā)消費(fèi)時,消費(fèi)是亂序的禾锤。消息系統(tǒng)為了做到這點(diǎn)香罐,會采用只有一個消費(fèi)者消費(fèi)的理念,但這也意味是無法并行操作时肿。
kafka這點(diǎn)做的更好庇茫,通過稱為分區(qū)(主題內(nèi))的并行概念,kafka即可以提供順序又可以負(fù)載均衡螃成。這是通過給主題內(nèi)的相同分組下的消費(fèi)者提供多個分區(qū)的架構(gòu)旦签,來實(shí)現(xiàn)每個分區(qū)只能被一個消費(fèi)者消費(fèi)。通過這種方式寸宏,可以確保同一分區(qū)只有一個消費(fèi)者宁炫,因此一個分區(qū)消費(fèi)消息是順序的; 同時氮凝,由于有多個分區(qū)羔巢,因此可以負(fù)載均衡。注意:一個分組內(nèi)罩阵,消費(fèi)者數(shù)量不能多于分區(qū)數(shù)量竿秆。此處的:不能多于,不是絕對稿壁。即:一個應(yīng)用集群(有消費(fèi)者)可能遠(yuǎn)遠(yuǎn)多于分區(qū)數(shù)量幽钢,只能說超出的消費(fèi)者永遠(yuǎn)都無分區(qū)消費(fèi),但并不影響其它消費(fèi)者正常使用傅是。
kafka僅僅支持分區(qū)內(nèi)的消息順序消費(fèi)匪燕,并不支持全局(同一主題的不同分區(qū)之間)的消息順序蕾羊。每個分區(qū)排序與根據(jù)消息key進(jìn)行數(shù)據(jù)分區(qū)的能力相結(jié)合,足以滿足大多數(shù)應(yīng)用程序的需求帽驯。 但是龟再,如果你需要一個全局順序消費(fèi)消息,你可以通過一個主題只有一個分區(qū)的方法實(shí)現(xiàn)尼变,但是這也意味著一個分組只有一消費(fèi)者利凑。
保證
一個高級的kafka提供以下保證:
- 由生產(chǎn)者發(fā)送到特定主題分區(qū)的消息將按照它們發(fā)送的順序添加。 也就是說享甸,如果記錄M1和記錄M2由同一個生產(chǎn)者發(fā)送截碴,并且M1被首先發(fā)送梳侨,則M1將具有比M2更低的偏移量值并且出現(xiàn)在日志中較早的地方蛉威。
- 消費(fèi)者實(shí)例按照存儲在日志中的順序查看記錄。
- 對于具有復(fù)制因子(replication factor)N的主題走哺,我們將容忍多達(dá)N-1個服務(wù)器故障蚯嫌,而不會丟失任何提交給日志的記錄。
有關(guān)這些保證的更多細(xì)節(jié)在文檔的設(shè)計(jì)章節(jié)丙躏。
kafka作為消息系統(tǒng)
Kafka的流概念如何與傳統(tǒng)的企業(yè)消息系統(tǒng)相比較择示?
消息傳統(tǒng)上有兩種模式:隊(duì)列和發(fā)布-訂閱。在隊(duì)列中晒旅,消費(fèi)者池可以從服務(wù)器讀取并且每條消息只去往其中的一個;在發(fā)布-訂閱中消息被廣播給所有消費(fèi)者栅盲。這兩種模式都有其優(yōu)點(diǎn)和缺點(diǎn)。隊(duì)列的優(yōu)勢在于它允許您將數(shù)據(jù)處理劃分為多個消費(fèi)者實(shí)例废恋,這樣可以擴(kuò)展處理谈秫。不幸的是,隊(duì)列不是多訂閱的鱼鼓,一旦一個進(jìn)程讀取了數(shù)據(jù)它就消失了拟烫。發(fā)布-訂閱允許您將數(shù)據(jù)廣播到多個進(jìn)程,但無法進(jìn)行擴(kuò)展處理迄本,因?yàn)槊織l消息都發(fā)送給每個訂閱者硕淑。
Kafka的消費(fèi)群體概念包含了這兩個概念。與隊(duì)列一樣嘉赎,消費(fèi)者組允許您將一系列流程(消費(fèi)者組的成員)的處理分開置媳。與發(fā)布-訂閱一樣,Kafka允許您向多個消費(fèi)者群體廣播消息公条。
Kafka模型的優(yōu)點(diǎn)是每個主題都具有這些屬性 - 它可以擴(kuò)展處理半开,也可以是多訂閱 - topic不需要選擇其中一個。
Kafka也比傳統(tǒng)的消息系統(tǒng)有更強(qiáng)的順序保證赃份。
傳統(tǒng)隊(duì)列在服務(wù)器上按順序保留記錄寂拆,并且如果多個消費(fèi)者從隊(duì)列中消費(fèi)奢米,則服務(wù)器按照它們存儲的順序取出記錄。但是纠永,雖然服務(wù)器按順序取出記錄鬓长,但是記錄是異步傳遞給消費(fèi)者的,所以不同的消費(fèi)者可能不是按照順序收到消息尝江。這實(shí)際上意味著記錄的排序在并行消耗的情況下丟失涉波。消息傳遞系統(tǒng)通常具有“排他消費(fèi)者”的屬性,只允許一個進(jìn)程從隊(duì)列中消耗炭序,但這當(dāng)然意味著在處理中沒有并行處理能力啤覆。
Kafka做得更好。 通過在主題內(nèi)部有一個并行的概念 - 分區(qū)惭聂,Kafka能夠提供排序保證和負(fù)載平衡窗声。 這是通過將主題中的分區(qū)分配給使用者組中的使用者來實(shí)現(xiàn)的,以便每個分區(qū)僅由組中的一個使用者使用辜纲。 通過這樣做笨觅,我們確保消費(fèi)者是該分區(qū)的唯一消費(fèi)者,并按順序使用這些數(shù)據(jù)耕腾。 由于有很多分區(qū)见剩,這仍然可以平衡許多消費(fèi)者實(shí)例的負(fù)載。 但請注意扫俺,消費(fèi)群組中的消費(fèi)者實(shí)例不能多于分區(qū)苍苞。
卡夫卡作為存儲系統(tǒng)
任何允許將消息發(fā)布出去的消息隊(duì)列都可以充當(dāng)存儲系統(tǒng)。 Kafka的不同之處在于它是一個非常好的存儲系統(tǒng)狼纬。
數(shù)據(jù)寫入kafka時被寫入到磁盤, 并復(fù)制到其他服務(wù)器上進(jìn)行容錯, kafka允許生產(chǎn)者只有在消息已經(jīng)復(fù)制完, 并存儲后才得到寫成功的通知, 否則就認(rèn)為失敗.
kafka也很有效率利用了磁盤結(jié)構(gòu)–無論你存儲的是50KB或50TB的數(shù)據(jù)在kafka上, kafka都會有同樣的性能
由于嚴(yán)謹(jǐn)?shù)目紤]存儲并允許客戶端控制其讀取位置羹呵,所以可以將Kafka視為專用于高性能,低延遲提交日志存儲畸颅,復(fù)制和傳播的專用分布式文件系統(tǒng)担巩。
kafka作為數(shù)據(jù)流處理
只讀取,寫入和存儲數(shù)據(jù)流是不夠的没炒,目的是允許流的實(shí)時處理涛癌。
kafka的流數(shù)據(jù)處理器是持續(xù)從輸入的topic讀取連續(xù)的數(shù)據(jù)流, 進(jìn)行數(shù)據(jù)處理, 轉(zhuǎn)換, 后產(chǎn)生連續(xù)的數(shù)據(jù)流輸出到topic中
例如,零售應(yīng)用程序可能會接受輸入的銷售和發(fā)貨流送火,并輸出一系列重排序的數(shù)據(jù)并針對這些數(shù)據(jù)的計(jì)算進(jìn)行價格調(diào)整拳话。
直接使用生產(chǎn)者和消費(fèi)者API可以做簡單的處理。但是對于更復(fù)雜的轉(zhuǎn)換种吸,Kafka提供了一個完全集成的Streams API弃衍。這允許構(gòu)建應(yīng)用程序進(jìn)行非一般的處理,從而對流進(jìn)行聚合或者join另外一個流坚俗。
這個工具有助于解決這類應(yīng)用程序面臨的難題:處理亂序數(shù)據(jù)镜盯,重新處理代碼更改的輸入岸裙,執(zhí)行有狀態(tài)的計(jì)算等等。
流API基于Kafka提供的核心原函數(shù)構(gòu)建:它使用生產(chǎn)者和消費(fèi)者API進(jìn)行輸入速缆,使用Kafka進(jìn)行有狀態(tài)存儲降允,并在流處理器實(shí)例之間使用相同的組機(jī)制來實(shí)現(xiàn)容錯。
整合
消息傳遞艺糜,存儲和流處理的這種組合可能看起來很不尋常剧董,但對于Kafka作為一個流媒體平臺來說,這是非常重要的破停。
像HDFS這樣的分布式文件系統(tǒng)允許存儲用于批處理的靜態(tài)文件翅楼。這樣的系統(tǒng)可以有效地存儲和處理過去的歷史數(shù)據(jù)。
傳統(tǒng)的企業(yè)消息系統(tǒng)只允許處理在你訂閱之后到達(dá)的數(shù)據(jù)真慢,以這種方式構(gòu)建的應(yīng)用程序處理在將來到達(dá)的數(shù)據(jù)毅臊。
Kafka結(jié)合了這兩種功能,而且這兩種組合對于Kafka用作流應(yīng)用平臺以及流式傳輸數(shù)據(jù)管道都是至關(guān)重要的晤碘。
通過將存儲和低延遲訂閱相結(jié)合褂微,流式應(yīng)用程序可以同樣的方式處理歷史和未來的數(shù)據(jù)功蜓。一個應(yīng)用可以處理歷史存儲的數(shù)據(jù), 也可以在讀到最后記錄后, 保持等待未來的數(shù)據(jù)進(jìn)行處理园爷。這是流處理的概括概念,包括批處理以及消息驅(qū)動的應(yīng)用程序式撼。