Kafka 介紹

Apache Kafka是一個分佈式流式平臺。數據庫

流平臺有三個關鍵的能力:

  • 發佈和訂閱記錄流,相似於消息隊列或企業消息傳遞系統。
  • 使用容錯耐用的方式存儲記錄流。
  • 記錄產生時處理數據。

Kafka主要是用在兩類應用中:

  • 在收數端和實時計算或批處理計算框架之間作數據通道
  • 做爲處理流式數據的應用

爲了解kafka怎麼處理這些事情,須要先了解一下概念:

  • Kafka是運行在一臺或者多臺服務器的集羣上的,而且能夠擴展到多個數據中心;
  • Kafka集羣以叫作topics的類別存儲流記錄;
  • 每一個記錄都由key,value,timestamp組成;

Kafka有4個核心API:

  • Producer API : 應用程序發佈流記錄到一個或者多個Kafka topics;
  • Consumer API : 應用程序訂閱一個或者多個topics而且處理產生的數據;
  • Streams API : 應用程序扮演着流處理器的角色,從一個或者多個輸入流中消費數據而且將產生的數據輸出到一個或者多個topic中。
  • Connector API:構建而且運行將Kafka topic鏈接到現有應用程序或數據系統的可重用生產者或消費者。 例如,關係數據庫的鏈接器可能捕獲對錶的每一個更改。

在Kafka中,客戶端和服務器之間的通訊是經過簡單,高性能,語言無關的TCP協議完成的。 此協議已版本化並保持與舊版本的向後兼容性。 咱們爲Kafka提供Java客戶端,但客戶端有多種語言版本。服務器

Topics and Logs

首先咱們先了解一下kafka記錄流提供的核心抽象-topic。負載均衡

Topic 是發佈記錄的類別或訂閱源名稱。kafka中topic 能夠有多個訂閱者, 便可以有0個,1個或者多個消費者訂閱。框架

對於每個topic,Kafka 的集羣都會維護着以下圖這樣的分區log:異步

每一個分區都是有序的、不可更高的記錄序列,這些記錄都是持續的被追加到結構化的commit log中。分區中的每一個記錄都會打上本分區惟一的被稱爲offset的序列id。分佈式

Kafka集羣負責將全部發布的記錄(不管是否消費)持久化,這些記錄都是有一個配置的保留時間。例如,若是保留時間設置的是兩天,那麼記錄發佈以後兩天內是能夠消費的,兩天以後就會被清除來事放空間。Kafka的性能在數據大小方面其實是恆定的,所以長時間存儲數據不是問題。函數

實際上,每一個消費者保留的惟一元數據是該消費者在log中的偏移量或位置。偏移量是由消費者來控制的:一般消費者在讀取記錄的時候會線性的推動其偏移量,可是實際上,既然消費者控制着消費的位置,就能夠以任意順序來消費記錄。例如消費者能夠從新設置偏移量來從新處理消費過的數據或者跳過最近的記錄從頭最新位置開始消費。工具

這些特性的結合就意味着Kafka消費者是很是cheap的,消費者的來去對於集羣或者其餘消費者沒有太多影響。例如,可使用命令行工具來查看任何一個topic中的內容而不會對其餘消費者消費的內容產生影響。性能

日誌中的分區有多種用途。首先,它們容許日誌擴展到超出單個服務器的大小。 每一個單獨的分區必須有託管它的服務器,但topic可能有許多分區,所以它能夠處理任意數量的數據。 其次,最重要的一點是它們充當了並行性的單位 。命令行

Distribution(分佈式)

log分區分佈在kafka集羣的服務器上,每一個服務器處理數據並請求分區的共享。每一個分區在服務器上都有配置的副本數量來容錯。

每一個分區都有一個服務器扮演者leader的角色,0個或者多個服務器扮演者followers的角色。leader處理這個分區的全部讀寫請求,follower被動的複製leader的數據。若是leader崩潰了,其中的follwers就會自動變成新的leader。每一個服務器都充當其某些分區的領導者和其餘服務器的追隨者,所以負載在羣集中獲得很好的平衡。

