1. Kafka概述
1.1 定義
Kafka 是由 Apache 軟件基金會開發的一個開源流處理平臺。
Kafka 是一個分布式的基于發布/訂閱模式的消息隊列(Message Queue),主要應用于大數據實時處理領域。
1.2 消息隊列
1.2.1 傳統消息隊列的應用場景
1.2.2 為什么需要消息隊列
解耦:允許你獨立的擴展或修改兩邊的處理過程,只要確保它們遵守同樣的接口約束。
冗余:消息隊列把數據進行持久化直到它們已經被完全處理,通過這一方式規避了數據丟失風險。許多消息隊列所采用的"插入-獲取-刪除"范式中,在把一個消息從隊列中刪除之前,需要你的處理系統明確的指出該消息已經被處理完畢,從而確保你的數據被安全的保存直到你使用完畢。
擴展性:因為消息隊列解耦了你的處理過程,所以增大消息入隊和處理的頻率是很容易的,只要另外增加處理過程即可。
靈活性 & 峰值處理能力:在訪問量劇增的情況下,應用仍然需要繼續發揮作用,但是這樣的突發流量并不常見。如果以能處理這類峰值訪問為標準來投入資源隨時待命無疑是巨大的浪費。使用消息隊列能夠使關鍵組件頂住突發的訪問壓力,而不會因為突發的超負荷的請求而完全崩潰。
可恢復性:系統的一部分組件失效時,不會影響到整個系統。消息隊列降低了進程間的耦合度,所以即使一個處理消息的進程掛掉,加入隊列中的消息仍然可以在系統恢復后被處理。
順序保證:在大多使用場景下,數據處理的順序都很重要。大部分消息隊列本來就是排序的,并且能保證數據會按照特定的順序來處理。(Kafka 保證一個 Partition 內的消息的有序性)
緩沖:有助于控制和優化數據流經過系統的速度, 解決生產消息和消費消息的處理速度不一致的情況。
異步通信:很多時候,用戶不想也不需要立即處理消息。消息隊列提供了異步處理機制,允許用戶把一個消息放入隊列,但并不立即處理它。想向隊列中放入多少消息就放多少,然后在需要的時候再去處理它們。
1.2.3 消息隊列的兩種模式
點對點模式(一對一,消費者主動拉取數據,收到后消息清除)
消息生產者生產消息發送到 Queue 中,然后消費者從 Queue 中取出并且消費消息。消息被消費以后,queue 中不再有存儲,所以消息消費者不可能消費到已經被消費的消息。Queue 支持存在多個消費者,但是對一個消息而言,只會有一個消費者可以消費。
發布/訂閱模式(一對多,數據生產后,推送給所有訂閱者)
消息生產者(發布)將消息發布到 topic 中,同時有多個消息消費者(訂閱)消費該消息。和點對點方式不同,發布到 topic 的消息會被所有訂閱者消費。
1.3 Kafka 基礎架構圖
Producer :消息生產者,就是向 kafka broker 發消息的客戶端;
Consumer :消息消費者,向 kafka broker 取消息的客戶端;
Consumer Group (CG):消費者組,由多個 consumer 組成。消費者組內每個消費者負責消費不同分區的數據,一個分區只能由一個組內消費者消費;消費者組之間互不影響。所有的消費者都屬于某個消費者組,即消費者組是邏輯上的一個訂閱者。
Broker :一臺 kafka 服務器就是一個 broker(雖然多個 Broker 進程能夠運行在同一臺機器上,但更常見的做法是將不同的 Broker 分散運行在不同的機器上)。一個集群由多個 broker 組成。一個 broker 可以容納多個 topic;
Topic :可以理解為一個隊列,Kafka 的消息通過 Topics(主題) 進行分類,生產者和消費者面向的都是一個 topic;
Partition:為了實現擴展性,一個非常大的 topic 可以分布到多個 broker(即服務器)上, 一個 topic 可以分為多個 partition,每個 partition 是一個有序的隊列;partition 中的每條消息都會被分配一個有序的 id( offset)。kafka 只保證按一個 partition 中的順序將消息發給 consumer,不保證一個 topic 的整體(多個 partition 間)的順序;
Replica:副本,為保證集群中的某個節點發生故障時,該節點上的 partition 數據不丟失,且 kafka 仍然能夠繼續工作,kafka 提供了副本機制,一個 topic 的每個分區都有若干個副本, 一個 leader 和若干個 follower;
leader:每個分區多個副本的“主”,生產者發送數據的對象,以及消費者消費數據的對象都是 leader;
follower:每個分區多個副本中的“從”,實時從 leader 中同步數據,保持和 leader 數據的同步。leader 發生故障時,某個 follower 會成為新的 follower;
offset:kafka 的存儲文件都是按照offset.kafka來命名,用 offset 做名字的好處是方便查找。例如你想找位于 2049 的位置,只要找到 2048.kafka 的文件即可。當然 the first offset 就是 00000000000.kafka。
2. Hello Kafka
2.1 動起手來
Quickstart
中文版入門指南
2.2 基本概念(官方介紹翻譯)
Kafka 是一個分布式的流處理平臺。是支持分區的(partition)、多副本的(replica),基于 ZooKeeper 協調的分布式消息系統,它的最大的特性就是可以實時的處理大量數據以滿足各種需求場景:比如基于 hadoop 的批處理系統、低延遲的實時系統、storm/Spark 流式處理引擎,web/nginx 日志、訪問日志,消息服務等等
有三個關鍵能力
它可以讓你發布和訂閱記錄流。在這方面,它類似于一個消息隊列或企業消息系統
它可以讓你持久化收到的記錄流,從而具有容錯能力
它可以讓你處理收到的記錄流
應用于兩大類應用
構建實時的流數據管道,可靠地獲取系統和應用程序之間的數據。
構建實時流的應用程序,對數據流進行轉換或反應。
想要了解 Kafka 如何具有這些能力,首先,明確幾個概念:
Kafka 作為一個集群運行在一個或多個服務器上
Kafka 集群存儲的消息是以主題(topics)為類別記錄的
每個消息記錄包含一個鍵,一個值和時間戳
Kafka有五個核心API:
Producer API允許應用程序發布記錄流至一個或多個 Kafka 的話題(Topics)
Consumer API允許應用程序訂閱一個或多個主題,并處理這些主題接收到的記錄流
Streams API允許應用程序充當流處理器(stream processor),從一個或多個主題獲取輸入流,并生產一個輸出流至一個或多個的主題,能夠有效地變換輸入流為輸出流
Connector API允許構建和運行可重用的生產者或消費者,能夠把 Kafka 主題連接到現有的應用程序或數據系統。例如,一個連接到關系數據庫的連接器(connector)可能會獲取每個表的變化
Admin API允許管理和檢查主題、brokes 和其他 Kafka 對象。(這個是新版本才有的)
Kafka 的客戶端和服務器之間的通信是靠一個簡單的,高性能的,與語言無關的 TCP 協議完成的。這個協議有不同的版本,并保持向后兼容舊版本。Kafka 不光提供了一個 Java 客戶端,還有許多語言版本的客戶端。
主題和日志
主題是同一類別的消息記錄(record)的集合。Kafka 的主題支持多用戶訂閱,也就是說,一個主題可以有零個,一個或多個消費者訂閱寫入的數據。對于每個主題,Kafka 集群都會維護一個分區日志,如下所示:
每個分區是一個有序的,不可變的消息序列,新的消息不斷追加到 partition 的末尾。在每個 partition 中,每條消息都會被分配一個順序的唯一標識,這個標識被稱為offset,即偏移量。kafka 不能保證全局有序,只能保證分區內有序。
Kafka 集群保留所有發布的記錄,不管這個記錄有沒有被消費過,Kafka 提供可配置的保留策略去刪除舊數據(還有一種策略根據分區大小刪除數據)。例如,如果將保留策略設置為兩天,在數據發布后兩天,它可用于消費,之后它將被丟棄以騰出空間。Kafka 的性能跟存儲的數據量的大小無關(會持久化到硬盤), 所以將數據存儲很長一段時間是沒有問題的。
事實上,在單個消費者層面上,每個消費者保存的唯一的元數據就是它所消費的數據日志文件的偏移量。偏移量是由消費者來控制的,通常情況下,消費者會在讀取記錄時線性的提高其偏移量。不過由于偏移量是由消費者控制,所以消費者可以將偏移量設置到任何位置,比如設置到以前的位置對數據進行重復消費,或者設置到最新位置來跳過一些數據。
分布式
日志的分區會跨服務器的分布在 Kafka 集群中,每個服務器會共享分區進行數據請求的處理。每個分區可以配置一定數量的副本分區提供容錯能力。
每個分區都有一個服務器充當“leader”和零個或多個服務器充當“followers”。leader 處理所有的讀取和寫入分區的請求,而 followers 被動的從領導者拷貝數據。如果 leader 失敗了,followers 之一將自動成為新的領導者。每個服務器可能充當一些分區的 leader 和其他分區的 follower,所以 Kafka 集群內的負載會比較均衡。
生產者
生產者發布數據到他們所選擇的主題。生產者負責選擇把記錄分配到主題中的哪個分區。這可以使用輪詢算法( round-robin)進行簡單地平衡負載,也可以根據一些更復雜的語義分區算法(比如基于記錄一些鍵值)來完成。
消費者
消費者以消費群(consumer group)的名稱來標識自己,每個發布到主題的消息都會發送給訂閱了這個主題的消費群里面的一個消費者的一個實例。消費者的實例可以在單獨的進程或單獨的機器上。
如果所有的消費者實例都屬于相同的消費群,那么記錄將有效地被均衡到每個消費者實例。
如果所有的消費者實例有不同的消費群,那么每個消息將被廣播到所有的消費者進程。
這是 kafka 用來實現一個 topic 消息的廣播(發給所有的 consumer) 和單播(發給任意一個 consumer)的手段。一個 topic 可以有多個 CG。topic 的消息會復制 (不是真的復制,是概念上的)到所有的 CG,但每個 partion 只會把消息發給該 CG 中的一 個 consumer。如果需要實現廣播,只要每個 consumer 有一個獨立的 CG 就可以了。要實現單播只要所有的 consumer 在同一個 CG。用 CG 還可以將 consumer 進行自由的分組而不需要多次發送消息到不同的 topic;
舉個栗子:
如上圖所示,一個兩個節點的 Kafka 集群上擁有一個四個 partition(P0-P3)的 topic。有兩個消費者組都在消費這個 topic 中的數據,消費者組 A 有兩個消費者實例,消費者組 B 有四個消費者實例。
從圖中我們可以看到,在同一個消費者組中,每個消費者實例可以消費多個分區,但是每個分區最多只能被消費者組中的一個實例消費。也就是說,如果有一個 4 個分區的主題,那么消費者組中最多只能有 4 個消費者實例去消費,多出來的都不會被分配到分區。其實這也很好理解,如果允許兩個消費者實例同時消費同一個分區,那么就無法記錄這個分區被這個消費者組消費的 offset 了。如果在消費者組中動態的上線或下線消費者,那么 Kafka 集群會自動調整分區與消費者實例間的對應關系。
Kafka消費群的實現方式是通過分割日志的分區,分給每個 Consumer 實例,使每個實例在任何時間點的都可以“公平分享”獨占的分區。維持消費群中的成員關系的這個過程是通過 Kafka 動態協議處理。如果新的實例加入該組,他將接管該組的其他成員的一些分區;如果一個實例死亡,其分區將被分配到剩余的實例。
Kafka 只保證一個分區內的消息有序,不能保證一個主題的不同分區之間的消息有序。分區的消息有序與依靠主鍵進行數據分區的能力相結合足以滿足大多數應用的要求。但是,如果你想要保證所有的消息都絕對有序可以只為一個主題分配一個分區,雖然這將意味著每個消費群同時只能有一個消費進程在消費。
保證
Kafka 提供了以下一些高級別的保證:
由生產者發送到一個特定的主題分區的消息將被以他們被發送的順序來追加。也就是說,如果一個消息 M1 和消息 M2 都來自同一個生產者,M1 先發,那么 M1 將有一個低于 M2 的偏移,會更早在日志中出現。
消費者看到的記錄排序就是記錄被存儲在日志中的順序。
對于副本因子 N 的主題,我們將承受最多 N-1 次服務器故障切換而不會損失任何的已經保存的記錄。
2.3 Kafka的使用場景
消息
Kafka 被當作傳統消息中間件的替代品。消息中間件的使用原因有多種(從數據生產者解耦處理,緩存未處理的消息等)。與大多數消息系統相比,Kafka 具有更好的吞吐量,內置的分區,多副本和容錯功能,這使其成為大規模消息處理應用程序的良好解決方案。
網站行為跟蹤
Kafka 的初衷就是能夠將用戶行為跟蹤管道重構為一組實時發布-訂閱數據源。這意味著網站活動(頁面瀏覽量,搜索或其他用戶行為)將被發布到中心主題,這些中心主題是每個用戶行為類型對應一個主題的。這些數據源可被訂閱者獲取并用于一系列的場景,包括實時處理,實時監控和加載到 Hadoop 或離線數據倉庫系統中進行離線處理和報告。用戶行為跟蹤通常會產生巨大的數據量,因為用戶每個頁面的瀏覽都會生成許多行為活動消息。
測量
Kafka 通常用于監測數據的處理。這涉及從分布式應用程序聚集統計數據,生產出集中的運行數據源 feeds(以便訂閱)。
日志聚合
許多人用 Kafka 作為日志聚合解決方案的替代品。日志聚合通常從服務器收集物理日志文件,并將它們集中放置(可能是文件服務器或HDFS),以便后續處理。kafka 抽象出文件的細節,并將日志或事件數據作為消息流清晰地抽象出來。這為低時延的處理提供支持,而且更容易支持多個數據源和分布式的數據消費。相比集中式的日志處理系統(如 Scribe 或 Flume),Kafka 性能同樣出色,而且因為副本備份提供了更強的可靠性保證和更低的端到端延遲。
流處理
Kafka 的流數據管道在處理數據的時候包含多個階段,其中原始輸入數據從 Kafka 主題被消費然后匯總,加工,或轉化成新主題用于進一步的消費或后續處理。例如,用于推薦新聞文章的數據流處理管道可能從 RSS 源抓取文章內容,并將其發布到“文章”主題; 進一步的處理可能是標準化或刪除重復數據,然后發布處理過的文章內容到一個新的主題, 最后的處理階段可能會嘗試推薦這個內容給用戶。這種處理管道根據各個主題創建實時數據流圖。從版本 0.10.0.0 開始,Apache Kafka 加入了輕量級的但功能強大的流處理庫Kafka Streams,Kafka Streams 支持如上所述的數據處理。除了Kafka Streams,可以選擇的開源流處理工具包括Apache Storm and Apache Samza。
事件源
事件源是一種應用程序設計風格,是按照時間順序記錄的狀態變化的序列。Kafka 的非常強大的存儲日志數據的能力使它成為構建這種應用程序的極好的后端選擇。
提交日志
Kafka 可以為分布式系統提供一種外部提交日志(commit-log)服務。日志有助于節點之間復制數據,并作為一種數據重新同步機制用來恢復故障節點的數據。Kafka 的 log compaction 功能有助于支持這種用法。Kafka 在這種用法中類似于 Apache BookKeeper 項目。
-
大數據
+關注
關注
64文章
8894瀏覽量
137477 -
消息隊列
+關注
關注
0文章
33瀏覽量
3000 -
kafka
+關注
關注
0文章
51瀏覽量
5225
原文標題:程序員必須了解的消息隊列之王-Kafka
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論