只有光頭才能變強。git
文本已收錄至個人GitHub倉庫,歡迎Star:github.com/ZhongFuChen…github
在這篇以前已經寫過兩篇基礎文章了,強烈建議先去閱讀:面試
衆所周知,消息隊列的產品有好幾種,這裏我選擇學習Kafka的緣由,無他,公司在用。數據庫
我司使用的是Kafka和自研的消息隊列(Kafka和RocketMQ)改版,因而我就想學學Kafka這款消息隊列啦。本篇文章對Kafka入門,但願對你們有所幫助。apache
本文知識點提早預覽:緩存
這篇文章花了我很長時間畫圖,目的是但願以最通俗易懂的方式帶你們入門,若是以爲不錯,但願能給我點個贊!服務器
首先咱們得去官網看看是怎麼介紹Kafka的:網絡
在收集資料學習的時候,已經發現有很多的前輩對官網的介紹進行翻譯和總結了,因此我這裏就不重複了,貼下地址你們自行去學習啦:框架
我以前寫過的消息隊列入門文章也提到了,要作一個消息隊列可能要考慮到如下的問題:分佈式
下面我以Kafka爲例對這些問題進行簡單的解答,進而入門Kafka。
衆所周知,Kafka是一個消息隊列,把消息放到隊列裏邊的叫生產者,從隊列裏邊消費的叫消費者。
一個消息中間件,隊列不僅僅只有一個,咱們每每會有多個隊列,而咱們生產者和消費者就得知道:把數據丟給哪一個隊列,從哪一個隊列消息。咱們須要給隊列取名字,叫作topic(至關於數據庫裏邊表的概念)
如今咱們給隊列取了名字之後,生產者就知道往哪一個隊列丟數據了,消費者也知道往哪一個隊列拿數據了。咱們能夠有多個生產者**往同一個隊列(topic)丟數據,多個消費者往同一個隊列(topic)**拿數據
爲了提升一個隊列(topic)的吞吐量,Kafka會把topic進行分區(Partition)
因此,生產者其實是往一個topic名爲Java3y中的分區(Partition)丟數據,消費者其實是往一個topic名爲Java3y的分區(Partition)取數據
一臺Kafka服務器叫作Broker,Kafka集羣就是多臺Kafka服務器:
一個topic會分爲多個partition,實際上partition會分佈在不一樣的broker中,舉個例子:
由此得知: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 操做。
上面balabala地都是講生產者把數據丟進topic是怎麼樣的,下面來說講消費者是怎麼消費的。既然數據是保存在partition中的,那麼消費者實際上也是從partition中取數據。
生產者能夠有多個,消費者也能夠有多個。像上面圖的狀況,是一個消費者消費三個分區的數據。多個消費者能夠組成一個消費者組。
原本是一個消費者消費三個分區的,如今咱們有消費者組,就能夠每一個消費者去消費一個分區(也是爲了提升吞吐量)
按圖上所示的狀況,這裏想要說明的是:
前面講解到了生產者往topic裏丟數據是存在partition上的,而partition持久化到磁盤是IO順序訪問的,而且是先寫緩存,隔一段時間或者數據量足夠大的時候才批量寫入磁盤的。
消費者在讀的時候也頗有講究:正常的讀磁盤數據是須要將內核態數據拷貝到用戶態的,而Kafka 經過調用sendfile()
直接從內核空間(DMA的)到內核空間(Socket的),少作了一步拷貝的操做。
有的同窗可能會產生疑問:消費者是怎麼知道本身消費到哪裏的呀?Kafka不是支持回溯嗎?那是怎麼作的呀?
這裏要引出offset
了,Kafka就是用offset
來表示消費者的消費進度到哪了,每一個消費者會都有本身的offset
。說白了offset
就是表示消費者的消費進度。
在之前版本的Kafka,這個offset
是由Zookeeper來管理的,後來Kafka開發者認爲Zookeeper不合適大量的刪改操做,因而把offset
在broker之內部topic(__consumer_offsets
)的方式來保存起來。
每次消費者消費的時候,都會提交這個offset
,Kafka可讓你選擇是自動提交仍是手動提交。
既然提到了Zookeeper,那就多說一句。Zookeeper雖然在新版的Kafka中沒有用做於保存客戶端的offset
,可是Zookeeper是Kafka一個重要的依賴。
服務器89/年,229/3年,買來送本身,送女友立刻過年再合適不過了,買了搭建個項目給面試官看也香,還能夠熟悉技術棧,(老用戶用家人帳號買就行了,我用我女友的😂)。掃碼或者點擊購買
經過這篇文章,文章開頭那幾個問題估計多多少少都懂一些啦。我來簡要回答一下:
使用消息隊列不多是單機的(必然是分佈式or集羣)
Kafka自然是分佈式的,往一個topic丟數據,實際上就是往多個broker的partition存儲數據
數據寫到消息隊列,可能會存在數據丟失問題,數據在消息隊列須要持久化(磁盤?數據庫?Redis?分佈式文件系統?)
Kafka會將partition以消息日誌的方式(落磁盤)存儲起來,經過 順序訪問IO和緩存(等到必定的量或時間)才真正把數據寫到磁盤上,來提升速度。
想要保證消息(數據)是有序的,怎麼作?
Kafka會將數據寫到partition,單個partition的寫入是有順序的。若是要保證全局有序,那隻能寫入一個partition中。若是要消費也有序,消費者也只能有一個。
爲何在消息隊列中重複消費了數據
凡是分佈式就沒法避免網絡抖動/機器宕機等問題的發生,頗有可能消費者A讀取了數據,還沒來得及消費,就掛掉了。Zookeeper發現消費者A掛了,讓消費者B去消費本來消費者A的分區,等消費者A重連的時候,發現已經重複消費同一條數據了。(各類各樣的狀況,消費者超時等等都有可能...)
若是業務上不容許重複消費的問題,最好消費者那端作業務上的校驗(若是已經消費過了,就不消費了)
這篇文章主要是Kafka入門,Kafka還涉及到別的概念,以及還有別的東西。在我感受中,不少的面試題都跟配置有關,因此在解決某些問題的時候,先看看能不能經過現有配置解決掉(學多了框架,你就會發現不少官方的就已經支持解決了,你作的可能改改配置/參數就完事了)。
本已收錄至個人GitHub精選文章,歡迎Star:github.com/ZhongFuChen…
樂於輸出乾貨的Java技術公衆號:Java3y。公衆號內有300多篇原創技術文章、海量視頻資源、精美腦圖,關注便可獲取!
很是感謝人才們能看到這裏,若是這個文章寫得還不錯,以爲「三歪」我有點東西的話 求點贊 求關注️ 求分享👥 求留言💬 對暖男我來講真的 很是有用!!!
創做不易,各位的支持和承認,就是我創做的最大動力,咱們下篇文章見!