深入研究作爲許多公司架構核心的系統
[Kafka ]全面介紹Apache Kafka™

介紹

卡夫卡是一個現在聽到很多的話......許多領先的數字公司似乎也在使用它。但究竟是什麼呢?

Kafka最初於2011年在LinkedIn開發,自那時起經歷了很多改進。如今它是一個完整的平臺,允許您冗餘地存儲荒謬的數據量,擁有一個具有巨大吞吐量(數百萬/秒)的消息總線,並對同時通過它的數據使用實時流處理。

Kafka是一個分佈式,可水平擴展,容錯的提交日誌。

那是一些奇特的話,讓我們一個接一個地看看他們的意思。之後,我們將深入探討它的工作原理。

分佈式

分佈式系統是分成多個運行的計算機的系統,所有這些計算機在一個集羣中一起工作,作爲最終用戶的一個單一節點出現。 Kafka的分佈在於它在不同節點(稱爲代理)上存儲,接收和發送消息。

我也對此有一個全面的介紹

這種方法的好處是高可擴展性和容錯性。

水平可擴展性

我們首先定義術語垂直可伸縮性。比如說,你有一個傳統的數據庫服務器開始變得過載。解決這個問題的方法是簡單地增加服務器上的資源(CPU,RAM,SSD)。這稱爲垂直縮放 - 您可以向機器添加更多資源。向上擴展有兩大缺點:

  • 硬件定義了限制。你不能無限期地向上擴展。
  • 它通常需要停機時間,這是大公司無法承受的。

水平可擴展性通過向其投入更多機器來解決同樣的問題。添加新計算機不需要停機,也不會限制羣集中的計算機數量。問題在於並非所有系統都支持水平可伸縮性,因爲它們不是設計用於集羣中,而是那些通常更復雜的系統。

[Kafka ]全面介紹Apache Kafka™

Horizontal scaling becomes much cheaper after a ce

容錯

非分佈式系統中出現的一點是它們具有單點故障(SPoF)。 如果您的單個數據庫服務器由於某種原因而失敗(正如機器那樣),那就搞砸了。

分佈式系統的設計方式是以可配置的方式適應故障。 在5節點Kafka羣集中,即使其中2個節點關閉,您也可以繼續工作。 值得注意的是,容錯與性能直接相關,因爲在您的系統容錯程度越高時,性能就越差。

提交日誌

提交日誌(也稱爲預寫日誌,事務日誌)是僅支持附加的持久有序數據結構。 您無法修改或刪除記錄。 它從左到右閱讀並保證項目訂購。

[Kafka ]全面介紹Apache Kafka™

Sample illustration of a commit log

- 你是在告訴我Kafka是如此簡單的數據結構嗎?

在很多方面,是的。這種結構是卡夫卡的核心,非常寶貴,因爲它提供了排序,而排序則提供了確定性的處理。這兩者都是分佈式系統中的重要問題。

Kafka實際上將所有消息存儲到磁盤(稍後會詳細介紹),並在結構中對它們進行排序,以便利用順序磁盤讀取。

讀取和寫入是一個恆定時間O(1)(知道記錄ID),與磁盤上其他結構的O(log N)操作相比是一個巨大的優勢,因爲每次磁盤搜索都很昂貴。

讀取和寫入不會影響另一個。寫作不會鎖定讀數,反之亦然(與平衡樹相對)

這兩點具有巨大的性能優勢,因爲數據大小與性能完全分離。無論您的服務器上有100KB還是100TB的數據,Kafka都具有相同的性能。

它是如何工作的?

應用程序(生產者)將消息(記錄)發送到Kafka節點(代理),並且所述消息由稱爲消費者的其他應用程序處理。所述消息存儲在主題中,並且消費者訂閱該主題以接收新消息。

[Kafka ]全面介紹Apache Kafka™

隨着主題變得非常大,它們會分成更小的分區,以獲得更好的性能和可伸縮性。 (例如:假設您存儲了用戶登錄請求,您可以按用戶用戶名的第一個字符拆分它們)

Kafka保證分區內的所有消息都按照它們進入的順序排序。區分特定消息的方式是通過其偏移量,您可以將其視爲普通數組索引,序列號對於每個新消息遞增 在一個分區。

[Kafka ]全面介紹Apache Kafka™