異地數據同步

Kafka MirrorMaker 爲集羣提供了異地數據同步工具。使用MirrorMaker,消息能夠跨多個數據中心或者雲進行復制同步。也可使用主/被的方式來備份或者恢復數據;或者主/主的方式來是數據更加靠近用戶。

Producers(生產者)

生產者發佈選擇的數據到topic中。消費者負責選擇記錄分配到topic的那個分區中。可使用round-robin方式簡單的進行負載均衡或者使用語義分區函數來作。

Consumers(消費者)

消費者經過consumer group name來標記,每條記錄都會發布到topic中後會被投遞到訂閱使用者組中一個消費者實例。消費實例能夠在單獨的進程中或者在單獨的機器上。

若是全部消費者都有一樣的消費組,那麼記錄將有效地在消費者實例上進行負載平衡;

若是全部的消費者有不一樣的消費組,那麼每條記錄都會廣播到全部的消費者實例上;

有四個分區(P0-P3)的Kafka 集羣,集羣有兩臺服務器,有兩個消費組。消費組A有兩個消費者實例,消費組B有4個消費實例。

然而,更常見的是,咱們發現主題具備少許的消費者羣體,每一個「邏輯訂閱者」一個。 每一個組由許多用於可伸縮性和容錯的消費者實例組成。 這只不過是發佈 - 訂閱語義,其中訂閱者是消費者羣集而不是單個進程。

Kafka實現的消費方式是在消費者實例上劃分日誌中的分區以便於每一個實例在任什麼時候間點都是每一個分區公平的獨佔消費者。維護組中成員資格的過程由Kafka協議動態處理。 若是新實例加入該組,他們將從該組的其餘成員接管一些分區; 若是實例死亡,其分區將分發給其他實例。

Kafka只能保證每一個分區的記錄數是有序的,不一樣分區之間不保證有序。每一個有序的分區加上使用key分區的能力對於大部分應用是足夠的。然而,你須要整體有序的話可使用一個分區的topic。這就意味着每一個消費組只有一個消費進程。

多租戶

能夠將Kafka部署爲多租戶解決方案。多租戶經過配置哪些topic能夠生產或者消費數據來啓用。也能夠選擇是否支持配額。管管理員能夠定義和強制執行配額,以控制客戶端使用的代理資源。

Guarantees(高可用)

高級別的Kafka提供了以下的保證:

  • 由生產者生產的消息發送到指定分區而且消息順序是發送的順序。這就意味着若是同一個生產者發送了兩條記錄M1,M2,M1先發送,那麼在log中M1就會有一個比M2更小的偏移量。
  • 一個消費者看見記錄的順序是在log中存儲的順序;
  • 對於一個有N個副本的topic,能夠容許有N-1個服務器崩潰而不丟失任何數據。

Kafka 做爲一個消息系統

Kafka 的流概念與傳統企業消息系統相好比何?

傳統消息系統有兩種模式:隊列和發佈訂閱。在隊列模式中,許多消費者從服務讀取數據,每條記錄都流向消費者之一;在發佈訂閱模式下數據會廣播到全部消費者那裏。這兩種模式都有好處和壞處。隊列的好處是能夠把處理數據的壓力分散到多個消費者實例上,這就能夠擴展處理能力。然而隊列不是多訂閱的,一旦數據被讀取了數據就沒。發佈訂閱能夠將數據廣播到全部的消費者那裏,缺點就是沒有辦法擴展處理能力因爲消息會廣播到每一個訂閱者那裏。

Kafka 消費組的概念綜合了這兩個概念。消費組做爲隊列來看是能夠把處理能力分散到多個進程上,做爲發佈訂閱,能夠將數據廣播到多個消費組。

Kafka 相比於傳統的消息系統的另外一個優點是有更好的順序保證。

