Kafka學習筆記(一) :爲何須要Kafka?

咱們在學習一個東西的時候,每每只有真正瞭解它背後的含義,才能一步一步的掌握它,直到指揮若定。對於Kafka來講,我也是一個小白,本篇文章我就以一個小白的角度來初探一下Kafka,本篇文章基於官方文檔,順便說一句官方文檔真的很重要,且讀且珍惜。算法

背景

Kafka最先是由LinkedIn公司開發的,做爲其自身業務消息處理的基礎,後LinkedIn公司將Kafka捐贈給Apache,如今已經成爲Apache的一個頂級項目了,Kafka做爲一個高吞吐的分佈式的消息系統,目前已經被不少公司應用在實際的業務中了,而且與許多數據處理框架相結合,好比Hadoop,Spark等。數據庫

消息系統

在實際的業務需求中,咱們須要處理各類各樣的消息,好比Page View,日誌,請求等,那麼一個好的消息系統應該擁有哪些功能呢?api

  • 擁有消息發佈和訂閱的功能,相似於消息隊列或者企業消息傳送系統;
  • 能存儲消息流,並具有容錯性;
  • 可以實時的處理消息;

以上3點是做爲一個好的消息系統的最基本的能力。服務器

那麼Kafka爲何會誕生呢?框架

其實在咱們工做中,相信有不少也接觸過消息隊列,甚至本身也寫過簡單的消息系統,它最基本應該擁有發佈/訂閱的功能,以下圖所示:分佈式

simple-message-system

其中消費者A與消費者B都訂閱了消息源A和消息源B,這種模式很簡單,可是相對來講也有弊端,好比如下兩點:oop

  • 該模式下消費者須要實時去處理消息,由於這裏消息源和消費者都不會維護一個消息隊列(維護代價太大),這將會致使消費者如果暫時沒有能力消費,則消息會丟失,固然也就不能得到歷史的消息;
  • 消息源須要維護本來不屬於它的工做,好比維護訂閱者(消費者)的信息,向多個消費者發送消息,亦或者有些還須要處理消息反饋,這是本來純粹的消息源就會變得愈來愈複雜;

固然這些問題都是能夠改進的,好比咱們能夠在消息源和消費者中間增長一個消息隊列,以下圖所示:性能

simple-message-queue-system

從圖中咱們能夠看出,如今消息源只須要將消息發送到消息隊列中就行,至於其餘就將給消息隊列去完成,咱們能夠在消息隊列持久化消息,主動推消息給已經訂閱了該消息隊列的消費者,那麼這種模式還有什麼缺點嗎?學習

答案是有,上圖只是兩個消息隊列,咱們維護起來並不困難,可是若是有成百上千個呢?那不得gg,其實咱們能夠發現,消息隊列的功能都很相似,無非就是持久化消息,推送消息,給出反饋等功能,結構也很是相似,主要是消息內容,固然若是要通用化,消息結構也要儘量通用化,與具體平臺具體語言無關,好比用JSON格式等,全部咱們能夠演變出如下的消息系統:優化

message-system

這個方式看起來只是把上面的隊列合併到了一塊兒,其實並不那麼簡單,由於這個消息隊列集合要具有如下幾個功能:

  • 能統一管理全部的消息隊列,不是特殊需求不須要開發者本身去維護;
  • 高效率的存儲消息;
  • 消費者能快速的找到想要消費的消息;

固然這些只是最基本的功能,還有好比多節點容錯,數據備份等,一個好的消息系統須要處理的東西很是多,很慶幸,Kafka幫咱們作到了。

Kafka

在具體瞭解Kafka的細節前,咱們先來看一下它的一些基本概念:

  • Kafka是運行在一個集羣上,因此它能夠擁有一個或多個服務節點;
  • Kafka集羣將消息存儲在特定的文件中,對外表現爲Topics;
  • 每條消息記錄都包含一個key,消息內容以及時間戳;

從上面幾點咱們大體能夠推測Kafka是一個分佈式的消息存儲系統,那麼它就僅僅這麼點功能嗎,咱們繼續看下面。