卡夫卡遵循愚蠢的經紀人和聰明的消費者的原則。 這意味着Kafka不會跟蹤消費者讀取的記錄並刪除它們,而是將它們存儲一定的時間(例如一天)或直到滿足某個大小閾值。 消費者自己向卡夫卡民意調查新消息,並說出他們想要閱讀的記錄。 這允許它們按照自己的意願遞增/遞減它們所處的偏移量,從而能夠重放和重新處理事件。

值得注意的是,消費者實際上是消費者羣體,其中包含一個或多個消費者流程。 爲了避免兩個進程兩次讀取相同的消息,每個分區僅與每個組的一個消費者進程相關聯。

[Kafka ]全面介紹Apache Kafka™

持久化到磁盤

正如我之前提到的,Kafka實際上將所有記錄存儲到磁盤中,並且不會在RAM中保留任何內容。你可能想知道這是如何以最明智的方式做出明智的選擇。這背後有許多優化使其可行:

  1. Kafka有一個將消息組合在一起的協議。這允許網絡請求將消息組合在一起並減少網絡開銷,服務器反過來一次性保留大量消息,消費者一次獲取大型線性塊
  2. 磁盤上的線性讀/寫速度很快。現代磁盤速度慢的概念是由於大量磁盤搜索,這在大型線性操作中不是問題。
  3. 所述線性操作由OS大量優化,通過預讀(預取大塊倍數)和後寫(組小邏輯寫入大物理寫入)技術。
  4. 現代操作系統將磁盤緩存在空閒RAM中。這稱爲pagecache。
  5. 由於Kafka在整個流程(生產者 - >代理 - >消費者)中以未經修改的標準化二進制格式存儲消息,因此它可以使用零拷貝優化。那時操作系統將數據從pagecache直接複製到套接字,有效地完全繞過了Kafka代理應用程序。

所有這些優化都使Kafka能夠以接近網絡的速度傳遞消息。

數據分發和複製

我們來談談Kafka如何實現容錯以及它如何在節點之間分配數據。

數據複製

分區數據在多個代理中複製,以便在一個代理程序死亡時保留數據。

在任何時候,一個代理“擁有”一個分區,並且是應用程序從該分區寫入/讀取的節點。這稱爲分區領導者。它將收到的數據複製到N個其他經紀人,稱爲追隨者。它們也存儲數據,並準備好在領導節點死亡時被選爲領導者。

這有助於您配置保證任何成功發佈的消息都不會丟失。通過選擇更改複製因子,您可以根據數據的重要性來交換性能以獲得更強的持久性保證。

[Kafka ]全面介紹Apache Kafka™

通過這種方式,如果一個領導者失敗,追隨者可以取代他的位置。

不過你可能會問:

- 生產者/消費者如何知道分區的領導者是誰?

對於生產者/消費者來說,從分區寫入/讀取,他們需要知道它的領導者,對嗎?這些信息需要從某個地方獲得。

Kafka將這些元數據存儲在名爲Zookeeper的服務中。

什麼是Zookeeper?

Zookeeper是一個分佈式鍵值存儲。它針對讀取進行了高度優化,但寫入速度較慢。它最常用於存儲元數據和處理羣集的機制(心跳,分發更新/配置等)。

它允許服務的客戶(Kafka經紀人)訂閱並在發生變更後發送給他們。這就是經紀人如何知道何時切換分區領導者。動物園管理員也非常容錯,應該是,因爲卡夫卡在很大程度上依賴它。

它用於存儲所有類型的元數據,提到一些:

  • 消費者羣體的每個分區的偏移量(儘管現代客戶端在單獨的Kafka主題中存儲偏移量)
  • ACL(訪問控制列表) - 用於限制訪問/授權
  • 生產者和消費者配額 - 最大消息/秒邊界
  • 分區領導者及其健康

生產者/消費者如何知道分區的領導者是誰?

生產者和消費者過去常常直接連接並與Zookeeper交談以獲取此(和其他)信息。 Kafka已經遠離這種耦合,從版本0.8和0.9開始,客戶端直接從Kafka經紀人那裏獲取元數據信息,他們自己與Zookeeper交談。

[Kafka ]全面介紹Apache Kafka™

