全網最通俗易懂的Kafka入門!

前言

只有光頭才能變強。git

文本已收錄至個人GitHub倉庫,歡迎Star:github.com/ZhongFuChen…github

在這篇以前已經寫過兩篇基礎文章了,強烈建議先去閱讀:面試

衆所周知,消息隊列的產品有好幾種,這裏我選擇學習Kafka的緣由,無他,公司在用。數據庫

我司使用的是Kafka和自研的消息隊列(Kafka和RocketMQ)改版,因而我就想學學Kafka這款消息隊列啦。本篇文章對Kafka入門,但願對你們有所幫助。apache

本文知識點提早預覽:緩存

提早預覽

這篇文章花了我很長時間畫圖,目的是但願以最通俗易懂的方式帶你們入門,若是以爲不錯,但願能給我點個贊服務器

1、什麼是Kafka?

首先咱們得去官網看看是怎麼介紹Kafka的:網絡

在收集資料學習的時候,已經發現有很多的前輩對官網的介紹進行翻譯和總結了,因此我這裏就不重複了,貼下地址你們自行去學習啦:框架

我以前寫過的消息隊列入門文章也提到了,要作一個消息隊列可能要考慮到如下的問題:分佈式

  • 使用消息隊列不多是單機的(必然是分佈式or集羣)
  • 數據寫到消息隊列,可能會存在數據丟失問題,數據在消息隊列須要持久化(磁盤?數據庫?Redis?分佈式文件系統?)
  • 想要保證消息(數據)是有序的,怎麼作?
  • 爲何在消息隊列中重複消費了數據

下面我以Kafka爲例對這些問題進行簡單的解答,進而入門Kafka。

1.1 Kafka入門

衆所周知,Kafka是一個消息隊列,把消息放到隊列裏邊的叫生產者,從隊列裏邊消費的叫消費者

生產者和消費者

一個消息中間件,隊列不僅僅只有一個,咱們每每會有多個隊列,而咱們生產者和消費者就得知道:把數據丟給哪一個隊列,從哪一個隊列消息。咱們須要給隊列取名字,叫作topic(至關於數據庫裏邊的概念)

給隊列取名字,專業名詞叫topic

如今咱們給隊列取了名字之後,生產者就知道往哪一個隊列丟數據了,消費者也知道往哪一個隊列拿數據了。咱們能夠有多個生產者**往同一個隊列(topic)丟數據,多個消費者往同一個隊列(topic)**拿數據

爲了提升一個隊列(topic)的吞吐量,Kafka會把topic進行分區(Partition)

Kafka分區

因此,生產者其實是往一個topic名爲Java3y中的分區(Partition)丟數據,消費者其實是往一個topic名爲Java3y的分區(Partition)取數據

生產者和消費者實際上操做的是分區

一臺Kafka服務器叫作Broker,Kafka集羣就是多臺Kafka服務器:

Kafka集羣

一個topic會分爲多個partition,實際上partition會分佈在不一樣的broker中,舉個例子:

一個生產者丟數據給topic

由此得知:Kafka是自然分佈式的

若是不瞭解分佈式/集羣,以及基本的分佈式概念的同窗,能夠關注個人GitHub:github.com/ZhongFuChen…

關鍵字:分佈式、SpringCloud 保證能讓你搞懂。以爲我寫得不錯,就給我點個贊

如今咱們已經知道了往topic裏邊丟數據,實際上這些數據會分到不一樣的partition上,這些partition存在不一樣的broker上。分佈式確定會帶來問題:「萬一其中一臺broker(Kafka服務器)出現網絡抖動或者掛了,怎麼辦?」

Kafka是這樣作的:咱們數據存在不一樣的partition上,那kafka就把這些partition作備份。好比,如今咱們有三個partition,分別存在三臺broker上。每一個partition都會備份,這些備份散落在不一樣的broker上。

紅色表明主分區,紫色表明備份分區

紅色塊的partition表明的是分區,紫色的partition塊表明的是備份分區。生產者往topic丟數據,是與分區交互,消費者消費topic的數據,也是與主分區交互。

備份分區僅僅用做於備份,不作讀寫。若是某個Broker掛了,那就會選舉出其餘Broker的partition來做爲主分區,這就實現了高可用

另外值得一提的是:當生產者把數據丟進topic時,咱們知道是寫在partition上的,那partition是怎麼將其持久化的呢?(不持久化若是Broker中途掛了,那確定會丟數據嘛)。

Kafka是將partition的數據寫在磁盤的(消息日誌),不過Kafka只容許追加寫入(順序訪問),避免緩慢的隨機 I/O 操做。

  • Kafka也不是partition一有數據就立馬將數據寫到磁盤上,它會先緩存一部分,等到足夠多數據量或等待必定的時間再批量寫入(flush)。

上面balabala地都是講生產者把數據丟進topic是怎麼樣的,下面來說講消費者是怎麼消費的。既然數據是保存在partition中的,那麼消費者實際上也是從partition中取數據。

從各個主分區取數據

生產者能夠有多個,消費者也能夠有多個。像上面圖的狀況,是一個消費者消費三個分區的數據。多個消費者能夠組成一個消費者組

消費者組

