1. 程式人生 > >Kafka訊息佇列初識

Kafka訊息佇列初識

一、Kafka簡介

1.1 什麼是kafka

  kafka是一個分散式、高吞吐量、高擴充套件性的訊息佇列系統。kafka最初是由Linkedin公司開發的,後來在2010年貢獻給了Apache基金會,成為了一個開源專案。主要應用在日誌收集系統和訊息系統,相信大家之前也聽說過其他的訊息佇列中介軟體,比如RabbitMQ、AcitveMQ,其實kafka就是這麼一個東西,也可以叫做KafkaMQ。總之,Kafka比其他訊息佇列要好一點,優點也比較多,穩定性和效率都比較高,大家都說好,那就是真的好。

1.2 Kafka中的相關概念

  在理解Kafka的相關概念之前,我們先來看一張圖,這張圖基本上包括了Kafka所有的概念,對於我們理解Kafka十分有幫助。

  

  上圖中包含了2個Producer(生產者),一個Topic(主題),3個Partition(分割槽),3個Replica(副本),3個Broker(Kafka例項或節點),一個Consumer Group(消費者組),其中包含3個Consumer(消費者)。下面我們逐一介紹這些概念。

  1.2.1 Producer(生產者)

  生產者,顧名思義,就是生產東西的,也就是傳送訊息的,生產者每傳送一個條訊息必須有一個Topic(主題),也可以說是訊息的類別,生產者源源不斷的向kafka伺服器傳送訊息。

  1.2.2 Topic(主題)

  每一個傳送到Kafka的訊息都有一個主題,也可叫做一個類別,類似我們傳統資料庫中的表名一樣,比如說傳送一個主題為order的訊息,那麼這個order下邊就會有多條關於訂單的訊息,只不過kafka稱之為主題,都是一樣的道理。

  1.2.3 Partition(分割槽)

  生產者傳送的訊息資料Topic會被儲存在分割槽中,這個分割槽的概念和ElasticSearch中分片的概念是一致的,都是想把資料分成多個塊,好達到我們的負載均衡,合理的把訊息分佈在不同的分割槽上,分割槽是被分在不同的Broker上也就是伺服器上,這樣我們大量的訊息就實現了負載均衡。每個Topic可以指定多個分割槽,但是至少指定一個分割槽。每個分割槽儲存的資料都是有序的,不同分割槽間的資料不保證有序性。因為如果有了多個分割槽,消費資料的時候肯定是各個分割槽獨立開始的,有的消費得慢,有的消費得快肯定就不能保證順序了。那麼當需要保證訊息的順序消費時,我們可以設定為一個分割槽,只要一個分割槽的時候就只能消費這個一個分割槽,那自然就保證有序了。

  1.2.4 Replica(副本)

  副本就是分割槽中資料的備份,是Kafka為了防止資料丟失或者伺服器宕機採取的保護資料完整性的措施,一般的資料儲存軟體都應該會有這個功能。假如我們有3個分割槽,由於不同分割槽中存放的是部分資料,所以為了全部資料的完整性,我們就必須備份所有分割槽。這時候我們的一份副本就包括3個分割槽,每個分割槽中有一個副本,兩份副本就包含6個分割槽,一個分割槽兩份副本。Kafka做了副本之後同樣的會把副本分割槽放到不同的伺服器上,保證負載均衡。講到這我們就可以看見,這根本就是傳統資料庫中的主從複製的功能,沒錯,Kafka會找一個分割槽作為主分割槽(leader)來控制訊息的讀寫,其他的(副本)都是從分割槽(follower),這樣的話讀寫可以通過leader來控制,然後同步到副本上去,保證的資料的完整性。如果有某些伺服器宕機,我們可以通過副本恢復資料,也可以暫時用副本中的資料來使用。

  PS:這個東西實際跟ElasticSearch中的副本是完全一致的,不愧是一個爹出的東西,思想啥的都是一樣的。

  1.2.5 Broker(例項或節點)

  這個就好說了,意思就是Kafka的例項,啟動一個Kafka就是一個Broker,多個Brokder構成一個Kafka叢集,這就是分散式的體現,伺服器多了自然吞吐率效率啥的都上來了。

  1.2.6 Consumer Group(消費者組)和 Consumer(消費者)

  Consume消費者來讀取Kafka中的訊息,可以消費任何Topic的資料,多個Consume組成一個消費者組,一般的一個消費者必須有一個組(Group)名,如果沒有的話會被分一個預設的組名。