在Kafka中,流處理器是從輸入主題獲取連續數據流,對此輸入執行一些處理並生成數據流以輸出主題(或外部服務,數據庫,垃圾箱,無論何處......)的任何內容。

可以直接使用生產者/消費者API進行簡單處理,但是對於更復雜的轉換(如將流連接在一起),Kafka提供了一個集成的Streams API庫。

此API旨在用於您自己的代碼庫中,而不是在代理上運行。它與消費者API類似,可幫助您在多個應用程序(類似於消費者組)上擴展流處理工作。

無狀態處理

流的無狀態處理是確定性處理,其不依賴於任何外部。您知道,對於任何給定的數據,您將始終生成與其他任何內容無關的相同輸出。一個例子就是簡單的數據轉換 - 將某些內容附加到字符串“Hello” - >“Hello,World!”。

[Kafka ]全面介紹Apache Kafka™

流表雙重性

重要的是要認識到流和表基本相同。 流可以解釋爲表,表可以解釋爲流。

流作爲表

流可以解釋爲數據的一系列更新,其中聚合是表的最終結果。 這種技術稱爲事件採購。

如果您瞭解如何實現同步數據庫複製,您將看到它是通過所謂的流複製,其中表中的每個更改都發送到副本服務器。 事件採購的另一個例子是區塊鏈分類賬 - 分類賬也是一系列變化。

Kafka流可以用相同的方式解釋 - 當累積形成最終狀態時的事件。 此類流聚合保存在本地RocksDB中(默認情況下),稱爲KTable。

[Kafka ]全面介紹Apache Kafka™

表作爲流

可以將表視爲流中每個鍵的最新值的快照。 以相同的方式,流記錄可以生成表,表更新可以生成更改日誌流。

[Kafka ]全面介紹Apache Kafka™

有狀態處理

一些簡單的操作(如map()或filter())是無狀態的,不需要您保留有關處理的任何數據。但是,在現實生活中,您所做的大多數操作都是有狀態的(例如count()),因此需要您存儲當前累積的狀態。

在流處理器上維護狀態的問題是流處理器可能會失敗!你需要在哪裏保持這種狀態才能容錯?

一種簡單的方法是簡單地將所有狀態存儲在遠程數據庫中,並通過網絡連接到該存儲。這樣做的問題是沒有數據的位置和大量的網絡往返,這兩者都會顯着減慢您的應用程序。一個更微妙但重要的問題是您的流處理作業的正常運行時間將緊密耦合到遠程數據庫,並且作業將不會自包含(數據庫中的數據庫與另一個團隊的更改可能會破壞您的處理)。

那麼什麼是更好的方法呢?

回想一下表和流的二元性。這允許我們將流轉換爲與我們的處理位於同一位置的表。它還爲我們提供了一種處理容錯的機制 - 通過將流存儲在Kafka代理中。

流處理器可以將其狀態保持在本地表(例如RocksDB)中,該表將從輸入流(可能在某些任意轉換之後)更新。當進程失敗時,它可以通過重放流來恢復其數據。

您甚至可以將遠程數據庫作爲流的生產者,有效地廣播用於在本地重建表的更改日誌。

[Kafka ]全面介紹Apache Kafka™

KSQL

通常,您將被迫使用JVM語言編寫流處理,因爲這是唯一的官方Kafka Streams API客戶端。

[Kafka ]全面介紹Apache Kafka™

發佈於2018年4月,KSQL是一項功能,允許您使用熟悉的類似SQL的語言編寫簡單的流媒體作業。

您設置了KSQL服務器並通過CLI以交互方式查詢它以管理處理。它使用相同的抽象(KStream和KTable),保證了Streams API的相同優點(可伸縮性,容錯性),並大大簡化了流的工作。

這聽起來可能不是很多,但在實踐中對於測試內容更有用,甚至允許開發之外的人(例如產品所有者)使用流處理。我鼓勵您查看快速啓動視頻,看看它有多簡單。

流替代品

Kafka溪流是力量與簡約的完美結合。它可以說是市場上流媒體工作的最佳功能,它與其他流處理選擇(Storm,Samza,Spark,Wallaroo)相比,更容易與Kafka集成。