Kafka爲了擁有更強大的功能,提供了四大核心接口:

  • Producer API容許了應用能夠向Kafka中的topics發佈消息;
  • Consumer API容許了應用能夠訂閱Kafka中的topics,並消費消息;
  • Streams API容許應用能夠做爲消息流的處理者,好比能夠從topicA中消費消息,處理的結果發佈到topicB中;
  • Connector API提供Kafka與現有的應用或系統適配功能,好比與數據庫鏈接器能夠捕獲表結構的變化;

它們與Kafka集羣的關係能夠用下圖表示:

kafka-apis

在瞭解了Kafka的一些基本概念後,咱們具體來看看它的一些組成部分。

Topics

顧名思義Topics是一些主題的集合,更通俗的說Topic就像一個消息隊列,生產者能夠向其寫入消息,消費者能夠從中讀取消息,一個Topic支持多個生產者或消費者同時訂閱它,因此其擴展性很好。Topic又能夠由一個或多個partition(分區)組成,好比下圖:

log-anatomy

其中每一個partition中的消息是有序的,但相互之間的順序就不能保證了,若Topic有多個partition,生產者的消息能夠指定或者由系統根據算法分配到指定分區,若你須要全部消息都是有序的,那麼你最好只用一個分區。另外partition支持消息位移讀取,消息位移有消費者自身管理,好比下圖:

log-consumer

由上圖能夠看出,不一樣消費者對同一分區的消息讀取互不干擾,消費者能夠經過設置消息位移(offset)來控制本身想要獲取的數據,好比能夠從頭讀取,最新數據讀取,重讀讀取等功能。

關於Topic的分區策略以及與消費者間平衡後續文章會繼續深刻講解。

Distribution

上文說到過,Kafka是一個分佈式的消息系統,因此當咱們配置了多個Kafka Server節點後,它就擁有分佈式的能力,好比容錯等,partition會被分佈在各個Server節點上,同時它們中間又有一個leader,它會處理全部的讀寫請求,其餘followers會複製leader上的數據信息,一旦當leader由於某些故障而沒法提供服務後,就會有一個follower被推舉出來成爲新的leader來處理這些請求。

Geo-Replication

異地備份是做爲主流分佈式系統的基礎功能,用於集羣中數據的備份和恢復,Kafka利用MirrorMaker來實現這個功能,用戶只需簡單的進行相應配置便可。

Producers

Producers做爲消息的生產者,能夠本身指定將消息發佈到訂閱Topic中的指定分區,策略能夠本身指定,好比語義或者結構相似的消息發佈在同一分區,固然也能夠由系統循環發佈在每個分區上。

Consumers

Consumers是一羣消費者的集合,能夠稱之爲消費者組,是一種更高層次的的抽象,向Topic訂閱消費消息的單位是Consumers,固然它其中也能夠只有一個消費者(consumer)。下面是關於consumer的兩條原則:

  • 假如全部消費者都在同一個消費者組中,那麼它們將協同消費訂閱Topic的部分消息(根據分區與消費者的數量分配),保存負載平衡;
  • 假如全部消費者都在不一樣的消費者組中,而且訂閱了同個Topic,那麼它們將能夠消費Topic的全部消息;

下面是一個簡單的例子,幫助你們理解:

consumer-groups

上圖中有兩個Server節點,有一個Topic被分爲四個分區(P0-P4)分別被分配在兩個節點上,另外還有兩個消費者組(GA,GB),其中GA有兩個消費者實例,GB有四個消費者實例。

從圖中咱們能夠看出,首先訂閱Topic的單位是消費者組,另外咱們發現Topic中的消息根據必定規則將消息推送給具體消費者,主要原則以下:

  • 若消費者數小於partition數,且消費者數爲一個,那麼它就消費全部消息;
  • 若消費者數小於partition數,假設消費者數爲N,partition數爲M,那麼每一個消費者能消費的分區數爲M/N或M/N+1;
  • 若消費者數等於partition數,那麼每一個消費者都會均等分配到一個分區的消息;
  • 若消費者數大於partition數,則將會出現部分消費者得不到消息分區,出現空閒的狀況;

