聊聊 Kafka: Kafka 的基礎架構

一、我與快遞小哥的故事

一個很正常的一個工作日,老周正在忙着啪啪啪的敲代碼,辦公司好像安靜的只剩敲代碼的聲音。突然,我的電話鈴聲響起了,頓時打破了這種安靜。

我:喂,哪位?
快遞小哥:我是順豐快遞的,你有個包裹,請問你現在在家嗎?
我:哦,我現在不在家,晚上你再幫我送過來吧。
快遞小哥:要不我幫你放在菜鳥驛站吧?
我:可以可以,謝謝了。

還好有菜鳥驛站,不然工作日加班到很晚纔回家,晚上快遞小哥又下班了,得等到週末我在家快遞小哥才能幫我送了。如果沒有菜鳥驛站的話,我們來看下快遞小哥與我的交互圖:


要是有菜鳥驛站的話,我們再來看下交互圖:


上面故事中的菜鳥驛站就是消息隊列,也就是我們本篇要講的 Kafka;而快遞小哥就是生產者,老周就是消費者。老週一直很忙沒去菜鳥驛站取快遞,就是消息積壓。我給快遞小哥發消息說,確認快遞已經取到了,就是 ACK 機制。

小夥伴們可能發現了菜鳥驛站的好處了,真香。

這裏老周來總結幾點消息隊列的好處也就是使用場景:

我與快遞小哥的故事是真實發生的哈,正好我有個讀者前段時間面試順豐的時候被問到 Kafka 了,要我出 Kafka 的內容,所以有了靈感寫了這篇文章。

二、Kafka 介紹

Kafka 是最初由 Linkedin 公司開發,是一個 分佈式、分區的、多副本的、多生產者、多訂閱者,基於 zookeeper 協調的分佈式消息系統。常見可以用於 web/nginx 日誌、訪問日誌,消息服務等。

Linkedin 於 2010 年貢獻給了 Apache 基金會併成爲頂級開源項目。

2.1 基於 zookeeper 協調

這裏老周要提一下,Kafka 2.8.0 版本實現了 Raft 分佈式一致性機制,意味着可以脫離 ZooKeeper 獨立運行了。

ZooKeeper 在 Kafka 中扮演着重要的角色,用來存儲 Kafka 的元數據。ZooKeeper 存儲着 Partition 和 Broker 的元數據 ,同時也負責 Kafka Controller 的選舉工作。

對於 Kafka 來講,ZooKeeper 是一套外部系統,要想部署一套 Kafka 集羣,就要同時部署、管理、監控 ZooKeeper。ZooKeeper 有自己的配置方式、管理工具,和 Kafka 完全不一樣,所以,一起搞兩套分佈式系統,自然就提升了複雜度,也更容易出現問題。有時工作量還會加倍,例如要開啓一些安全特性,Kafka 和 ZooKeeper 中都需要配置。除了複雜度,外部存儲也會降低系統效率。

例如:

所以,ZooKeeper 帶來的複雜度、系統效率這兩個問題已經成爲 Kafka 的痛點,Kafka 團隊一直在努力去除對 ZooKeeper 的依賴。Kafka 2.8.0 這個版本終於實現了。

使用 Raft 模式之後,元數據、配置信息都會保存在 @metadata 這個 Topic 中,自動在集羣中複製。這樣 Kafka 就會簡單輕巧很多。

但需要注意的是,Zookeeper-less Kafka 還屬於早期版本,並不完善,所以,現在不要應用在線上產品環境中。

2.2 主要應用場景

2.3 Kafka 主要設計目標

2.4 兩種主要的消息傳遞模式

2.4.1 點對點模式


點對點模式通常是基於拉取或者輪詢的消息傳送模型,這個模型的特點是發送到隊列的消息被一個且只有一個消費者進行處理。生產者將消息放入消息隊列後,由消費者主動的去拉取消息進行消費。點對點模型的的優點是消費者拉取消息的頻率可以由自己控制。但是消息隊列是否有消息需要消費,在消費者端無法感知,所以在消費者端需要額外的線程去監控。

2.4.2 發佈訂閱模式


發佈訂閱模式是一個基於消息送的消息傳送模型,該模型可以有多種不同的訂閱者。生產者將消息放入消息隊列後,隊列會將消息推送給訂閱過該類消息的消費者。由於是消費者被動接收推送,所以無需感知消息隊列是否有待消費的消息!但是 consumer1、consumer2、consumer3 由於機器性能不一樣,所以處理消息的能力也會不一樣,但消息隊列卻無法感知消費者消費的速度!所以推送的速度成了發佈訂閱模模式的一個問題!假設三個消費者處理速度分別是 8M/s、5M/s、2M/s,如果隊列推送的速度爲 5M/s,則 consumer3 無法承受!如果隊列推送的速度爲 2M/s,則 consumer1、consumer2 會出現資源的極大浪費!

