概述
關於 kafka 的重要性就不再多說了,它不僅解耦了大數據組件之間的耦合性,而且還能對接流實時計算框架,充當其數據源,同時還能能接收大量數據輸入,以類似於消息隊列的方式組織統一管理。
官方定義:Apache Kafka® is a distributed streaming platform.即 kafka 是一個分佈式流平臺。通俗的說法是:Kafka是一種高吞吐量的分佈式發佈訂閱消息系統。說白了即消息中間件。而消息中間件一般支持兩種模式的隊列:一是消息隊列模式,二是發佈訂閱 (Pub-Sub) 模式。而 Kafka 即是採用後者方式的輕量級消息系統、流平臺。
這個系統需要滿足如下三個特性:
- 能夠對流記錄(每條消息)進行發佈、訂閱。
- 能夠支持容錯地持久化每一條流記錄。(注:採用時間複雜度O(1)的磁盤存儲結構,即使TB級別以上的數據也可以常數時間訪問)
- 能夠及實地處理每一條實時的流記錄消息。
爲何使用?
- 解耦:分佈式系統構件之間可以通過消息系統傳遞消息從而解除相互之間功能的耦合。
- 異步通信:在實現定義好Consumer消費者後,我們只需要在Producer生產者端將消息放入即可。無需立即對消息進行處理。
核心概念
你只要瞭解如下幾個核心概念,基本就能從全局上把握 kafka 了,下面依次介紹:
- Broker
即代理服務器,kafka 部署在集羣中的多臺機器上,其中的每一臺服務器即 Broker,它代表 kafka 的一個實例或節點,多個 Broker 構成一個 kafka 集羣。 - Topic
即話題,生產或消費流記錄(消息),都需要指定特定的 Topic,一般將同一業務數據、同一類型數據寫入同一 Topic。
(注:一般生產環境上,消息的 Topic 代表其所屬的類型,對應某個名字的消息隊列,比如要記錄網站用戶行爲,我們可以設計 PV,點擊,登錄等不同Topic) - Partition
即分區,因爲一個 Topic 下可能會有大量的數據,一個 Broker 可能存不下,故一個 Topic 可以有多個分區,相當於把一個大流數據集分爲多份,分別存在隸屬於同一個 Topic 下的不同分區中。
(注:Topic 是邏輯概念,Partition 是物理概念,每個分區對應於一個物理文件夾,存儲分區數據及索引文件) - Producer
即生產者,向 Broker 某一 Topic 主題發送數據的客戶端。 - Consumer
即消費者,消費指定 Topic 下的數據。 - Consumer Group
即消費者組,每個 Consumer 隸屬於某個特定的 Consumer Group,Producer 將一條消息發送給所有的 Consumer Group,但最終只能被 Consumer Group 下的唯一的一個 Consumer 消費。
(注:分組的目的是爲了加快讀取速度) - Replication
即副本,一個 Partition 分區可以有多個副本,存在不同的 Broker 中,提供容錯保證。
部分詳細架構分析
工作流程架構
下圖完整地描述 kafka 的整體流程結構,如有不足歡迎補充。
如上圖所示,有3個 Broker 代理服務器,有2個 Topic,其中 Topic1 有兩個分區,Topic2 有1個分區,集羣分區備份副本數爲3。
這裏需要注意的是:一個 Topic 可以被多個 Consumer Group 訂閱,但是隻能被其中的一個 Consumer 消費。這裏 Consumer Group A 和 Consumer Group B 都訂閱了 Topic 1 和 Topic 2。在Consumer Group 中所有 Consumer 是競爭關係,一個流記錄(消息)只能被一個 Consumer 消費。上圖中具體消費情況如下:
Consumer Group A 裏面的 Consumer 1 消費着 Broker1 上面的 Topic1
Consumer Group A 裏面的 Consumer 2 消費着 Broker3 上面的 Topic2
Consumer Group B 裏面的 Consumer 3 消費着 Broker2 上面的 Topic1
Consumer Group B 裏面的 Consumer 4 消費着 Broker3 上面的 Topic2
Consumer Group B 裏面的 Consumer 5 沒有消費任何 Topic
數據存儲架構
- Topic 存儲結構
一個 Topic 可以分爲多個 Partition,以文件夾的形式落盤,而每個 Partition 則是一個先進先出(FIFO)的隊列,在隊尾追加消息,在隊頭讀取。且在一個Topic 內部不能保證消息的順序性,只能保證一個 Partition 內部的消息的有序序 ,如下圖所示:
- Partition 存儲結構
每個 Topic 的 Partition 在物理上以文件夾的形式存在,此文件夾中存在兩種類型的文件,其一是以起始偏移量開頭、以 .log 結尾的數據文件,用於存儲流記錄消息數據 ;其二是以 .index 或 .timeindex 結尾的索引文件,用以定位消息讀取到的位置,提高消息寫入和查詢速度。它們統稱爲 Segment 文件。 - 偏移量
偏移量 OffSet 用於定位 Partition 分區中消息的順序編號。哪個 Consumer 消費到那裏,該 Consumer 的 Offset 就在哪裏,不同 Consumer 可能有不同的 Offset 值,由 Zookeeper 維護偏移量 Offset。
(架構心得:傳統消息系統將消費者消費到的 Offset 信息存儲在代理服務器,而 kafka 簡化設計,將 Offset 信息交由消費者各自保存,聯同其他管理信息一並存在 Zookeeper 中,讓代理服務器完全成爲無狀態的,這樣便會極大地提高消息系統的容錯性以及可擴展性。)
高可用
kafka 使用 ISR 副本管理機制來保證其高可用性。首先需要明確 kafka 副本基本管理單位是 Partition 分區,如果我們指定了多個副本策略,則這些副本里只有一個爲主副本(Leader),其他爲次級副本 (Follower),所有讀寫均和主副本來響應。
ISR 具體運行機制是:將所有的次級副本(偶數)放到兩個集合,其中一個集合被稱爲 ISR 集合,該集合裏的數據始終與主節點數據保持一致,數據寫入時,只有 ISR 集合中全部成功寫入纔算寫入成功,在做主備切換時,直接且只允許從 ISR集合中選取將要轉正的副本即可。
那麼爲何不採用 Zab(Zookeeper 採用的一致性協議)、或 Paxos 算法來保證 kafka 副本的數據一致性,而是採用另一套 ISR 副本管理機制來保證數據一致性呢?
原因其實很簡單,因爲在相同的副本容錯條件下, ISR 機制可以維護更少的數據副本。比如 ISR 集合大小爲 n+1(1主,n副,n爲偶數),那麼最多可以允許n個副本故障,而對於其他基於投票的一致性算法來說,則需要 2n + 1 個副本才能達到相同的容錯性。
以上關於 kafka 原理及架構就講這麼多,大晚上的寫完不容易,希望能對大家有所幫助,下篇文章會講下 kafka 具體使用。