1.3 Kafka的架構與設計

  一般的來說,一個Kafka叢集包含一個或多個的Producer,一個或多個的Broker,一個或多個的Consumer Group,和一個Zookeeper叢集。Kafka通過Zookeeper管理叢集配置,管理叢集在執行過程中負責均衡、故障轉移和恢復什麼的。Producer使用Push(推送)的方式將訊息釋出到Broker,Consumer使用Pull(拉取)的方式從Broker獲取訊息,兩者都是主動操作的。

  1.3.1 Topic和Partition

  Kafka最初設計初衷就是高吞吐率、速度快。所以在對Topic和Partition的設計中,把Topic分成一個或者多個分割槽,每個Partition在物理磁碟上對應一個資料夾,該資料夾下儲存這個Partition的所有訊息和索引檔案。當我們建立一個Topic是,同時可以指定分割槽資料,數目越多,吞吐量越大,但是消耗的資源也越多,當我們向Kafka傳送訊息時,會均衡的將訊息分散儲存在不同的分割槽中。在儲存的過程中,每條訊息都是被順序寫到磁碟上的。(順序寫磁碟的時候比隨機寫記憶體的想效率還高,這也是Kafka快的一個原因之一)。

  下面是Kafka的寫入原理圖,可以看出下列訊息都是順序的,消費者消費的時候也是按著順序來消費的。

  

  對於傳統的MQ而言,一般經過消費後的訊息都會被刪除,而Kafka卻不會被刪除,始終保留著所有的訊息,只記錄一個消費者消費訊息的offset(偏移量)作為標記,可以允許消費者可以自己設定這個offset,從而可以重複消費一些訊息。但不刪除肯定不行,日積月累,訊息勢必會越來越多,佔用空間也越來越大。Kafka提供了兩種策略來刪除訊息:一是基於時間,二是基於Partition檔案的大小,可以通過配置來決定用那種方式。不過現在磁碟那麼廉價,空間也很大,隔個一年半載刪除一次也不為過。

  1.3.2 Producer

  生產者傳送訊息時,會根據Partition的策略來決定存到那個Partition中,一般的預設的策略是Kafka提供的均衡分佈的策略,即實現了我們所要的負載均衡。一般的,當我們的訊息對順序沒有要求的話那就多設定幾個分割槽,這樣就能很好地負載均衡增加吞吐量了。分割槽的個數可以手動配置,也可以在建立Topic的時候就事先指定。傳送訊息的時候,需要指定訊息的key值,Producer會根據這個key值和Partition的數量來決定這個訊息發到哪個分割槽,可能裡邊就是一個hash演算法。

  1.3.3 Consumer Group 和 Consumer

  我們知道傳統的訊息佇列有兩種傳播訊息的方式,一種是單播,類似佇列的方式,一個訊息只被消費一次,消費過了,其他消費者就不能消費了;另一種是多播,類似釋出-訂閱的模式,一個訊息可以被多個消費者同時消費。Kafka通過消費者組的方式來實現這兩種方式,在一個Consumer Group中,每一個Topic中的訊息只能被這個組中的一個Consumer消費,所以對於設定了多分割槽的Topic來說,分割槽的個數和消費者的個數應該是一樣的,一個消費者消費一個分割槽,這樣每個消費者就成了單播形式,類似佇列的消費形式。所以說,一個消費者組裡邊的消費者不能多於Topic的分割槽數,一旦多於,多出來的消費者就不能消費到訊息。另外,不同的消費者組可以同時消費一個訊息,這樣就實現了多播,類似釋出-訂閱的模式。我們可以設定每個組中一個消費者的方式來實現釋出-訂閱的模式。當我們有多個程式都要對訊息進行處理時,我們就可以把他們設定到不同的消費者組中,來實現不同的功能。

  好了,以上我們已經對Kafka有了一個初步的認識,接下來就可以來使用了。

二、Kafka的安裝與使用

  使用Kafka需要先安裝jdk,1.7以上的版本,配置好環境變數,這一步就不囉嗦了!!

2.1 下載Kafka

  下載地址:http://kafka.apache.org/downloads,找到下邊的Binary Downloads就行了,版本隨意選擇,不過最好選擇比較舊一點了,以防新的版本有新的改動啥的,導致我們踩坑,我選了下邊這個版本:

  

  下載之後直接解壓就行了,壓縮包格式是在linux上用的,不過一般的我們學習一個東西都可以先從windows上開始, 操作起來比較簡單,由於這種高階東西執行起來都是命令列,所以對於linux和windows就沒啥區別的了,到linux也是命令直接複製貼上就行了。

  