大多數其他流處理框架的問題在於它們使用和部署起來很複雜。像Spark這樣的批處理框架需要:

  • 在一組計算機上控制大量作業,並在整個集羣中有效地分配它們。
  • 爲此,它必須動態地打包您的代碼並將其物理部署到將執行它的節點。 (以及配置,庫等)

不幸的是,解決這些問題使框架非常具有侵略性。他們希望控制代碼的部署,配置,監控和打包方式的許多方面。

Kafka Streams允許您在需要時推出自己的部署策略,無論是Kubernetes,Mesos,Nomad,Docker Swarm還是其他人。

Kafka Streams的基本動機是使所有應用程序能夠進行流處理,而無需運行和維護另一個集羣的操作複雜性。唯一潛在的缺點是它與卡夫卡緊密結合,但在現代世界中,大多數(如果不是全部)實時處理由卡夫卡提供動力可能不是一個很大的劣勢。

你什麼時候用Kafka?

正如我們已經介紹的那樣,Kafka允許您通過集中式介質獲取大量消息並存儲它們,而不必擔心性能或數據丟失等問題。

這意味着它非常適合用作系統架構的核心,充當連接不同應用程序的集中式媒體。 Kafka可以成爲事件驅動架構的中心部分,使您可以真正地將應用程序彼此分離。

[Kafka ]全面介紹Apache Kafka™

Kafka允許您輕鬆地分離不同(微)服務之間的通信。使用Streams API,現在可以比以往更輕鬆地編寫業務邏輯,從而豐富Kafka主題數據以供服務使用。可能性很大,我懇請您探討公司如何使用Kafka。

它爲什麼看到這麼多用途?

僅憑高性能,可用性和可擴展性並不足以使公司採用新技術。還有其他系統具有類似的特性,但沒有一個被廣泛使用。這是爲什麼?

Kafka越來越受歡迎(並且繼續這樣做)的原因是一個關鍵因素 - 現在的企業從事件驅動的架構中受益匪淺。這是因爲世界已經發生了變化 - 許多不同的服務(物聯網,機器學習,移動,微服務)正在生產和消費大量(並且不斷增長)的數據量。

具有持久存儲的單個實時事件廣播平臺是實現這種架構的最簡潔方式。想象一下,如果每個服務之間的流數據使用了一種特別適合它的不同技術,那將會是一種混亂。

這與Kafka爲這樣的通用系統(持久存儲,事件廣播,表和流原語,通過KSQL進行抽象,開源,積極開發)提供適當特性的事實相結合,使其成爲公司的明顯選擇。

摘要

Apache Kafka是一個分佈式流媒體平臺,每天可處理數萬億個事件。 Kafka提供低延遲,高吞吐量,容錯的發佈和訂閱管道,並能夠處理事件流。

我們回顧了它的基本語義(生產者,代理,消費者,主題),瞭解了它的一些優化(pagecache),通過複製數據瞭解了它的容錯能力,並介紹了它不斷增長的強大流媒體功能。

Kafka已經在全球數千家公司中大量採用,其中包括財富500強企業中的三分之一。隨着Kafka的積極開發和最近發佈的第一個主要版本1.0(2017年11月1日),有預測這個流媒體平臺將會與關係數據庫一樣,是數據平臺的重要核心。

我希望這篇介紹能幫助您熟悉Apache Kafka及其潛力。

進一步閱讀資源和我沒有提到的事情

以下是我沒有機會提到的一些功能,但重要的是要知道:

  • Controller Broker,同步副本 - Kafka保持集羣健康並確保足夠的一致性和持久性的方式。
  • Connector API - API幫助您將各種服務連接到Kafka作爲源或接收器(PostgreSQL,Redis,ElasticSearch)
  • 日誌壓縮 - 減少日誌大小的優化。在更改日誌流中非常有用
  • 完全一次的消息語義 - 保證消息只被接收一次。這是一個大問題,因爲很難實現。

資源

  • Apache Kafka的分佈式系統消防員(Firefighter)「鏈接」 - 控制器代理 ,深入探討經紀人之間的協調工作方式等等。
  • 彙總博客 「鏈接」「鏈接」- 關於Apache Kafka的大量信息
  • Kafka文檔 「鏈接」- 優秀,廣泛,高質量的文檔
  • Kafka Summit 2017視頻 「鏈接」

原文 「鏈接」

相关文章