Kafka 基礎概念及架構
一、Kafka 介紹
Kafka是⼀個分散式、分區的、多副本的、多⽣產者、多訂閱者,基於zookeeper協調的分散式⽇志系統(也可以當做MQ系統),常⻅可以⽤於web/nginx⽇志、訪問⽇志,消息服務等等。
Kafka主要應⽤場景:⽇志收集系統和消息系統
Kafka主要設計目標:
- 以時間複雜度為O(1)的⽅式提供消息持久化能⼒,即使對TB級以上數據也能保證常數時間的訪問性能。
- ⾼吞吐率。即使在⾮常廉價的商⽤機器上也能做到單機⽀持每秒100K條消息的傳輸。
- ⽀持Kafka Server間的消息分區,及分散式消費,同時保證每個partition內的消息順序傳輸。
- 同時⽀持離線數據處理和實時數據處理。
- ⽀持在線⽔平擴展
Kafka消息傳遞模式:發布-訂閱模式(不支援點對點模式)
Kafka消息推拉模式:Kafka只有消息的拉取,沒有推送,可以通過輪詢實現消息的推送
- Kafka在⼀個或多個可以跨越多個數據中⼼的伺服器上作為集群運⾏。
- Kafka集群中按照主題分類管理,⼀個主題可以有多個分區,⼀個分區可以有多個副本分區。
- 每個記錄由⼀個鍵,⼀個值和⼀個時間戳組成。
Kafka 的 4 個核心 API:
Producer API
:允許應⽤程式將記錄流發布到⼀個或多個Kafka主題。Consumer API
:允許應⽤程式訂閱⼀個或多個主題並處理為其⽣成的記錄流。Streams API
:允許應⽤程式充當串流處理器,使⽤⼀個或多個主題的輸⼊流,並⽣成⼀個或多個輸出主題的輸出流,從⽽有效地將輸⼊流轉換為輸出流。Connector API
:允許構建和運⾏將Kafka主題連接到現有應⽤程式或數據系統的可重⽤⽣產者或使⽤者。例如,關係資料庫的連接器可能會捕獲對錶的所有更改。
二、Kafka 優勢
⾼吞吐量:單機每秒處理⼏⼗上百萬的消息量。即使存儲了許多TB的消息,它也保持穩定的性能。
⾼性能:單節點⽀持上千個客戶端,並保證零停機和零數據丟失。
持久化數據存儲:將消息持久化到磁碟。通過將數據持久化到硬碟以及replication防⽌數據丟失。
- 零拷貝
- 順序讀,順序寫
- 利⽤Linux的⻚快取
分散式系統:易於向外擴展。所有的Producer、Broker和Consumer都會有多個,均為分散式的。⽆需停機即可擴展機器。多個Producer、Consumer可能是不同的應⽤。
可靠性:Kafka是分散式,分區,複製和容錯的。
客戶端狀態維護:消息被處理的狀態是在Consumer端維護,⽽不是由server端維護。當失敗時能⾃動平衡。
⽀持online和offline的場景
⽀持多種客戶端語⾔:Kafka⽀持Java、.NET、PHP、Python等多種語⾔。
三、Kafka 應用場景
⽇志收集:⼀個公司可以⽤Kafka可以收集各種服務的Log,通過Kafka以統⼀接⼝服務的⽅式開放給各種Consumer;
消息系統:解耦⽣產者和消費者、快取消息等;
⽤戶活動跟蹤:Kafka經常被⽤來記錄Web⽤戶或者App⽤戶的各種活動,如瀏覽⽹⻚、搜索、點擊等活動,這些活動資訊被各個伺服器發布到Kafka的Topic中,然後消費者通過訂閱這些Topic來做實時的監控分析,亦可保存到資料庫;
運營指標:Kafka也經常⽤來記錄運營監控數據。包括收集各種分散式應⽤的數據,⽣產各種操作的集中回饋,⽐如報警和報告;
流式處理:⽐如Spark Streaming和Storm。
四、Kafka 基本架構
消息和批次
消息:
- Kafka 的數據單元稱為消息。消息可以看做資料庫表的一條「行記錄」,消息由位元組數組組成。
- 消息有鍵,鍵也是一個位元組數組。當消息需要寫入不同的分區時,會使用鍵進行分區。
批次:
- 消息可以分批寫入Kafka,一批次消息屬於同一個主題和分區。
- 分批次寫入消息可以減少網路開銷。批次越大,單位時間處理消息越多,單個消息傳輸時間越長;批次消息數據會被壓縮,這樣能提升傳輸和存儲能力,也需要更多的計算處理。
模式
- 消息模式(schema)有許多可⽤的選項,以便於理解。如JSON和XML,但是它們缺乏強類型處理能⼒
- Kafka 使用的 Apache Avro(了解即可)。
- 數據格式的⼀致性對Kafka很重要,因為它消除了消息讀寫操作之間的耦合性
主題和分區
- Kafka的消息通過主題進⾏分類。主題可⽐是資料庫的表或者⽂件系統⾥的⽂件夾
- 主題可以被分為若⼲分區,⼀個主題通過分區分布於Kafka集群中,提供了橫向擴展的能⼒
生產者和消費者
生產者:
- ⽣產者創建消息。⼀個消息被發布到⼀個特定的主題上,⽣產者在默認情況下把消息均衡地分布到主題的所有分區上
- 直接指定消息的分區
- 根據消息的key散列取模得出分區
- 輪詢指定分區
消費者:
- 消費者消費消息。消費者通過偏移量來區分已經讀過的消息
- 消費者是消費組的⼀部分。消費組保證每個分區只能被⼀個消費者使⽤,避免重複消費
broker和集群
- 一個獨立的Kafka伺服器稱為broker。
- broker接收來⾃⽣產者的消息,為消息設置偏移量,並提交消息到磁碟保存
- broker為消費者提供服務,對讀取分區的請求做出響應,返回已經提交到磁碟上的消息
- 單個broker可以輕鬆處理數千個分區以及每秒百萬級的消息量
- 每個集群都有⼀個broker是集群控制器(⾃動從集群的活躍成員中選舉出來,通過Zookeeper的Master選舉)控制器負責管理⼯作
- 將分區分配給broker
- 監控broker
- 集群中一個分區屬於一個 broker,該broker稱為分區首領
- 一個分區可以分配給多個broker,此時會發生分區複製。分區複製提供了消息冗餘和高可用。副本分區不負責處理消息的讀寫
五、Kafka 核心概念
5.1 生產者 Producer
生產者創建消息,將消息發布到主題(Topic)中。一般一個消息會被發布到指定的主題上,然後通過以下幾種方式發布到指定主題分區:
- 默認情況下通過輪詢把消息均衡地分布到主題的所有分區上
- 有時我們可以將消息指定發到某一個分區上。通常是通過消息鍵和分區器來實現的,分區器可以為消息鍵計算出一個散列值,通過這個散列值就可以映射到相應的分區上
- 也可以自定義分區器,我們可以根據不同的業務規則將消息映射到不同分區。
5.2 消費者 Consumer
消費者從主題中讀取消息
- 消費者可以訂閱一個或多個主題,並按照消息生成的順序讀取
- 消費者可以通過偏移量(Offset)區分已經讀取的消息
- 偏移量是另⼀種元數據,它是⼀個不斷遞增的整數值,在創建消息時,Kafka 會把它添加到消息⾥
- 在給定的分區⾥,每個消息的偏移量都是唯⼀的
- 消費者把每個分區最後讀取的消息偏移量保存在Zookeeper 或Kafka(現在是存在Kafka上的) 上,如果消費者關閉或重啟,它的讀取狀態不會丟失
- 消費者是消費組的一部分。消費組保證每個分區只能被一個消費者使用
- 如果某一個消費者失效,就會進行再平衡,重新給消費組中的消費者分配消費分區,以達到高可用的目的
5.3 伺服器 Broker
一個獨立的Kafka伺服器就是一個 Broker。Broker為消費者提供服務,對讀取分區的請求做出響應,返回已經提交到磁碟上的消息。
- 如果某topic有N個partition,集群有N個broker,那麼每個broker存儲該topic的⼀個partition
- 如果某topic有N個partition,集群有(N+M)個broker,那麼其中有N個broker存儲該topic的⼀個partition,剩下的M個broker不存儲該topic的partition數據
- 如果某topic有N個partition,集群中broker數⽬少於N個,那麼⼀個broker存儲該topic的⼀個或多個partition。在實際⽣產環境中,盡量避免這種情況的發⽣,這種情況容易導致Kafka集群數據不均衡
Broker 是集群的組成部分。每個集群都有⼀個broker 同時充當了集群控制器的⻆⾊(⾃動從集群的活躍成員中選舉出來):
- 控制器負責管理⼯作,包括將分區分配給broker 和監控broker
在集群中,⼀個分區從屬於⼀個broker,該broker 被稱為分區的⾸領
5.4 主題 Topic
每條發布到Kafka的消息都有一個類別,這個類別就是Topic。
5.5 分區 Partition
主題可以分為若干個分區,消息可以寫主題的某一個分區中。
消息以追加的方式寫入分區,然後以先進後出的方式被讀取。
Kafka 無法在整個主題範圍內保證消息的順序,但是可以保證消息在單個分區中的順序。
Kafka 通過分區實現數據冗餘和伸縮性。
在需要嚴格保證消息順序的情況下,需要將分區設置為 1 。
5.6 副本 Replicas
5.6.1 副本概念
消息被寫入主題,每個主題有多個分區,每個分區有多個副本。副本被保存在broker 上,每個broker 可以保存成百上千個屬於不同主題和分區的副本
副本有兩種類型:
- ⾸領副本:每個分區都有⼀個⾸領副本。為了保證⼀致性,所有⽣產者請求和消費者請求都會經過這個副本
- 跟隨者副本:⾸領以外的副本都是跟隨者副本。跟隨者副本不處理來⾃客戶端的請求,它們唯⼀的任務就是從⾸領那⾥複製消息,保持與⾸領⼀致的狀態。如果⾸領發⽣崩潰,其中的⼀個跟隨者會被提升為新⾸領
5.6.1 副本介紹
Kafka 通過副本保證高可用。副本分為⾸領副本(Leader)和跟隨者副本(Follower)。
跟隨者副本包括同步副本和不同步副本,在發⽣⾸領副本切換的時候,只有同步副本可以切換為⾸領副本。
AR
分區中的所有副本統稱為AR(Assigned Repllicas)。AR=ISR+OSR
ISR
- 所有與leader副本保持⼀定程度同步的副本(包括Leader)組成 ISR,ISR集合是AR集合中的⼀個⼦集。
- 消息會先發送到leader副本,然後follower副本才能從leader副本中拉取消息進⾏同步,同步期間內follower副本相對於leader副本⽽⾔會有⼀定程度的滯後。前⾯所說的「⼀定程度」是指可以忍受的滯後範圍,這個範圍可以通過參數進⾏配置
OSR
- 與leader副本同步滯後過多的副本(不包括Leader)組成 OSR。
- 在正常情況下,所有的follower副本都應該與leader副本保持⼀定程度的同步,即AR=ISR,OSR集合為空
HW
HW是High Watermak的縮寫, 俗稱⾼⽔位,它表示了⼀個特定消息的偏移量(offset),消費之只能拉取到這個offset之前的消息。
LEO
LEO是Log End Offset的縮寫,它表示了當前⽇志⽂件中下⼀條待寫⼊消息的offset。
5.7 偏移量 Offset
5.7.1 生產者 Offset
消息寫⼊的時候,每⼀個分區都有⼀個offset,這個offset就是⽣產者的offset,同時也是這個分區的最新最⼤的offset
有些時候沒有指定某⼀個分區的offset,這個⼯作kafka幫我們完成
5.7.2 消費者 Offset
這是某⼀個分區的offset情況,⽣產者寫⼊的offset是最新最⼤的值是12,⽽當Consumer A進⾏消費時,從0開始消費,⼀直消費到了9,消費者的offset就記錄在9,Consumer B就紀錄在了11。等下⼀次他們再來消費時,他們可以選擇接著上⼀次的位置消費,當然也可以選擇從頭消費,或者跳到最近的記錄並從「現在」開始消費。