原文鏈接https://kafka.apache.org/intro
Apache Kafka作為一個(gè)流分布式平臺(tái)辆琅,到底意味著什么
我們認(rèn)為排抬,一個(gè)流處理平臺(tái)具有三個(gè)關(guān)鍵能力:
- 允許發(fā)布訂閱消息流,在這方面胯盯,類似于一個(gè)消息隊(duì)列网杆,或者企業(yè)消息系統(tǒng)捞蛋。
- 高容錯(cuò)的存儲(chǔ)消息流吠撮。
- 允許在消息流出現(xiàn)時(shí)實(shí)時(shí)地處理它們尊惰。
那么kakfa的優(yōu)勢(shì)體現(xiàn)在哪?
它應(yīng)用于兩大類應(yīng)用上:
- 構(gòu)建實(shí)時(shí)的數(shù)據(jù)流管道泥兰,可靠地獲取系統(tǒng)或應(yīng)用之間的數(shù)據(jù)弄屡。
- 構(gòu)建一個(gè)基于流的應(yīng)用,實(shí)時(shí)地轉(zhuǎn)換或?qū)?shù)據(jù)流做出反應(yīng)鞋诗。
為了理解kafka是如何做到這些事情琢岩,讓我們從下到上,深入挖掘kafka的能力师脂。
首先是一些概念
- kafka是作為一個(gè)集群運(yùn)行在一個(gè)或多個(gè)服務(wù)器上
- kakfa集群以topic的形式記錄存儲(chǔ)的消息流
- 每一條消息都包括一個(gè)key,一個(gè)value和一個(gè)時(shí)間戳
Kafka有四個(gè)核心的API
- Producer API:允許一個(gè)應(yīng)用發(fā)布消息流到一個(gè)或多個(gè)topic里
- Consumer API:允許一個(gè)應(yīng)用訂閱一個(gè)或多個(gè)topic江锨,處理它們產(chǎn)生的消息
- Streams API:允許一個(gè)應(yīng)用充當(dāng)一個(gè)流處理器吃警,消費(fèi)從一個(gè)或多個(gè)topic獲取的數(shù)據(jù)流,處理之后生產(chǎn)輸出流到一個(gè)或多個(gè)topic啄育,可以有效地把輸入流轉(zhuǎn)換成輸出流
- Connector API:允許構(gòu)建可重復(fù)使用的消費(fèi)者或生產(chǎn)者酌心,把topic連接到現(xiàn)有的應(yīng)用程序或者數(shù)據(jù)系統(tǒng)。
在Kafka中挑豌,客戶端和服務(wù)端的通信是通過簡(jiǎn)單的安券、高性能墩崩、與語(yǔ)言無(wú)關(guān)的TCP協(xié)議。除了Java Client之外侯勉,還有好多其他語(yǔ)言的Client可以選擇鹦筹。
話題和日志(Topics & Logs)
先來深入地了解下Kafka里面的topic。Topic是發(fā)布的消息的類別或者種子(Feed)名址貌。Kafka中的topic可以沒有訂閱者铐拐,可以有一個(gè)訂閱者,也可以有好多訂閱者练对。
對(duì)于每一個(gè)Topic遍蟋,Kafka集群維護(hù)這一個(gè)分區(qū)的log,就像下圖中的示例:
每一個(gè)分區(qū)都是一個(gè)有序的螟凭、不可變的消息隊(duì)列虚青, 并且可以持續(xù)的添加。分區(qū)中的消息都被分了一個(gè)序列號(hào)螺男,稱之為偏移量(offset)棒厘,在每個(gè)分區(qū)中此偏移量都是唯一的。
Kafka集群在一個(gè)可配置的時(shí)間段內(nèi)維持所有的消息烟号,無(wú)論它們是否被消費(fèi)绊谭。 比如這個(gè)時(shí)間段被設(shè)置為2天,那么這個(gè)消息在發(fā)布后兩天內(nèi)都能被獲取并消費(fèi)汪拥,兩天后就會(huì)被丟棄以釋放空間达传。
實(shí)際上消費(fèi)者所持有的僅有的元數(shù)據(jù)就是這個(gè)偏移量,也就是消費(fèi)者在這個(gè)log中的位置迫筑。 這個(gè)偏移量由消費(fèi)者控制:正常情況當(dāng)消費(fèi)者消費(fèi)消息的時(shí)候宪赶,偏移量也線性的的增加。但是由于實(shí)際上偏移量由消費(fèi)者自己控制脯燃,所以消費(fèi)者可以以任何順序讀取消息搂妻。舉個(gè)栗子,一個(gè)消費(fèi)者可以將偏移量重置為更老的一個(gè)偏移量辕棚,重新讀取消息欲主,或者設(shè)置為最新的值,跳過中間的消息逝嚎。
可以看到這種設(shè)計(jì)使得一個(gè)消費(fèi)者的操作不會(huì)影響其它消費(fèi)者扁瓢。 再說說分區(qū)。Kafka中采用分區(qū)的設(shè)計(jì)有幾個(gè)目的补君。一是不受單臺(tái)服務(wù)器的限制引几,一個(gè)分區(qū)可能會(huì)被持有它的服務(wù)器限制,但是Topic擁有多個(gè)分區(qū)挽铁,這就意味著它可以不受限的處理更多的數(shù)據(jù)伟桅。第二敞掘,分區(qū)可以作為并行處理的單元,稍后會(huì)談到這一點(diǎn)楣铁。
分布式
Log的分區(qū)被分布到集群中的多個(gè)服務(wù)器上玖雁,每個(gè)服務(wù)器處理它分到的分區(qū)。 根據(jù)配置每個(gè)分區(qū)還可以復(fù)制到其它服務(wù)器作為備份來容錯(cuò)民褂。 每個(gè)分區(qū)有一個(gè)leader茄菊,零或多個(gè)follower。Leader處理此分區(qū)的所有的讀寫請(qǐng)求赊堪,而follower被動(dòng)的復(fù)制數(shù)據(jù)面殖。如果leader宕機(jī),其它的一個(gè)follower會(huì)被推舉為新的leader哭廉。 一臺(tái)服務(wù)器可能同時(shí)是一個(gè)分區(qū)的leader脊僚,另一個(gè)分區(qū)的follower。 這樣可以平衡負(fù)載遵绰,避免所有的請(qǐng)求都只讓一臺(tái)或者某幾臺(tái)服務(wù)器處理辽幌。
生產(chǎn)者
生產(chǎn)者往某個(gè)Topic上發(fā)布消息,也負(fù)責(zé)選擇發(fā)布到Topic上的哪一個(gè)分區(qū)椿访。最簡(jiǎn)單的方式從分區(qū)列表中輪流選擇乌企。也可以根據(jù)某種算法依照權(quán)重選擇分區(qū)。
消費(fèi)者
消費(fèi)者用一個(gè)消費(fèi)者組名來標(biāo)記自己成玫。 一個(gè)發(fā)布在某個(gè)Topic上的消息被分發(fā)給此消費(fèi)者組中的一個(gè)消費(fèi)者加酵,注意是一個(gè)哦。一個(gè)消費(fèi)者可能在不同進(jìn)程或者機(jī)器上哭当。
如果所有的消費(fèi)者都在一個(gè)組里猪腕,那消息可以被有效的均衡負(fù)載到每一個(gè)消費(fèi)者。
如果所有消費(fèi)者都在不同的組里钦勘,那消息會(huì)被廣播到所有的消費(fèi)者陋葡。
2個(gè)kafka集群托管4個(gè)分區(qū)(P0-P3),2個(gè)消費(fèi)者組彻采,消費(fèi)組A有2個(gè)消費(fèi)者實(shí)例腐缤,消費(fèi)組B有4個(gè)。
更通用的肛响, 我們可以創(chuàng)建一些消費(fèi)者組作為邏輯上的訂閱者岭粤。每個(gè)組包含數(shù)目不等的消費(fèi)者, 一個(gè)組內(nèi)多個(gè)消費(fèi)者可以用來擴(kuò)展性能和容錯(cuò)终惑。