Apache Kafka是一個(gè)分布式流式平臺(tái)峻黍。
流平臺(tái)有三個(gè)關(guān)鍵的能力:
- 發(fā)布和訂閱記錄流复隆,類似于消息隊(duì)列或企業(yè)消息傳遞系統(tǒng)。
- 使用容錯(cuò)耐用的方式存儲(chǔ)記錄流姆涩。
- 記錄產(chǎn)生時(shí)處理數(shù)據(jù)挽拂。
Kafka主要是用在兩類應(yīng)用中:
- 在收數(shù)端和實(shí)時(shí)計(jì)算或批處理計(jì)算框架之間做數(shù)據(jù)通道
- 作為處理流式數(shù)據(jù)的應(yīng)用
為了解kafka怎么處理這些事情,需要先了解一下概念:
- Kafka是運(yùn)行在一臺(tái)或者多臺(tái)服務(wù)器的集群上的骨饿,并且可以擴(kuò)展到多個(gè)數(shù)據(jù)中心亏栈;
- Kafka集群以叫做topics的類別存儲(chǔ)流記錄;
- 每個(gè)記錄都由key宏赘,value绒北,timestamp組成;
Kafka有4個(gè)核心API:
- Producer API : 應(yīng)用程序發(fā)布流記錄到一個(gè)或者多個(gè)Kafka topics;
- Consumer API : 應(yīng)用程序訂閱一個(gè)或者多個(gè)topics并且處理產(chǎn)生的數(shù)據(jù)察署;
- Streams API : 應(yīng)用程序扮演著流處理器的角色闷游,從一個(gè)或者多個(gè)輸入流中消費(fèi)數(shù)據(jù)并且將產(chǎn)生的數(shù)據(jù)輸出到一個(gè)或者多個(gè)topic中。
- Connector API:構(gòu)建并且運(yùn)行將Kafka topic連接到現(xiàn)有應(yīng)用程序或數(shù)據(jù)系統(tǒng)的可重用生產(chǎn)者或消費(fèi)者。 例如脐往,關(guān)系數(shù)據(jù)庫(kù)的連接器可能捕獲對(duì)表的每個(gè)更改俱济。
在Kafka中,客戶端和服務(wù)器之間的通信是通過(guò)簡(jiǎn)單钙勃,高性能,語(yǔ)言無(wú)關(guān)的TCP協(xié)議完成的聂喇。 此協(xié)議已版本化并保持與舊版本的向后兼容性辖源。 我們?yōu)镵afka提供Java客戶端,但客戶端有多種語(yǔ)言版本希太。
Topics and Logs
首先我們先了解一下kafka記錄流提供的核心抽象-topic克饶。
Topic 是發(fā)布記錄的類別或訂閱源名稱。kafka中topic 可以有多個(gè)訂閱者誊辉, 即可以有0個(gè)矾湃,1個(gè)或者多個(gè)消費(fèi)者訂閱。
對(duì)于每一個(gè)topic堕澄,Kafka 的集群都會(huì)維護(hù)著如下圖這樣的分區(qū)log:
每個(gè)分區(qū)都是有序的邀跃、不可更高的記錄序列,這些記錄都是持續(xù)的被追加到結(jié)構(gòu)化的commit log中蛙紫。分區(qū)中的每個(gè)記錄都會(huì)打上本分區(qū)唯一的被稱為offset的序列id拍屑。
Kafka集群負(fù)責(zé)將所有發(fā)布的記錄(無(wú)論是否消費(fèi))持久化,這些記錄都是有一個(gè)配置的保留時(shí)間坑傅。例如僵驰,如果保留時(shí)間設(shè)置的是兩天,那么記錄發(fā)布之后兩天內(nèi)是可以消費(fèi)的唁毒,兩天之后就會(huì)被清除來(lái)事放空間蒜茴。Kafka的性能在數(shù)據(jù)大小方面實(shí)際上是恒定的,因此長(zhǎng)時(shí)間存儲(chǔ)數(shù)據(jù)不是問(wèn)題浆西。
實(shí)際上粉私,每個(gè)消費(fèi)者保留的唯一元數(shù)據(jù)是該消費(fèi)者在log中的偏移量或位置。偏移量是由消費(fèi)者來(lái)控制的:通常消費(fèi)者在讀取記錄的時(shí)候會(huì)線性的推進(jìn)其偏移量室谚,但是實(shí)際上毡鉴,既然消費(fèi)者控制著消費(fèi)的位置,就可以以任意順序來(lái)消費(fèi)記錄秒赤。例如消費(fèi)者可以重新設(shè)置偏移量來(lái)重新處理消費(fèi)過(guò)的數(shù)據(jù)或者跳過(guò)最近的記錄從頭最新位置開(kāi)始消費(fèi)猪瞬。
這些特性的結(jié)合就意味著Kafka消費(fèi)者是非常cheap的,消費(fèi)者的來(lái)去對(duì)于集群或者其他消費(fèi)者沒(méi)有太多影響入篮。例如陈瘦,可以使用命令行工具來(lái)查看任何一個(gè)topic中的內(nèi)容而不會(huì)對(duì)其他消費(fèi)者消費(fèi)的內(nèi)容產(chǎn)生影響。
日志中的分區(qū)有多種用途潮售。首先痊项,它們?cè)试S日志擴(kuò)展到超出單個(gè)服務(wù)器的大小锅风。 每個(gè)單獨(dú)的分區(qū)必須有托管它的服務(wù)器,但topic可能有許多分區(qū)鞍泉,因此它可以處理任意數(shù)量的數(shù)據(jù)皱埠。 其次,最重要的一點(diǎn)是它們充當(dāng)了并行性的單位 咖驮。
Distribution(分布式)
log分區(qū)分布在kafka集群的服務(wù)器上边器,每個(gè)服務(wù)器處理數(shù)據(jù)并請(qǐng)求分區(qū)的共享。每個(gè)分區(qū)在服務(wù)器上都有配置的副本數(shù)量來(lái)容錯(cuò)托修。
每個(gè)分區(qū)都有一個(gè)服務(wù)器扮演者leader的角色忘巧,0個(gè)或者多個(gè)服務(wù)器扮演者followers的角色。leader處理這個(gè)分區(qū)的所有讀寫請(qǐng)求睦刃,follower被動(dòng)的復(fù)制leader的數(shù)據(jù)砚嘴。如果leader崩潰了,其中的follwers就會(huì)自動(dòng)變成新的leader涩拙。每個(gè)服務(wù)器都充當(dāng)其某些分區(qū)的領(lǐng)導(dǎo)者和其他服務(wù)器的追隨者际长,因此負(fù)載在群集中得到很好的平衡。
異地?cái)?shù)據(jù)同步
Kafka MirrorMaker 為集群提供了異地?cái)?shù)據(jù)同步工具吃环。使用MirrorMaker,消息可以跨多個(gè)數(shù)據(jù)中心或者云進(jìn)行復(fù)制同步也颤。也可以使用主/被的方式來(lái)備份或者恢復(fù)數(shù)據(jù);或者主/主的方式來(lái)是數(shù)據(jù)更加靠近用戶郁轻。
Producers(生產(chǎn)者)
生產(chǎn)者發(fā)布選擇的數(shù)據(jù)到topic中翅娶。消費(fèi)者負(fù)責(zé)選擇記錄分配到topic的那個(gè)分區(qū)中『梦ǎ可以使用round-robin方式簡(jiǎn)單的進(jìn)行負(fù)載均衡或者使用語(yǔ)義分區(qū)函數(shù)來(lái)做竭沫。
Consumers(消費(fèi)者)
消費(fèi)者通過(guò)consumer group name來(lái)標(biāo)記,每條記錄都會(huì)發(fā)布到topic中后會(huì)被投遞到訂閱使用者組中一個(gè)消費(fèi)者實(shí)例骑篙。消費(fèi)實(shí)例可以在單獨(dú)的進(jìn)程中或者在單獨(dú)的機(jī)器上蜕提。
如果所有消費(fèi)者都有同樣的消費(fèi)組,那么記錄將有效地在消費(fèi)者實(shí)例上進(jìn)行負(fù)載平衡靶端;
如果所有的消費(fèi)者有不同的消費(fèi)組谎势,那么每條記錄都會(huì)廣播到所有的消費(fèi)者實(shí)例上;
有四個(gè)分區(qū)(P0-P3)的Kafka 集群杨名,集群有兩臺(tái)服務(wù)器脏榆,有兩個(gè)消費(fèi)組。消費(fèi)組A有兩個(gè)消費(fèi)者實(shí)例台谍,消費(fèi)組B有4個(gè)消費(fèi)實(shí)例须喂。
然而,更常見(jiàn)的是,我們發(fā)現(xiàn)主題具有少量的消費(fèi)者群體坞生,每個(gè)“邏輯訂閱者”一個(gè)仔役。 每個(gè)組由許多用于可伸縮性和容錯(cuò)的消費(fèi)者實(shí)例組成。 這只不過(guò)是發(fā)布 - 訂閱語(yǔ)義是己,其中訂閱者是消費(fèi)者群集而不是單個(gè)進(jìn)程又兵。
Kafka實(shí)現(xiàn)的消費(fèi)方式是在消費(fèi)者實(shí)例上劃分日志中的分區(qū)以便于每個(gè)實(shí)例在任何時(shí)間點(diǎn)都是每個(gè)分區(qū)公平的獨(dú)占消費(fèi)者。維護(hù)組中成員資格的過(guò)程由Kafka協(xié)議動(dòng)態(tài)處理卒废。 如果新實(shí)例加入該組寒波,他們將從該組的其他成員接管一些分區(qū); 如果實(shí)例死亡,其分區(qū)將分發(fā)給其余實(shí)例升熊。
Kafka只能保證每個(gè)分區(qū)的記錄數(shù)是有序的,不同分區(qū)之間不保證有序绸栅。每個(gè)有序的分區(qū)加上使用key分區(qū)的能力對(duì)于大部分應(yīng)用是足夠的级野。然而,你需要總體有序的話可以使用一個(gè)分區(qū)的topic粹胯。這就意味著每個(gè)消費(fèi)組只有一個(gè)消費(fèi)進(jìn)程蓖柔。
多租戶
可以將Kafka部署為多租戶解決方案。多租戶通過(guò)配置哪些topic可以生產(chǎn)或者消費(fèi)數(shù)據(jù)來(lái)啟用风纠。也可以選擇是否支持配額况鸣。管管理員可以定義和強(qiáng)制執(zhí)行配額,以控制客戶端使用的代理資源竹观。
Guarantees(高可用)
高級(jí)別的Kafka提供了如下的保證:
由生產(chǎn)者生產(chǎn)的消息發(fā)送到指定分區(qū)并且消息順序是發(fā)送的順序镐捧。這就意味著如果同一個(gè)生產(chǎn)者發(fā)送了兩條記錄M1,M2臭增,M1先發(fā)送懂酱,那么在log中M1就會(huì)有一個(gè)比M2更小的偏移量。
一個(gè)消費(fèi)者看見(jiàn)記錄的順序是在log中存儲(chǔ)的順序誊抛;
對(duì)于一個(gè)有N個(gè)副本的topic列牺,可以允許有N-1個(gè)服務(wù)器崩潰而不丟失任何數(shù)據(jù)。
Kafka 作為一個(gè)消息系統(tǒng)
Kafka 的流概念與傳統(tǒng)企業(yè)消息系統(tǒng)相比如何拗窃?
傳統(tǒng)消息系統(tǒng)有兩種模式:隊(duì)列和發(fā)布訂閱瞎领。在隊(duì)列模式中,許多消費(fèi)者從服務(wù)讀取數(shù)據(jù)随夸,每條記錄都流向消費(fèi)者之一九默;在發(fā)布訂閱模式下數(shù)據(jù)會(huì)廣播到所有消費(fèi)者那里。這兩種模式都有好處和壞處逃魄。隊(duì)列的好處是可以把處理數(shù)據(jù)的壓力分散到多個(gè)消費(fèi)者實(shí)例上荤西,這就可以擴(kuò)展處理能力。然而隊(duì)列不是多訂閱的,一旦數(shù)據(jù)被讀取了數(shù)據(jù)就沒(méi)邪锌。發(fā)布訂閱可以將數(shù)據(jù)廣播到所有的消費(fèi)者那里勉躺,缺點(diǎn)就是沒(méi)有辦法擴(kuò)展處理能力由于消息會(huì)廣播到每個(gè)訂閱者那里。
Kafka 消費(fèi)組的概念綜合了這兩個(gè)概念觅丰。消費(fèi)組作為隊(duì)列來(lái)看是可以把處理能力分散到多個(gè)進(jìn)程上饵溅,作為發(fā)布訂閱,可以將數(shù)據(jù)廣播到多個(gè)消費(fèi)組妇萄。
Kafka 相比于傳統(tǒng)的消息系統(tǒng)的另一個(gè)優(yōu)勢(shì)是有更好的順序保證蜕企。
傳統(tǒng)隊(duì)列在服務(wù)器上按照順序保存記錄,如果消費(fèi)者從隊(duì)列中消費(fèi)數(shù)據(jù)的時(shí)候冠句,服務(wù)器會(huì)按照存儲(chǔ)的順序提供記錄轻掩。雖然服務(wù)器按照順序分發(fā)記錄,但是記錄是異步的傳遞到消費(fèi)者那里的懦底,因此可能到達(dá)消費(fèi)者的時(shí)候是亂序的唇牧。這就意味著在并行處理的消費(fèi)上記錄是亂序的。消息傳遞系統(tǒng)通常通過(guò)具有“獨(dú)占消費(fèi)者”的概念來(lái)解決這個(gè)問(wèn)題聚唐,該概念只允許一個(gè)進(jìn)程從隊(duì)列中消耗丐重,但這當(dāng)然意味著處理中沒(méi)有并行性。
Kafka在這方面做的會(huì)更好杆查。通過(guò)在topic中提出了一個(gè)parallelism—the partition—within 的概念 扮惦,Kafka 能夠在消費(fèi)者流程池中提供訂購(gòu)保證和負(fù)載平衡。這是通過(guò)將topic中的分區(qū)分配給使用者組中的使用者來(lái)實(shí)現(xiàn)的亲桦,以便每個(gè)分區(qū)僅由該組中的一個(gè)使用者使用崖蜜。 通過(guò)這樣做,我們確保使用者是該分區(qū)的唯一讀者并按順序使用數(shù)據(jù)客峭。 由于有許多分區(qū)纳猪,這仍然可以讓許多消費(fèi)者實(shí)例的實(shí)現(xiàn)負(fù)載均衡。 但請(qǐng)注意桃笙,消費(fèi)者組中的消費(fèi)者實(shí)例不能超過(guò)分區(qū)氏堤。
Kafka 作為存儲(chǔ)系統(tǒng)
任何允許發(fā)布與消費(fèi)消息分離的消息隊(duì)列實(shí)際上充當(dāng)了正在進(jìn)行的消息的存儲(chǔ)系統(tǒng)。 Kafka的不同之處在于它是一個(gè)非常好的存儲(chǔ)系統(tǒng)搏明。
寫入Kafka的數(shù)據(jù)都寫入磁盤并且都有備份用來(lái)做容錯(cuò)鼠锈。Kafka允許生產(chǎn)者等待確認(rèn)消息以便于副本寫入的完整性來(lái)確保數(shù)據(jù)仍然存在及時(shí)寫入服務(wù)器宕機(jī)。
Kafka很好的使用了磁盤的接口 -- 在服務(wù)器上不論是寫入50KB還是50TB的數(shù)據(jù)星著,效率都是一樣的购笆。
由于是存儲(chǔ)系統(tǒng),允許客戶端控制其讀取位置虚循,可以將Kafka視為一種專用于高性能同欠,低延遲提交日志存儲(chǔ)样傍,復(fù)制和傳播的專用分布式文件系統(tǒng)
Kafka 作為流處理系統(tǒng)
只有讀,寫铺遂,以及存儲(chǔ)流數(shù)據(jù)還是不夠的衫哥,目的是實(shí)現(xiàn)流的實(shí)時(shí)處理。
Kafka 的流處理器是從輸入topic的獲取流數(shù)據(jù)襟锐,在輸入中執(zhí)行一些處理操作撤逢,最后將處理結(jié)果輸出到topic中。
例如粮坞,零售應(yīng)用可能會(huì)將銷量以及出貨量作為輸入流蚊荣,然后將重新排序以及價(jià)格調(diào)整以后的數(shù)據(jù)輸出到topic中。
直接使用生產(chǎn)者或者消費(fèi)者API就可以做一些簡(jiǎn)單的處理莫杈。然后對(duì)于復(fù)雜的變換處理互例,kafka 提供了提供了一整套集成的Stream API。這就可以構(gòu)建計(jì)算流的聚合或者流join這樣不一般的應(yīng)用筝闹。
這總便利幫助我們解決了這類應(yīng)用面對(duì)的難題:處理亂序數(shù)據(jù)敲霍,代碼變動(dòng)需要重新處理,執(zhí)行有狀態(tài)的計(jì)算等等丁存。
流API建立在Kafka提供的核心原語(yǔ)上:使用生產(chǎn)者消費(fèi)者API作為輸入,使用Kafka作為有狀態(tài)的存儲(chǔ)柴我,在流處理實(shí)例間使用相同組的機(jī)制進(jìn)行容錯(cuò)解寝。
總結(jié)
將消息,存儲(chǔ)以及流處理結(jié)合起來(lái)看似不是很常見(jiàn)艘儒,但是對(duì)于Kafka這種角色的流處理平臺(tái)十分重要的聋伦。
像HDFS這樣的分布式文件系統(tǒng)存儲(chǔ)靜態(tài)文件進(jìn)行批處理。這樣的系統(tǒng)允許存儲(chǔ)和處理過(guò)去的歷史數(shù)據(jù)界睁。
傳統(tǒng)的企業(yè)級(jí)消息系統(tǒng)可以處理訂閱以后即將到來(lái)的消息觉增,應(yīng)用內(nèi)建這個(gè)方式來(lái)處理即將到來(lái)的數(shù)據(jù)。
Kafka 將這些能力都融合進(jìn)來(lái)翻斟,同時(shí)這種組合對(duì)于Kafka作為流媒體應(yīng)用程序平臺(tái)以及流數(shù)據(jù)管道的使用至關(guān)重要逾礁。
通過(guò)組合存儲(chǔ)和低延遲訂閱,流應(yīng)用程序可以以相同的方式處理過(guò)去和未來(lái)的數(shù)據(jù)访惜。 也就是說(shuō)嘹履,單個(gè)應(yīng)用程序可以處理歷史存儲(chǔ)的數(shù)據(jù),而不是在它到達(dá)最后一條記錄時(shí)結(jié)束债热,它可以在未來(lái)數(shù)據(jù)到達(dá)時(shí)繼續(xù)處理砾嫉。 這是包含批處理以及消息驅(qū)動(dòng)應(yīng)用程序的流處理的一般概念。
同樣窒篱,對(duì)于流數(shù)據(jù)流水線焕刮,訂閱實(shí)時(shí)事件的組合使得可以將Kafka用于極低延遲的流水線; 但是舶沿,能夠可靠地存儲(chǔ)數(shù)據(jù)使得可以將其用于必須保證數(shù)據(jù)傳輸?shù)年P(guān)鍵數(shù)據(jù),或者與僅定期加載數(shù)據(jù)或可能長(zhǎng)時(shí)間停機(jī)以進(jìn)行維護(hù)的離線系統(tǒng)集成配并。 流處理設(shè)施可以在數(shù)據(jù)到達(dá)時(shí)對(duì)其進(jìn)行轉(zhuǎn)換括荡。
<a >點(diǎn)擊該鏈接,獲取博客解鎖驗(yàn)證碼</a>