傳統隊列在服務器上按照順序保存記錄,若是消費者從隊列中消費數據的時候,服務器會按照存儲的順序提供記錄。雖然服務器按照順序分發記錄,可是記錄是異步的傳遞到消費者那裏的,所以可能到達消費者的時候是亂序的。這就意味着在並行處理的消費上記錄是亂序的。消息傳遞系統一般經過具備「獨佔消費者」的概念來解決這個問題,該概念只容許一個進程從隊列中消耗,但這固然意味着處理中沒有並行性。

Kafka在這方面作的會更好。經過在topic中提出了一個parallelism—the partition—within 的概念 ,Kafka 可以在消費者流程池中提供訂購保證和負載平衡。這是經過將topic中的分區分配給使用者組中的使用者來實現的,以便每一個分區僅由該組中的一個使用者使用。 經過這樣作,咱們確保使用者是該分區的惟一讀者並按順序使用數據。 因爲有許多分區,這仍然可讓許多消費者實例的實現負載均衡。 但請注意,消費者組中的消費者實例不能超過度區。

Kafka 做爲存儲系統

任何容許發佈與消費消息分離的消息隊列實際上充當了正在進行的消息的存儲系統。 Kafka的不一樣之處在於它是一個很是好的存儲系統。

寫入Kafka的數據都寫入磁盤而且都有備份用來作容錯。Kafka容許生產者等待確認消息以便於副本寫入的完整性來確保數據仍然存在及時寫入服務器宕機。

Kafka很好的使用了磁盤的接口 -- 在服務器上不管是寫入50KB仍是50TB的數據,效率都是同樣的。

因爲是存儲系統,容許客戶端控制其讀取位置,能夠將Kafka視爲一種專用於高性能,低延遲提交日誌存儲,複製和傳播的專用分佈式文件系統

Kafka 做爲流處理系統

只有讀,寫,以及存儲流數據仍是不夠的,目的是實現流的實時處理。

Kafka 的流處理器是從輸入topic的獲取流數據,在輸入中執行一些處理操做,最後將處理結果輸出到topic中。

例如,零售應用可能會將銷量以及出貨量做爲輸入流,而後將從新排序以及價格調整之後的數據輸出到topic中。

直接使用生產者或者消費者API就能夠作一些簡單的處理。而後對於複雜的變換處理,kafka 提供了提供了一整套集成的Stream API。這就能夠構建計算流的聚合或者流join這樣不通常的應用。

這總便利幫助咱們解決了這類應用面對的難題:處理亂序數據,代碼變更須要從新處理,執行有狀態的計算等等。

流API創建在Kafka提供的核心原語上:使用生產者消費者API做爲輸入,使用Kafka做爲有狀態的存儲,在流處理實例間使用相同組的機制進行容錯。

總結

將消息,存儲以及流處理結合起來看似不是很常見,可是對於Kafka這種角色的流處理平臺十分重要的。

像HDFS這樣的分佈式文件系統存儲靜態文件進行批處理。這樣的系統容許存儲和處理過去的歷史數據。

傳統的企業級消息系統能夠處理訂閱之後即將到來的消息,應用內建這個方式來處理即將到來的數據。

Kafka 將這些能力都融合進來,同時這種組合對於Kafka做爲流媒體應用程序平臺以及流數據管道的使用相當重要。

經過組合存儲和低延遲訂閱,流應用程序能夠以相同的方式處理過去和將來的數據。 也就是說,單個應用程序能夠處理歷史存儲的數據,而不是在它到達最後一條記錄時結束,它能夠在將來數據到達時繼續處理。 這是包含批處理以及消息驅動應用程序的流處理的通常概念。

一樣,對於流數據流水線,訂閱實時事件的組合使得能夠將Kafka用於極低延遲的流水線; 可是,可以可靠地存儲數據使得能夠將其用於必須保證數據傳輸的關鍵數據,或者與僅按期加載數據或可能長時間停機以進行維護的離線系統集成。 流處理設施能夠在數據到達時對其進行轉換。

點擊該連接,獲取博客解鎖驗證碼

相關文章
相關標籤/搜索