原本是一個消費者消費三個分區的,如今咱們有消費者組,就能夠每一個消費者去消費一個分區(也是爲了提升吞吐量)

消費者組的每一個消費者會去對應partition拿數據

按圖上所示的狀況,這裏想要說明的是:

  • 若是消費者組中的某個消費者掛了,那麼其中一個消費者可能就要消費兩個partition了
  • 若是隻有三個partition,而消費者組有4個消費者,那麼一個消費者會空閒
  • 若是多加入一個消費者組,不管是新增的消費者組仍是本來的消費者組,都能消費topic的所有數據。(消費者組之間從邏輯上它們是獨立的)

前面講解到了生產者往topic裏丟數據是存在partition上的,而partition持久化到磁盤是IO順序訪問的,而且是先寫緩存,隔一段時間或者數據量足夠大的時候才批量寫入磁盤的。

消費者在讀的時候也頗有講究:正常的讀磁盤數據是須要將內核態數據拷貝到用戶態的,而Kafka 經過調用sendfile()直接從內核空間(DMA的)到內核空間(Socket的),少作了一步拷貝的操做。

Kafka 讀數據 巧妙

有的同窗可能會產生疑問:消費者是怎麼知道本身消費到哪裏的呀?Kafka不是支持回溯嗎?那是怎麼作的呀?

  • 好比上面也提到:若是一個消費者組中的某個消費者掛了,那掛掉的消費者所消費的分區可能就由存活的消費者消費。那存活的消費者是須要知道掛掉的消費者消費到哪了,否則怎麼玩。

這裏要引出offset了,Kafka就是用offset來表示消費者的消費進度到哪了,每一個消費者會都有本身的offset。說白了offset就是表示消費者的消費進度

在之前版本的Kafka,這個offset是由Zookeeper來管理的,後來Kafka開發者認爲Zookeeper不合適大量的刪改操做,因而把offset在broker之內部topic(__consumer_offsets)的方式來保存起來。

每次消費者消費的時候,都會提交這個offset,Kafka可讓你選擇是自動提交仍是手動提交。

既然提到了Zookeeper,那就多說一句。Zookeeper雖然在新版的Kafka中沒有用做於保存客戶端的offset,可是Zookeeper是Kafka一個重要的依賴。

  • 探測broker和consumer的添加或移除。
  • 負責維護全部partition的領導者/從屬者關係(主分區和備份分區),若是主分區掛了,須要選舉出備份分區做爲主分區。
  • 維護topic、partition等元配置信息
  • ....

這張圖來源胡夕老師的《Kafka核心技術與實戰》

最後

服務器89/年,229/3年,買來送本身,送女友立刻過年再合適不過了,買了搭建個項目給面試官看也香,還能夠熟悉技術棧,(老用戶用家人帳號買就行了,我用我女友的😂)。掃碼或者點擊購買

搭建教程,從0開始一步一步帶你搭建😂

經過這篇文章,文章開頭那幾個問題估計多多少少都懂一些啦。我來簡要回答一下:

使用消息隊列不多是單機的(必然是分佈式or集羣)

Kafka自然是分佈式的,往一個topic丟數據,實際上就是往多個broker的partition存儲數據

數據寫到消息隊列,可能會存在數據丟失問題,數據在消息隊列須要持久化(磁盤?數據庫?Redis?分佈式文件系統?)

Kafka會將partition以消息日誌的方式(落磁盤)存儲起來,經過 順序訪問IO和緩存(等到必定的量或時間)才真正把數據寫到磁盤上,來提升速度。

想要保證消息(數據)是有序的,怎麼作?

Kafka會將數據寫到partition,單個partition的寫入是有順序的。若是要保證全局有序,那隻能寫入一個partition中。若是要消費也有序,消費者也只能有一個。

爲何在消息隊列中重複消費了數據

凡是分佈式就沒法避免網絡抖動/機器宕機等問題的發生,頗有可能消費者A讀取了數據,還沒來得及消費,就掛掉了。Zookeeper發現消費者A掛了,讓消費者B去消費本來消費者A的分區,等消費者A重連的時候,發現已經重複消費同一條數據了。(各類各樣的狀況,消費者超時等等都有可能...)

若是業務上不容許重複消費的問題,最好消費者那端作業務上的校驗(若是已經消費過了,就不消費了)


這篇文章主要是Kafka入門,Kafka還涉及到別的概念,以及還有別的東西。在我感受中,不少的面試題都跟配置有關,因此在解決某些問題的時候,先看看能不能經過現有配置解決掉(學多了框架,你就會發現不少官方的就已經支持解決了,你作的可能改改配置/參數就完事了)。

本已收錄至個人GitHub精選文章,歡迎Stargithub.com/ZhongFuChen…

樂於輸出乾貨的Java技術公衆號:Java3y。公衆號內有300多篇原創技術文章、海量視頻資源、精美腦圖,關注便可獲取!

轉發到朋友圈是對我最大的支持!

很是感謝人才們能看到這裏,若是這個文章寫得還不錯,以爲「三歪」我有點東西的話 求點贊 求關注️ 求分享👥 求留言💬 對暖男我來講真的 很是有用!!!

創做不易,各位的支持和承認,就是我創做的最大動力,咱們下篇文章見!

相關文章
相關標籤/搜索