Kafka概念與基本架構(gòu)

1. Kafka介紹

Kafka是最初由Linkedin公司開發(fā),是一個(gè)分布式分區(qū)的、多副本的、多生產(chǎn)者多訂閱者,基于zookeeper協(xié)調(diào)的分布式日志系統(tǒng)(也可以當(dāng)做MQ系統(tǒng)),常見(jiàn)可以用于web/nginx日志、訪問(wèn)日志,消息服務(wù)等等,Linkedin于2010年貢獻(xiàn)給了Apache基金會(huì)并成為頂級(jí)開源項(xiàng)目。

主要應(yīng)用場(chǎng)景:日志收集系統(tǒng)和消息系統(tǒng)

Kafka主要設(shè)計(jì)目標(biāo)如下:

  • 以時(shí)間復(fù)雜度為O(1)的方式提供消息持久化能力,即使對(duì)TB級(jí)以上數(shù)據(jù)也能保證常數(shù)時(shí)間的訪問(wèn)性能

  • 高吞吐率。即使在非常廉價(jià)的商用機(jī)器上也能做到單機(jī)支持每秒100K條消息的傳輸

  • 支持Kafka Server間的消息分區(qū),及分布式消息,同時(shí)保證每個(gè)partition內(nèi)的消息順序傳輸

  • 同時(shí)支持離線數(shù)據(jù)處理和實(shí)時(shí)數(shù)據(jù)處理

  • 支持在線水平擴(kuò)展


    image-20210312102002488.png

有兩種主要消息傳遞模式:點(diǎn)對(duì)點(diǎn)傳遞模式、發(fā)布-訂閱模式。大部分消息系統(tǒng)選用發(fā)布-訂閱模式。

Kafka就是一種發(fā)布-訂閱模式。

對(duì)消息中間件,消息分推拉兩種模式。Kafka只有消息的拉取,沒(méi)有推送,可以通過(guò)輪詢實(shí)現(xiàn)消息的推送

Kafka 特性:

Kafka在一個(gè)或多個(gè)可以跨越多個(gè)數(shù)據(jù)中心的服務(wù)器上作為集群運(yùn)行。

Kafka集群集群中按照主題分類管理,一個(gè)主題可以有多個(gè)分區(qū),一個(gè)分區(qū)可以有多個(gè)副本分區(qū)

每個(gè)記錄由一個(gè)鍵,一個(gè)值和一個(gè)時(shí)間戳組成

Kafka四個(gè)核心API

  • Producer API

    允許應(yīng)用程序?qū)⒂涗浟靼l(fā)布到一個(gè)或多個(gè)Kafka主題。

  • Consumer API

    允許應(yīng)用程序訂閱一個(gè)或多個(gè)主題并處理為其生成的記錄流

  • Streams API

    允許應(yīng)用程序充當(dāng)流處理器,使用一個(gè)或多個(gè)主題的輸入流,并生成一個(gè)或多個(gè)輸出主題的輸出流,從而有效地將輸入流換為輸出流

  • Connector API

    允許構(gòu)建和運(yùn)行將Kafka主題鏈接到現(xiàn)有應(yīng)用程序或數(shù)據(jù)系統(tǒng)的可重用生產(chǎn)者或使用者

    例如:關(guān)系數(shù)據(jù)庫(kù)的連接器可能會(huì)捕獲對(duì)表的所有更改

2. Kafka優(yōu)勢(shì)

  • 高吞吐量

    單機(jī)每秒處理幾十上百萬(wàn)的消息量。即使存儲(chǔ)了許多TB的消息,它也保持穩(wěn)定的性能。

  • 高性能

    單節(jié)點(diǎn)支持上千個(gè)客戶端,并保證零停機(jī)和零數(shù)據(jù)丟失。

  • 持久化數(shù)據(jù)存儲(chǔ)

    將消息持久化到磁盤,通過(guò)將數(shù)據(jù)持久化到硬盤以及replication防止數(shù)據(jù)丟失。

    • 零拷貝

    • 順序讀,順序?qū)?/p>

    • 利用Linux的也緩存

  • 分布式系統(tǒng),易于向外擴(kuò)展

    所有的Producer、Broker和Consumer都會(huì)有多個(gè),均為分布式的。無(wú)須停機(jī)即可擴(kuò)展機(jī)器。多個(gè)Producer、Consumer可能是不同的應(yīng)用。

  • 可靠性

    Kafka是分布式,分區(qū)、復(fù)制和容錯(cuò)的。

  • 客戶端狀態(tài)維護(hù)

    消息被處理的狀態(tài)是在Consumer端維護(hù),而不是由Server端維護(hù)。當(dāng)失敗時(shí)能自動(dòng)平衡

  • 支持online和offline的場(chǎng)景

  • 支持多種客戶端語(yǔ)言

    Kafka支持Java、.NET、PHP、Python等多種語(yǔ)言