大部分的消息系統選用發佈訂閱模式。Kafka 就是一種發佈訂閱模式。

2.5 Kafka 四個核心 API

三、Kafka 的優勢

四、Kafka 的應用場景

4.1 日誌收集

Kafka 可以收集各種服務的 Log,通過 Kafka 以統一接口服務的方式開放給各種 Consumer。

4.2 消息系統

解耦生產者和消費者、緩存消息等。

4.3 用戶活動跟蹤

4.4 運營指標

Kafka 也經常用來記錄運營監控數據。包括收集各種分佈式應用的數據,生產各種操作的集中反饋,比如報警和報告。

4.5 流式處理

比如 Spark Streaming 和 Storm。

五、基礎架構

5.1 Kafka 架構圖


5.2 消息和批次

5.3 模式

5.4 主題和分區

5.5 生產者和消費者


5.6 broker 和集羣


每個集羣都有一個 broker 是集羣控制器(自動從集羣的活躍成員中選舉出來)。

控制器負責管理工作:

集羣中一個分區屬於一個 broker,該 broker 稱爲分區首領。
一個分區可以分配給多個 broker,此時會發生分區複製。
分區的複製提供了消息冗餘, 高可用 。副本分區不負責處理消息的讀寫。

六、核心概念

6.1 Producer

生產者創建消息。

該角色將消息發佈到 Kafka 的 topic 中。broker 接收到生產者發送的消息後,broker 將該消息追加到當前用於追加數據的 segment 文件中。

一般情況下,一個消息會被髮布到一個特定的主題上。

6.2 Consumer

消費者讀取消息。


6.3 Broker

一個獨立的 Kafka 服務器被稱爲 broker。

broker 爲消費者提供服務,對讀取分區的請求作出響應,返回已經提交到磁盤上的消息。

broker 是集羣的組成部分。每個集羣都有一個 broker  同時充當了集羣控制器的角色(自動從集羣的活躍成員中選舉出來)。

控制器負責管理工作,包括將分區分配給 broker 和監控 broker。

在集羣中,一個分區從屬於一個 broker,該 broker 被稱爲分區的首領。


6.4 Topic

每條發佈到 Kafka 集羣的消息都有一個類別,這個類別被稱爲 Topic。

物理上不同 Topic 的消息分開存儲。

主題就好比數據庫的表,尤其是分庫分表之後的邏輯表。

6.5 Partition

6.6 Replicas

Kafka 使用主題來組織數據,每個主題被分爲若干個分區,每個分區有多個副本。那些副本被保存在 broker 上,每個 broker 可以保存成百上千個屬於不同主題和分區的副本。

副本有以下兩種類型:

6.7 Offset

6.7.1 生產者 Offset

消息寫入的時候,每一個分區都有一個 offset,這個 offset 就是生產者的 offset,同時也是這個分區的最新最大的 offset。

有些時候沒有指定某一個分區的 offset,這個工作 kafka 幫我們完成。

6.7.2 消費者 Offset

這是某一個分區的 offset 情況,生產者寫入的 offset 是最新最大的值是 12,而當 Consumer A 進行消費時,從 0 開始消費,一直消費到了 9,消費者的 offset 就記錄在 9,Consumer B 就紀錄在了 11。等下一次他們再來消費時,他們可以選擇接着上一次的位置消費,當然也可以選擇從頭消費,或者跳到最近的記錄並從 “現在” 開始消費。

6.8、副本

Kafka 通過副本保證高可用。副本分爲首領副本(Leader) 和跟隨者副本(Follower)。

跟隨者副本包括同步副本不同步副本,在發生首領副本切換的時候,只有同步副本可以切換爲首領副本。

6.8.1 AR

分區中的所有副本統稱爲AR(Assigned Repllicas)

AR=ISR+OSR

6.8.2 ISR

所有與leader副本保持一定程度同步的副本(包括Leader)組成ISR(In-Sync Replicas),ISR 集合是 AR 集合中的一個子集。消息會先發送到 leader 副本,然後 follower 副本才能從 leader 副本中拉取消息進行同步,同步期間內 follower 副本相對於 leader 副本而言會有一定程度的滯後。前面所說的 “一定程度” 是指可以忍受的滯後範圍,這個範圍可以通過參數進行配置。

6.8.3 OSR

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

6.8.4 HW

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

6.8.5 LEO

LEO 是Log End Offset的縮寫,它表示了當前日誌文件中下一條待寫入消息的 offset。

歡迎大家關注我的公衆號【老周聊架構】,Java 後端主流技術棧的原理、源碼分析、架構以及各種互聯網高併發、高性能、高可用的解決方案。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/Y6YYKh39HoDMoZ4vYA9cSw