全網最通俗易懂的Kafka入門
前言
只有光頭才能變強。
文字已收錄至我的GitHub倉庫,歡迎Star:https://github.com/ZhongFuCheng3y/3y
眾所周知,訊息佇列的產品有好幾種,這裡我選擇學習Kafka的原因,無他,公司在用。
我司使用的是Kafka和自研的訊息佇列(Kafka和RocketMQ)改版,於是我就想學學Kafka這款訊息佇列啦。本篇文章對Kafka入門,希望對大家有所幫助。
本文知識點提前預覽:
這篇文章花了我很長時間畫圖,目的是希望以最通俗易懂的方式帶大家入門,如果覺得不錯,希望能給我點個贊!
一、什麼是Kafka?
首先我們得去官網看看是怎麼介紹Kafka的:
https://kafka.apache.org/intro
在收集資料學習的時候,已經發現有不少的前輩對官網的介紹進行翻譯和總結了,所以我這裡就不重複了,貼下地址大家自行去學習啦:
https://scala.cool/2018/03/learning-kafka-1/
https://colobu.com/2014/08/06/kafka-quickstart/
我之前寫過的訊息佇列入門文章也提到了,要做一個訊息佇列可能要考慮到以下的問題:
使用訊息佇列不可能是單機的(必然是分散式or叢集)
資料寫到訊息佇列,可能會存在資料丟失問題,資料在訊息佇列需要持久化(磁碟?資料庫?Redis?分散式檔案系統?)
想要保證訊息(資料)是有序的,怎麼做?
為什麼在訊息佇列中重複消費了資料
下面我以Kafka為例對這些問題進行簡單的解答,進而入門Kafka。
1.1 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:https://github.com/ZhongFuCheng3y/3y
關鍵字:分散式、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,而消費者組有4個消費者,那麼一個消費者會空閒
如果多加入一個消費者組,無論是新增的消費者組還是原本的消費者組,都能消費topic的全部資料。(消費者組之間從邏輯上它們是獨立的)
前面講解到了生產者往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一個重要的依賴。
探測broker和consumer的新增或移除。
負責維護所有partition的領導者/從屬者關係(主分割槽和備份分割槽),如果主分割槽掛了,需要選舉出備份分割槽作為主分割槽。
維護topic、partition等元配置資訊
….
最後
通過這篇文章,文章開頭那幾個問題估計多多少少都懂一些啦。我來簡要回答一下:
使用訊息佇列不可能是單機的(必然是分散式or叢集)
Kafka天然是分散式的,往一個topic丟資料,實際上就是往多個broker的partition儲存資料
資料寫到訊息佇列,可能會存在資料丟失問題,資料在訊息佇列需要持久化(磁碟?資料庫?Redis?分散式檔案系統?)
Kafka會將partition以訊息日誌的方式(落磁碟)儲存起來,通過 順序訪問IO和快取(等到一定的量或時間)才真正把資料寫到磁碟上,來提高速度。
想要保證訊息(資料)是有序的,怎麼做?
Kafka會將資料寫到partition,單個partition的寫入是有順序的。如果要保證全域性有序,那隻能寫入一個partition中。如果要消費也有序,消費者也只能有一個。
為什麼在訊息佇列中重複消費了資料
凡是分散式就無法避免網路抖動/機器當機等問題的發生,很有可能消費者A讀取了資料,還沒來得及消費,就掛掉了。Zookeeper發現消費者A掛了,讓消費者B去消費原本消費者A的分割槽,等消費者A重連的時候,發現已經重複消費同一條資料了。(各種各樣的情況,消費者超時等等都有可能…)
如果業務上不允許重複消費的問題,最好消費者那端做業務上的校驗(如果已經消費過了,就不消費了)
這篇文章主要是Kafka入門,Kafka還涉及到別的概念,以及還有別的東西。在我感覺中,很多的面試題都跟配置有關,所以在解決某些問題的時候,先看看能不能通過現有配置解決掉(學多了框架,你就會發現很多官方的就已經支援解決了,你做的可能改改配置/引數就完事了)。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69900354/viewspace-2666745/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 全網最通俗易懂的Kafka入門!Kafka
- 全網最通俗易懂的【短連結】入門
- 全網最詳細的Spring入門教程Spring
- 通俗易懂的 Git入門Git
- 通俗易懂的 Deno 入門教程
- Kafka 入門Kafka
- Spring Boot的Kafka入門Spring BootKafka
- kafka入門案例Kafka
- Apache Kafka教程--Kafka新手入門ApacheKafka
- 通俗易懂的ArcGis開發快速入門
- Kafka簡單入門Kafka
- Kafka入門(1):概述Kafka
- kafka(docker) 入門分享KafkaDocker
- Kafka基礎入門Kafka
- kafka從入門到關門Kafka
- 通俗易懂:圖卷積神經網路入門詳解卷積神經網路
- (通俗易懂小白入門)網路流最大流——EK演算法演算法
- Kafka 入門與實踐Kafka
- kafka快速入門到精通Kafka
- Kafka基礎入門篇Kafka
- Kafka除錯入門(一)Kafka除錯
- 網際網路協議入門-通俗易懂的講計算機網路5層結構協議計算機網路
- Kafka 入門(四)-- Python Kafka Client 效能測試KafkaPythonclient
- 網際網路協議入門-通俗易懂的講計算機網路5層結構(二)協議計算機網路
- 圖解一致性雜湊演算法,全網(小區區域網)最通俗易懂圖解演算法
- 全網最清晰的ConstraintLayout教程AI
- Kafka 入門(三)--為什麼 Kafka 依賴 ZooKeeper?Kafka
- Kafka從入門到放棄(一) —— 初識KafkaKafka
- kafka入門安裝和使用Kafka
- Kafka Streams開發入門(1)Kafka
- Kafka 入門(一)--安裝配置和 kafka-python 呼叫KafkaPython
- Kafka【入門】就這一篇!Kafka
- Kafka入門(4):深入消費者Kafka
- Kafka入門(2):消費與位移Kafka
- 全網最適合入門的物件導向程式設計教程:36 Python的內建資料型別-字典物件程式設計Python資料型別
- 全網最適合入門的物件導向程式設計教程:00 物件導向設計方法導論物件程式設計
- 2019全網最實用的ppt素材網站!網站
- CAP理論—最通俗易懂的解釋