3. Kafka應(yīng)用場(chǎng)景

  • 日志收集

    一個(gè)公司可以用Kafka收集各種服務(wù)的Log,通過(guò)Kafka以統(tǒng)一接口服務(wù)的方式開發(fā)給各種Consumer

  • 消息系統(tǒng)

    解耦生產(chǎn)者和消費(fèi)者、緩存消息等。

  • 用戶活動(dòng)跟蹤

    Kafka經(jīng)常被用來(lái)記錄Web用戶或者APP用戶的各種活動(dòng),如瀏覽網(wǎng)頁(yè),搜索,點(diǎn)擊等活動(dòng),這些活動(dòng)信息被各個(gè)服務(wù)發(fā)布到Kafka的Topic中,然后消費(fèi)者通過(guò)訂閱這些Topic來(lái)做實(shí)時(shí)的監(jiān)控分析,亦可保持到數(shù)據(jù)庫(kù)。

  • 運(yùn)營(yíng)指標(biāo)

    Kafka也經(jīng)常用來(lái)記錄運(yùn)營(yíng)監(jiān)控?cái)?shù)據(jù)。包括手機(jī)各種分布式應(yīng)用的數(shù)據(jù),生產(chǎn)各種操作集中反饋,比如報(bào)警和報(bào)告

  • 流失處理

    比如Spark Streaming 和Storm

4. 基本架構(gòu)

4.1 消息和批次

Kafka的數(shù)據(jù)單元稱為消息。可以把消息看成是數(shù)據(jù)庫(kù)里的一個(gè)數(shù)據(jù)行或一條記錄。消息由字節(jié)數(shù)組組成。

消息有鍵,鍵也是一個(gè)字節(jié)數(shù)組。當(dāng)消息以一種可控的方式寫入不同的分區(qū)時(shí),會(huì)用到鍵。

為了提高效率,消息被分批寫入Kafka。批次就是一組消息,這些消息屬于同一個(gè)主體和分區(qū)。

把消息分成批次可以減少網(wǎng)絡(luò)開銷。批次越大,單位時(shí)間內(nèi)處理的消息就越多,單個(gè)消息的傳輸時(shí)間就越長(zhǎng)。批次數(shù)據(jù)會(huì)被壓縮,這樣可以提升數(shù)據(jù)的傳輸和存儲(chǔ)能力,但是需要更多的計(jì)算處理。

4.2 模式

消息模式(schema)有許多可用的選項(xiàng),以便于理解。如JSON和XML,但是它缺乏強(qiáng)類型處理能力。Kafka的許多開發(fā)者喜歡使用Apache Avro。Avro提供了一種緊湊的序列化格式,模式和消息體分開。當(dāng)模式發(fā)生變化時(shí),不需要重新生成代碼,它還支持強(qiáng)類型和模式進(jìn)化,其版本即向前兼容,也向后兼容。

數(shù)據(jù)格式的一致性對(duì)Kafka很重要,因?yàn)樗讼⒆x寫操作之間的耦合性。

4.3 主體和分區(qū)

Kafka的消息通過(guò)主體進(jìn)行分類。主題可比是數(shù)據(jù)庫(kù)的表或者文件系統(tǒng)里的文件夾。主題可以被分為若干分區(qū),一個(gè)主題通過(guò)分區(qū)分布于Kafka集群中,提供了橫向擴(kuò)展的能力。


image-20210312110958520.png

4.4 生產(chǎn)者和消費(fèi)者

生產(chǎn)者創(chuàng)建消息。消費(fèi)者消費(fèi)消息。

一個(gè)消費(fèi)被發(fā)布到一個(gè)特定的主題上。

生產(chǎn)者在默認(rèn)情況下把消息均衡地分布到主題的所有分區(qū)上:

1. 直接指定消息的分區(qū)

2. 根據(jù)消息的key散列取模得出分區(qū)

3. 輪詢指定分區(qū)

消費(fèi)者通過(guò)偏移量來(lái)區(qū)分已經(jīng)讀過(guò)的消息,從而消費(fèi)消息。

消費(fèi)者是消費(fèi)組的一部分。消費(fèi)組保證每個(gè)分區(qū)只能被一個(gè)消費(fèi)者使用,避免重復(fù)消費(fèi)。

image-20210312111420527.png

4.5 Broker和集群

一個(gè)獨(dú)立的Kafka服務(wù)器稱為broker。broker接收來(lái)自生產(chǎn)者的消息,為消息設(shè)置偏移量,并提交消息到磁盤保存。broker為消費(fèi)者提供服務(wù),對(duì)讀取分區(qū)的請(qǐng)求作出響應(yīng),返回已經(jīng)提交到磁盤上的消息。單個(gè)broker可以輕松處理數(shù)千個(gè)分區(qū)以及每秒百萬(wàn)級(jí)的消息量

