為什麼要使用Kafka?

2021-09-11 04:05:13 字數 3846 閱讀 4744

我們在學習乙個東西的時候,往往只有真正了解它背後的含義,才能一步一步的掌握它,直到運籌帷幄。對於kafka來說,我也是乙個小白,本篇文章我就以乙個小白的角度來初探一下kafka,本篇文章基於官方文件,順便說一句官方文件真的很重要,且讀且珍惜。

kafka最早是由linkedin公司開發的,作為其自身業務訊息處理的基礎,後linkedin公司將kafka捐贈給apache,現在已經成為apache的乙個頂級專案了,kafka作為乙個高吞吐的分布式的訊息系統,目前已經被很多公司應用在實際的業務中了,並且與許多資料處理框架相結合,比如hadoop,spark等。

在實際的業務需求中,我們需要處理各種各樣的訊息,比如page view,日誌,請求等,那麼乙個好的訊息系統應該擁有哪些功能呢?

以上3點是作為乙個好的訊息系統的最基本的能力。

那麼kafka為什麼會誕生呢?

其實在我們工作中,相信有很多也接觸過訊息佇列,甚至自己也寫過簡單的訊息系統,它最基本應該擁有發布/訂閱的功能,如下圖所示:

其中消費者a與消費者b都訂閱了訊息源a和訊息源b,這種模式很簡單,但是相對來說也有弊端,比如以下兩點:

當然這些問題都是可以改進的,比如我們可以在訊息源和消費者中間增加乙個訊息佇列,如下圖所示:

從圖中我們可以看出,現在訊息源只需要將訊息傳送到訊息佇列中就行,至於其他就將給訊息佇列去完成,我們可以在訊息佇列持久化訊息,主動推訊息給已經訂閱了該訊息佇列的消費者,那麼這種模式還有什麼缺點嗎?

答案是有,上圖只是兩個訊息佇列,我們維護起來並不困難,但是如果有成百上千個呢?那不得gg,其實我們可以發現,訊息佇列的功能都很類似,無非就是持久化訊息,推送訊息,給出反饋等功能,結構也非常類似,主要是訊息內容,當然如果要通用化,訊息結構也要盡可能通用化,與具體平台具體語言無關,比如用json格式等,所有我們可以演變出以下的訊息系統:

這個方式看起來只是把上面的佇列合併到了一起,其實並不那麼簡單,因為這個訊息佇列集合要具備以下幾個功能:

當然這些只是最基本的功能,還有比如多節點容錯,資料備份等,乙個好的訊息系統需要處理的東西非常多,很慶幸,kafka幫我們做到了。

在具體了解kafka的細節前,我們先來看一下它的一些基本概念:

從上面幾點我們大致可以推測kafka是乙個分布式的訊息儲存系統,那麼它就僅僅這麼點功能嗎,我們繼續看下面。

kafka為了擁有更強大的功能,提供了四大核心介面:

它們與kafka集群的關係可以用下圖表示:

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

topics

顧名思義topics是一些主題的集合,更通俗的說topic就像乙個訊息佇列,生產者可以向其寫入訊息,消費者可以從中讀取訊息,乙個topic支援多個生產者或消費者同時訂閱它,所以其擴充套件性很好。topic又可以由乙個或多個partition(分割槽)組成,比如下圖:

其中每個partition中的訊息是有序的,但相互之間的順序就不能保證了,若topic有多個partition,生產者的訊息可以指定或者由系統根據演算法分配到指定分割槽,若你需要所有訊息都是有序的,那麼你最好只用乙個分割槽。另外partition支援訊息位移讀取,訊息位移有消費者自身管理,比如下圖:

由上圖可以看出,不同消費者對同一分割槽的訊息讀取互不干擾,消費者可以通過設定訊息位移(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的兩條原則:

上圖中有兩個server節點,有乙個topic被分為四個分割槽(p0-p4)分別被分配在兩個節點上,另外還有兩個消費者組(ga,gb),其中ga有兩個消費者例項,gb有四個消費者例項。

從圖中我們可以看出,首先訂閱topic的單位是消費者組,另外我們發現topic中的訊息根據一定規則將訊息推送給具體消費者,主要原則如下:

總的來說,kafka會根據消費者組的情況均衡分配訊息,比如有訊息著例項宕機,亦或者有新的消費者加入等情況。

guarantees

kafka作為乙個高水準的系統,提供了以下的保證:

說了這麼多,前面也講了訊息系統的演變過程,那麼kafka相比其他的訊息系統優勢具體在**?

傳統的訊息系統模型主要有兩種:訊息佇列和發布/訂閱。

1.訊息佇列

特性描述

表現形式

一組消費者從訊息佇列中獲取訊息,訊息會被推送給組中的某乙個消費者

優勢水平擴充套件,可以將訊息資料分開處理

劣勢訊息佇列不是多使用者的,當一條訊息記錄被乙個程序讀取後,訊息便會丟失

2.發布/訂閱

特性描述

表現形式

訊息會廣播傳送給所有消費者

優勢可以多程序共享訊息

劣勢每個消費者都會獲得所有訊息,無法通過新增消費程序提高處理效率

從上面兩個表中可以看出兩種傳統的訊息系統模型的優缺點,所以kafka在前人的肩膀上進行了優化,吸收他們的優點,主要體現在以下兩方面:

kafka通過結合這兩點(這兩點的具體描述檢視上面章節),完美的解決了它們兩者模式的缺點。

儲存訊息也是訊息系統的一大功能,kafka相對普通的訊息佇列儲存來說,它的表現實在好的太多,首先kafka支援寫入確認,保證訊息寫入的正確性和連續性,同時kafka還會對寫入磁碟的資料進行複製備份,來實現容錯,另外kafka對磁碟的使用結構是一致的,就說說不管你的伺服器目前磁碟儲存的訊息資料有多少,它新增訊息資料的效率是相同的。

kafka的儲存機制很好的支援消費者可以隨意控制自身所需要讀取的資料,在很多時候你也可以將kafka作為乙個高效能,低延遲的分布式檔案系統。

kafka作為乙個完美主義代表者,光有普通的讀寫,儲存等功能是不夠的,它還提供了實時處理訊息流的介面。

很多時候原始的資料並不是我們想要的,我們想要的是經過處理後的資料結果,比如通過一天的搜尋資料得出當天的搜尋熱點等,你可以利用streams api來實現自己想要的功能,比如從輸入topic中獲取資料,然後再發布到具體的輸出topic中。

kafka的流處理可以解決諸如處理無序資料、資料的複雜轉換等問題。

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

相比hdfs分布式檔案儲存系統,雖然它能支援高效儲存並且批處理資料,但是它只支援處理過去的歷史資料。

相比普通的訊息系統來說,雖然能處理現在至未來的資料,但是它並不沒有儲存歷史的資料。

kafka集眾家之所長,使整個系統能兼顧各方面的需求,可以用乙個詞來說: 「完美」!

本文從訊息系統的演變講起,到kafka的具體組成,最後到kafka的三大特性,旨在幫助大家能夠大概的了解kafka是什麼的,到底有什麼作用,當然這只是乙個小白的簡單理解,如有寫得不對的地方,希望大家能夠指出,不勝感激。

為什麼要使用blog

有哥們問我,你為什麼使用blog?我總結了一下,覺得有如下幾個原因。1對自己的督促 有了blog,就會經常記得寫點東西 就會經常翻翻網上的新文章,了解一下新技術,不至於迷失在忙碌的生活中 如果把自己的所感所想所學寫出了,自己對自己也會有個概念,不至於迷迷糊糊 還有,畢竟是掛在網上的文字,心中難免擔心...

為什麼要使用XML

xml 代表擴充套件標記語言 extensible markup language 是由 world wide web consortium w 3c 的 xml工作組定義的。這個工作組是這樣描述該語言的 擴充套件標記語言 xml 是 sgml 的子集,其目標是允許普通的 sgml 在web 上以目...

為什麼要使用Nginx?

有人說這些基準測試是不準確的,因為在這樣那樣的環境下,做的比較不一致。我傾向同意基準測試只是告訴了我們其中一部分情況,你能做的是消除偏見 有人見過所有人都同意乙個基準測試是公平的嗎?我是沒見過。我們投資的一些公司把web平台切換到nginx後,可以顯著的解決擴充套件問題。nginx明顯有效的實現了今...