總的來講,Kafka會根據消費者組的狀況均衡分配消息,好比有消息着實例宕機,亦或者有新的消費者加入等狀況。

Guarantees

kafka做爲一個高水準的系統,提供瞭如下的保證:

  • 消息的添加是有序的,生產者越早向訂閱的Topic發送的消息,會更早的被添加到Topic中,固然它們可能被分配到不一樣的分區;
  • 消費者在消費Topic分區中的消息時是有序的;
  • 對於有N個複製節點的Topic,系統能夠最多容忍N-1個節點發生故障,而不丟失任何提交給該Topic的消息丟失;

相關這些點的細節,我準備再後續文章中再慢慢深刻。

Kafka as a Messaging System

說了這麼多,前面也講了消息系統的演變過程,那麼Kafka相比其餘的消息系統優點具體在哪裏?
傳統的消息系統模型主要有兩種:消息隊列和發佈/訂閱。

1.消息隊列

特性 描述
表現形式 一組消費者從消息隊列中獲取消息,消息會被推送給組中的某一個消費者
優點 水平擴展,能夠將消息數據分開處理
劣勢 消息隊列不是多用戶的,當一條消息記錄被一個進程讀取後,消息便會丟失

2.發佈/訂閱

特性 描述
表現形式 消息會廣播發送給全部消費者
優點 能夠多進程共享消息
劣勢 每一個消費者都會得到全部消息,沒法經過添加消費進程提升處理效率

從上面兩個表中能夠看出兩種傳統的消息系統模型的優缺點,因此Kafka在前人的肩膀上進行了優化,吸取他們的優勢,主要體如今如下兩方面:

  • 經過Topic方式來達到消息隊列的功能
  • 經過消費者組這種方式來達到發佈/訂閱的功能

Kafka經過結合這兩點(這兩點的具體描述查看上面章節),完美的解決了它們二者模式的缺點。

Kafka as a Storage System

存儲消息也是消息系統的一大功能,Kafka相對普通的消息隊列存儲來講,它的表現實在好的太多,首先Kafka支持寫入確認,保證消息寫入的正確性和連續性,同時Kafka還會對寫入磁盤的數據進行復製備份,來實現容錯,另外Kafka對磁盤的使用結構是一致的,就說說無論你的服務器目前磁盤存儲的消息數據有多少,它添加消息數據的效率是相同的。

Kafka的存儲機制很好的支持消費者能夠隨意控制自身所須要讀取的數據,在不少時候你也能夠將Kafka做爲一個高性能,低延遲的分佈式文件系統。

Kafka for Stream Processing

Kafka做爲一個完美主義表明者,光有普通的讀寫,存儲等功能是不夠的,它還提供了實時處理消息流的接口。

不少時候原始的數據並非咱們想要的,咱們想要的是通過處理後的數據結果,好比經過一天的搜索數據得出當天的搜索熱點等,你能夠利用Streams API來實現本身想要的功能,好比從輸入Topic中獲取數據,而後再發布到具體的輸出Topic中。

Kafka的流處理能夠解決諸如處理無序數據、數據的複雜轉換等問題。

總結

消息傳遞、存儲、流處理這麼功能單一來看確實很普通,但如何把它們完美的結合到一塊兒,就是一種優雅的體現,Kafka作到了這一點。

相比HDFS分佈式文件存儲系統,雖然它能支持高效存儲而且批處理數據,可是它只支持處理過去的歷史數據。

相比普通的消息系統來講,雖然能處理如今至將來的數據,可是它並不沒有存儲歷史的數據。

Kafka集衆家之所長,使整個系統能兼顧各方面的需求,能夠用一個詞來講: 「完美」!

本文從消息系統的演變講起,到Kafka的具體組成,最後到Kafka的三大特性,旨在幫助你們可以大概的瞭解Kafka是什麼的,到底有什麼做用,固然這只是一個小白的簡單理解,若有寫得不對的地方,但願你們可以指出,不勝感激。

相關文章
相關標籤/搜索