image-20210312111655113.png

每個(gè)集群都有一個(gè)broker是集群控制器(自動(dòng)從集群的活躍成員中選舉處理)

控制器負(fù)責(zé)管理工作:

  • 將分區(qū)分配給broker

  • 監(jiān)控broker

集群中一個(gè)分區(qū)屬于一個(gè)broker,該broker稱為分區(qū)首領(lǐng)

一個(gè)分區(qū)可以分配給多個(gè)broker,此時(shí)會(huì)發(fā)送分區(qū)復(fù)制。

分區(qū)復(fù)制提供了消息冗余,高可用。副本分區(qū)不負(fù)責(zé)處理消息的讀寫。

4.6 核心概念

4.6.1 Producer

生產(chǎn)者創(chuàng)建消息。

該角色將消息發(fā)布到Kafka的Topic中。broker接收到生產(chǎn)者發(fā)送的消息后,broker將該消息追加到當(dāng)前用于追加數(shù)據(jù)的segment文件中。

一般情況下,一個(gè)消息會(huì)被發(fā)布到一個(gè)特定的主題上。

  1. 默認(rèn)情況下通過(guò)輪詢把消息均衡地分布到主題的所有分區(qū)上。

  2. 在某些情況下,生產(chǎn)者會(huì)把消息直接寫到指定的分區(qū)。這通常是通過(guò)消息鍵和分區(qū)器來(lái)實(shí)現(xiàn)的,分區(qū)器為鍵生成一個(gè)散列值,并將其映射到指定的分區(qū)上。這樣可以保證包含同一個(gè)鍵的消息會(huì)被寫到同一分區(qū)上。

  3. 生產(chǎn)者也可以使用自定義的分區(qū)器,根據(jù)不同的業(yè)務(wù)規(guī)則將消息映射到分區(qū)

4.6.2 Consumer

消費(fèi)者讀取消息。

  1. 消費(fèi)者訂閱一個(gè)或多個(gè)主題,并按照消息生成的順序讀取它們。

  2. 消費(fèi)者通過(guò)檢查消息的偏移量來(lái)區(qū)分已經(jīng)讀取過(guò)的消息。偏移量是另一種元數(shù)據(jù),它是一個(gè)不斷遞增的整數(shù)值,在創(chuàng)建消息時(shí),Kafka 會(huì)把它添加到消息里。在給定的分區(qū)里,每個(gè)消息的偏移量都是唯一的。消費(fèi)者把每個(gè)分區(qū)最后讀取的消息偏移量保存在Zookeeper或Kafka上,如果消費(fèi)者關(guān)閉或重啟,它的讀取狀態(tài)不會(huì)丟失。

  3. 消費(fèi)者是消費(fèi)組的一部分。群組保證每個(gè)分區(qū)只能被一個(gè)消費(fèi)者使用。

  4. 如果一個(gè)消費(fèi)者失效,消費(fèi)組里的其他消費(fèi)者可以接管失效消費(fèi)者的工作,再平衡,分區(qū)重新分配。

image-20210312120104284.png

4.6.3 Broker

一個(gè)獨(dú)立的Kafka服務(wù)器被稱為broker

broker 為消費(fèi)者提供服務(wù),對(duì)讀取分區(qū)的請(qǐng)求作出響應(yīng),返回已經(jīng)提交到磁盤上的消息。

  1. 如果topic有N個(gè)partition,集群有N個(gè)broker,那么每個(gè)broker存儲(chǔ)該topic的一個(gè)partition。

  2. 如果topic有N個(gè)partition,集群有(N+M)個(gè)broker,那么其中有N個(gè)broker存儲(chǔ)該topic的一個(gè)partition,剩下的M個(gè)broker不存儲(chǔ)該topic的partition數(shù)據(jù)。

  3. 如果某個(gè)topic有N個(gè)partition,集群中broker數(shù)目少于N個(gè),那么一個(gè)broker存儲(chǔ)該topic的一個(gè)或多個(gè)partition。在實(shí)際生產(chǎn)環(huán)境中,盡量避免這種情況的發(fā)送,這種情況容易導(dǎo)致Kafka集群數(shù)據(jù)不均衡。

broker是集群的組成部分。每個(gè)集群都有一個(gè)broker同時(shí)充當(dāng)集群控制器的角色(自動(dòng)從集群的活躍成員中選舉出來(lái))。

控制器復(fù)制管理工作,包括將分區(qū)分配給broker和監(jiān)控broker

在集群中,一個(gè)分區(qū)從屬于一個(gè)broker,該broker被稱為分區(qū)的首領(lǐng)。

image-20210312120822076.png

4.6.4 Topic

每條發(fā)布到Kafka集群的消息都有一個(gè)類別,這個(gè)類別被稱為一個(gè)Topic