2.2 啟動Kakfa

  2.2.1 啟動Zookeeper

  因為Kafka依賴Zookeeper,所以要先啟動它,如下圖,定位到Kafka的目錄,我的是 F:\Dev\kafka_2.11-2.1.0。

  

  在位址列中輸出cmd,然後敲回車,瞬間開啟一個命令列,然後輸入:.\bin\windows\zookeeper-server-start.bat   .\config\zookeeper.properties,注意. 代表當前目錄,使用這個bat啟動Zookeeper並且使用後邊的配置。

  

  發現上邊那句話,並且沒報錯什麼的,表示Zookeeper啟動成功。

  2.2.2 啟動Kafka

  同樣,在位址列中輸出cmd,瞬間啟動一個命令列,然後輸入:.\bin\windows\kafka-server-start.bat .\config\server.properties

   

  發現上邊那句話,並且沒報錯什麼的,表示Kafka啟動成功。

  2.2.3 建立Topic

  同樣,進入到F:\Dev\kafka_2.11-2.1.0\bin\windows,在位址列中輸出cmd,瞬間啟動一個命令列,然後輸入:kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test,建立一個主題test。

  

  發現上邊那句話,並且沒報錯什麼的,表示主題Topic建立成功。

  2.2.4 建立Producer

  同樣,進入到F:\Dev\kafka_2.11-2.1.0\bin\windows,在位址列中輸出cmd,瞬間啟動一個命令列,然後輸入:kafka-console-producer.bat --broker-list localhost:9092 --topic test,建立一個Producer,準備生產主題為test的訊息。

  

  出現一個游標,表示等待生產訊息,一會我們可以輸入訊息。

  2.2.5 建立Consumer

  同樣,進入到F:\Dev\kafka_2.11-2.1.0\bin\windows,在位址列中輸出cmd,瞬間啟動一個命令列,然後輸入:kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic test --from-beginning,建立一個Consumer,準備消費主題為test的訊息。

  

  也會出現一個游標,等待顯示訊息。

  2.2.6 測試生產和消費

  在Producer控制檯輸入訊息,會在Consumer控制檯看見訊息:

  

   以上就是Kafka的搭建和使用,也不是那麼的複雜。我們在開發中肯定使用的是各類語言封裝過的驅動,java、.net的都差不多,先理解了原理,用起來就方便多了。

三、Kafka客戶端驅動的使用

   下面我們使用.net的Kafka驅動Confluent.Kafka,來看看是如果使用Kafka的,其他語言的小夥伴可以自行搜尋相關的驅動。

  3.1 建立應用

   如下圖,建立一個解決方案,新增兩個控制檯專案,一個作為生產者,一個作為消費者。

  

  3.2 新增Producer和Consumer類

  新增Producer類和Consumer類,配置中的server寫死為預設的Kafka伺服器的地址,如下圖所示:

  

  

     3.3 新增Program.cs中的啟動程式碼

   新增Producer的程式碼:

   

  新增Consumer的程式碼:

  

  3.4 啟動Kafka服務

  按照步驟2.2.1和2.2.2 啟動Zookeeper和Kafka,消費者和生產者就不用啟動了,我們用控制檯代替。

  3.4 啟動例項

  分別啟動Producer例項和Consumer例項,在Producer控制檯下輸入訊息,可以發現Consumer控制檯下顯示訊息,和前邊我們所做的是一致的。

  

  好了,以上就是Kafka的初步使用,有了這些基礎,我們就可以搭建一個訊息佇列開始處理訊息了。

   參考文章:https://www.cnblogs.com/xxinwen/p/10683416.html,https://www.cnblogs.com/qingyunzong/p/9004593.html

  程式碼託管到github,地址:https://github.com/EmmaCCC/KafkaStudy.git

四、總結

  到此為止,我們已經基本掌握了Kafka的使用,至於詳細的配置啥的等到我們用的時候再去研究,假如沒機會用到,那就不用去學了,不過用到用不到學了總是有用的,因為到時候簡歷上又可以寫上一項技能了:熟練使用Kafka搭建高併發分散式訊息佇列系統,承載千萬級別的訊息併發,之後的怎麼噴就看你自己了。