物理上不同Topic的消息分開存儲(chǔ)。

主題就好比數(shù)據(jù)庫(kù)的表,尤其是分庫(kù)分表之后的邏輯表。

4.6.5 Partition

主題可以被分為若干個(gè)分區(qū),一個(gè)分區(qū)就是一個(gè)提交日志。

消息以追加的方式寫入分區(qū),然后以先入先出的順序讀取。

無(wú)法在整個(gè)主題范圍內(nèi)保證消息的順序,但可以保證消息在單個(gè)分區(qū)內(nèi)的順序。

Kafka通過(guò)分區(qū)來(lái)實(shí)現(xiàn)數(shù)據(jù)冗余和伸縮性。

在需要嚴(yán)格保證消息的消費(fèi)順序的場(chǎng)景下,需要將partition數(shù)目設(shè)為1

image-20210312134028017.png

4.6.6 Replicas

Kafka 使用主題來(lái)組織數(shù)據(jù),每個(gè)主題被分為若干個(gè)分區(qū),每個(gè)分區(qū)有多個(gè)副本。那些副本被保存在broker上,每個(gè)broker可以保存成百上千個(gè)屬于不同主題和分區(qū)的副本。

副本有兩種類型

  • 首領(lǐng)副本

    每個(gè)分區(qū)都有一個(gè)首領(lǐng)副本。為了保證一致性,所有生產(chǎn)者請(qǐng)求和消費(fèi)者請(qǐng)求都會(huì)經(jīng)過(guò)這個(gè)副本。

  • 跟隨者副本

    首領(lǐng)意外的副本都是跟隨者副本。跟隨者副本不處理來(lái)自客戶端的請(qǐng)求,他們唯一的任務(wù)就是從首領(lǐng)那里復(fù)制消息,保持與首領(lǐng)一直的狀態(tài)。如果首領(lǐng)發(fā)生崩潰,其中的一個(gè)跟隨者會(huì)被提升為新首領(lǐng)。

4.6.7 Offset

4.6.7.1 生產(chǎn)者Offset

消息寫入的時(shí)候,每一個(gè)分區(qū)都有一個(gè)Offset,這個(gè)Offset就是生產(chǎn)者的Offset,同時(shí)也是這個(gè)分區(qū)的最新最大的offset。

有些時(shí)候沒(méi)有指定某一個(gè)分區(qū)的offset,這個(gè)工作kafka幫我們完成。

image-20210312134601962.png
4.6.7.2 消費(fèi)者offset
image-20210312135427705.png

這是某一個(gè)分區(qū)的offset情況,生產(chǎn)者寫入的offset是最新最大的值是12,而當(dāng)Consumer A進(jìn)行消費(fèi)時(shí),從0開始消費(fèi),一直消費(fèi)到9,消費(fèi)者的offset就記錄在9,Consumer B就記錄在11。等下一次他們?cè)賮?lái)消費(fèi)時(shí),他們可以選擇接著上一次的位置消費(fèi),當(dāng)然也可以選擇從頭消費(fèi),或者跳到最近的記錄從“現(xiàn)在”開始消費(fèi)。

4.8 副本

Kafka 通過(guò)副本保證高可用。副本分為首領(lǐng)副本(Leader)和跟隨者副本(Follower)。

跟隨者副本包括同步副本和不同步副本,在發(fā)生首領(lǐng)副本切換的時(shí)候,只有同步副本可以切換為首領(lǐng)副本。

4.8.1 AR

分區(qū)中的所有副本統(tǒng)稱為AR(Assigned Replicas)

AR=ISR + OSR

4.8.1.1 ISR

所有與leader副本保持一定程度同步的副本(包括Leader)組成ISR(In-Sync Replicas),ISR集合是AR集合中的一個(gè)子集。消息會(huì)先發(fā)送到leader副本,然后follower副本才能從leader副本中拉取消息進(jìn)行同步,同步期間內(nèi)follower副本相對(duì)于leader副本而言會(huì)有一定程度的滯后。前面所說(shuō)的“一定程度”是指可以忍受的滯后范圍,這個(gè)范圍可以通過(guò)參數(shù)進(jìn)行配置。

4.8.1.2 OSR

與leader副本同步滯后過(guò)多的副本(不包括leader)副本,組成OSR(Out-Sync Replicas)。在正常情況下,所有的follower副本都應(yīng)該與leader副本保持一定程度的同步,即AR=ISR,OSR集合為空

4.8.2 HW

HW是High Watermak的縮寫,俗稱高水位,它表示了一個(gè)特定消息的偏移量(offset),消費(fèi)者只能拉取到這個(gè)offset之前的消息。

4.8.3 LEO

LEO是 Log End Offset的縮寫,它表示了當(dāng)前日志文件中下一條待寫入消息的offset


image-20210312142439994.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容