20200103 kafka基礎

kafka使用場景,kafka優勢,kafka相關概念,zookeeper集羣搭建,kafka集羣搭建

有應用場景纔有意義

 

kafka的定義:是一個分佈式消息系統,或者說消息中間件,由LinkedIn使用Scala編寫,具有高水平擴展和高吞吐量。

應用領域:已被多家不同類型的公司作爲多種類型的數據管道和消息系統使用。如:淘寶,支付寶,百度,twitter等。目前越來越多的開源分佈式處理系統都支持與Kafka集成。

Kafka架構:

 

數據分區,消費分組;

高級消息隊列協議一些基本的概念:

•AMQP協議:高級消息隊列協議

•AMQP服務器端(broker):用來接收生產者發送的消息並將這些消息路由給服務器中的隊列;消息隊列服務器或者說kafka服務器

Broker:Kafka 集羣包含一個或多個服務器,這種服務器被稱爲 broker。

Topic:每條發佈到 Kafka 集羣的消息都有一個類別,這個類別被稱爲 Topic。(物理上不同 Topic 的消息分開存儲,邏輯上一個 Topic 的消息雖然保存於一個或多個 broker 上,但用戶只需指定消息的 Topic 即可生產或消費數據而不必關心數據存於何處)。特指Kafka處理的消息源(feeds of messages)的不同分類。

Partition:Partition 是物理上的概念,每個 Topic 包含一個或多個 Partition。Topic物理上的分組,一個topic可以分爲多個partition,每個partition是一個有序的隊列。partition中的每條消息都會被分配一個有序的id(offset)。

Producer:負責發佈消息到 Kafka broker。向broker發佈消息的客戶端應用程序;

Consumer:消息消費者,向 Kafka broker 讀取消息的客戶端。從消息隊列中請求消息的客戶端應用程序;

Consumer Group:每個 Consumer 屬於一個特定的 Consumer Group(可爲每個 Consumer 指定 group name,若不指定 group name 則屬於默認的 group)。

消息以及消息標識,磁盤,偏移量,kafka服務器,消費者和生產者,推拉,發送,接收,消費。

Message:消息是通信的基本單位,每個producer可以向一個topic(主題)發佈一些消息(多條)

1、主題(Topic):一個主題類似新聞中的體育、娛樂、教育等分類概念,在實際工程中通常一個業務一個主題(相當於消息標記);

2、分區(Partition):一個topic中的消息數據按照多個分區組織分區是kafka消息隊列組織的最小單位,一個分區可以看做是一個FIFO的隊列;(分區是提高kafka性能的關鍵手段,分區裏面的消息是按照從新到老的形式組織)(消息在分區裏面)

3、備份(Replication):爲了保證分佈式可靠性,kafka0.8開始對每個分區的數據進行備份(不同Broker上),防止其中一個Broker宕機造成分區數據不可用。

4、Zookeeper:一個提供分佈式狀態管理、分佈式配置管理、分佈式鎖服務等的集羣,服務註冊中心。

5、Kafka的動態擴容目前是通過zookeeper來完成的。kafka不支持事務,但是性能高,框架總要有取捨。都支持集羣,都支持負載均衡,但是隻有kafka支持動態擴容。

 

Kafka 客戶端支持當前大部分主流語言,使用某種語言和kafka服務器進行通信(即編寫自己的consumer和producer程序)

 

流式處理平臺,必須滿足以下三個關鍵特性:

1)能夠允許發佈和訂閱流數據

2)存儲流數據時提供相應的容錯機制

3)當流數據到達時能被及時處理

每一個消息都是一個Record對象。

kafka提供兩種刪除老消息的策略。

 

Kafka的使用流程

1、對配置參數的封裝:Properties

2、如何創建一個消息生產者? KafkaProducer

3、生產者如何發送消息? KafkaProducer.send(new ProducerRecord(topic,key,calue))

4、如何創建一個消息消費者? KafkaConsumer

5、消費者如何獲取消息?

1)subscribe() 監聽某個主題;

2)consumer.poll(100);

3)獲取ConsumerRecord對象,從此對象中獲取消息記錄。

kafka在落實在代碼層面,在java程序中使用kafka,有哪些常用的類?

KafkaProducer,ProducerRecord,key.serializer,value.serializer。

監聽消息,如果消息到達服務器端,就進行拉取。

由客戶端創建topic。

 

參數含義

Properties props = new Properties();

//配置kafka服務器集羣地址

props.put("bootstrap.servers","192.168.140.101:9092,192.168.140.102:9092,192.168.140.103:9092");

props.put("acks", "all");

props.put("retries", 0);

props.put("batch.size", 16384);

props.put("linger.ms", 1);

props.put("buffer.memory", 33554432);

props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");

props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

參與消息確認的broker數量控制,0代表不需要任何確認 1代表需要leader replica確認 -1代表需要ISR中所有進行確認

request.required.acks 0

acks設置決定請求被認定爲處理完成的標準。當我們設置acks爲“all”,將會阻塞所有記錄的提交,這是一種速度最慢但是可靠性最高的設置。

如果請求失敗,生產者可以自動地重跑,但是我們設置retries爲0的話就不會重跑。retries的設置也關係到能否使用副本功能

生產者緩存了每個分區下未被髮送的記錄。緩存大小可以通過batch.size配置。增大緩存可以增大批處理量,但是會佔用更多內存(由於通常情況下,會爲每一分區產生一個批,即:同一分區(目錄)的records纔會放到一個batch裏面)。

buffer.memory設置決定了Producer緩存區整個可用的內存。如果記錄記錄發送速度總是比推送到集羣速度快,那麼緩存區將被耗盡。當緩存區資源耗盡,消息發送send方法調用將被阻塞,阻塞的門限時間由max.block.ms設定,阻塞超過限定時間會拋出TimeoutException異常。

 

負載均衡原理

producer根據用戶指定的算法,將消息發送到指定的partition

存在多個partiiton,每個partition有自己的replica,每個replica分佈在不同的Broker節點上

多個partition需要選取出lead partition,lead partition負責讀寫,並由zookeeper負責fail over

通過zookeeper管理broker與consumer的動態加入與離開。

 

Kafka SDK:發佈有順序要求,消費端先啓動運行;如果生產端先運行,可能會導致消息丟失,會導致消息丟失麼?

SDK中就包含這兩個接口:receiver接口和send接口。

 

Kafka基本架構

Apache Kafka是分佈式發佈-訂閱消息系統。

kafka的核心組件,每個組件的功能和作用。

消息:消息內容;topic是消息id,或者說消息名稱。通過topic可以找到消息名稱。想要獲取消息,直接找消息id才行。

消息體+消息id,通過消息id獲取消息體

broker(服務代理): 已發佈的消息保存在一組服務器中,它們被稱爲代理(Broker)或Kafka集羣;

消費者(Consumer):可以訂閱一個或多個話題,並從Broker拉數據,從而消費這些已發佈的消息;

topic,producer,broker(服務代理),consumer.消息的訂閱(subscribe) pull與push的過程。

服務代理存儲消息。

producer 到 broker 的過程是 push,也就是有數據就推送到 broker,而 consumer 到 broker 的過程是 pull,是通過 consumer 主動去拉數據的,而不是 broker 把數據主動發送到 consumer 端的。

producer向哪個topic發送消息,consumer從哪個Topic中獲取消息。他們兩者並不關係每條消息存儲在哪個broker上

 

kafka高吞吐量的原理

由於消息是追加到分區中的,多個分區順序寫磁盤的總效率要比隨機寫內存還要高(引用Apache Kafka – A High Throughput Distributed Messaging System的觀點),是Kafka高吞吐率的重要保證之一。

每個分區順序寫磁盤;很多個topic,每個topic下的分區順序寫磁盤,並行處理。

 

Zookeeper在kafka集羣的作用

1、Zookeeper它維持了一張註冊表,記錄了各個節點的 IP、端口等信息

2、Kafka使用zookeeper作爲其分佈式協調框架,很好的將消息生產、消息存儲、消息消費的過程結合在一起。(將三者聯繫到一起);

3、多個broker協同合作,producer 和 consumer 部署在各個業務邏輯中被頻繁的調用,三者通過 zookeeper管理協調請求和轉發。這樣一個高性能的分佈式消息發佈訂閱系統就完成了(zookeeper用於管理broker集羣)。

4、Kafka將元數據信息保存在Zookeeper中,但是發送給Topic本身的數據是不會發到Zk上的

5、kafka使用zookeeper來實現動態的集羣擴展,不需要更改客戶端(producer和consumer)的配置。broker會在zookeeper註冊並保持相關的元數據(topic,partition信息等)更新。

6、客戶端會在zookeeper上註冊相關的watcher。一旦zookeeper發生變化,客戶端能及時感知並作出相應調整。這樣就保證了添加或去除broker時,各broker間仍能自動實現負載均衡。這裏的客戶端指的是Kafka的消息生產端(Producer)和消息消費端(Consumer)

7、每個kafka節點會在zookeeper中註冊該機器的配置信息

 

Kafka架構,項目整體運行的順序

1、啓動zookeeper的server

2、啓動kafka的server

3、Producer 如果生產了數據,會先通過 zookeeper 找到 broker,然後將數據存放到 broker

4、Consumer 如果要消費數據,會先通過 zookeeper找對應的 broker,然後消費。

無論是生產者還是消費者都要從zookeeper上獲取broker的信息

 

kafka副本機制的作用

Kafka的信息複製確保了任何已發佈的消息不會丟失,並且可以在機器錯誤、程序錯誤或更常見些的軟件升級中使用。(主備機制)

爲了保證數據的可靠性,Kafka會給每個分區找一個節點當帶頭大哥(Leader),以及若干個節點當隨從(Follower)。消息寫入分區時,帶頭大哥除了自己複製一份外還會複製到多個隨從。如果隨從掛了,Kafka會再找一個隨從從帶頭大哥那裏同步歷史消息;如果帶頭大哥掛了,隨從中會選舉出新一任的帶頭大哥,繼續笑傲江湖。

由於Producer和Consumer都只會與Leader角色的分區副本相連,所以kafka需要以集羣的組織形式提供主題下的消息高可用。kafka支持主備複製,所以消息具備高可用和持久性。(三個分區;每個分區都有副本,也把每個分區當做副本,只是每個分區的角色不一樣,Leader角色的副本,Follower角色的副本

一個分區可以有多個副本,這些副本保存在不同的broker上。每個分區的副本中都會有一個作爲Leader。當一個broker失敗時,Leader在這臺broker上的分區都會變得不可用,kafka會自動移除Leader,再其他副本中選一個作爲新的Leader。(副本在圖上沒有體現出來)

在通常情況下,增加分區可以提高kafka集羣的吞吐量。然而,也應該意識到集羣的總分區數或是單臺服務器上的分區數過多,會增加不可用及延遲的風險。

在其他服務器上做副本,如果在本機上做副本,本機掛了,全部的消息都丟失了。

kafka的序列化和反序列化

kafka在發送和接受消息的時候,都是以byte[]字節型數組發送或者接受的。但是我們平常使用的時候,不但可以使用byte[],還可以使用int、short、long、float、double、String等數據類型,這是因爲在我們使用這些數據類型的時候,kafka根據我們指定的序列化和反序列化方式轉成byte[]類型之後再進行發送或者接受的(指定key和value的序列化與反序列化方式)

通常我們在使用kakfa發送或者接受消息的時候都需要指定消息的key和value序列化方式,如設置value.serializer爲org.apache.kafka.common.serialization.StringSerializer,設置value的序列化方式爲字符串,即我們可以發送string類型的消息。

指定消息key與value的序列化與反序列化方式。我們可以發送String類型的消息。

kafka如何實現序列化/反序列化的?我們的消息的key與value是什麼類型的,然後由這種類型幫助我們轉化成byte[ ]數組形式。

kafka實現序列化/反序列化可以簡單的總結爲兩步,第一步繼承序列化Serializer或者反序列化Deserializer接口。第二步實現接口方法,將指定類型序列化成byte[]或者將byte[]反序列化成指定數據類型。所以接下來,我們來實現自己的序列化/反序列化方式。可以自己定義序列化與反序列化的類。

 

kafka中的topic與partition

在 Kafka 中,Topic 是一個存儲消息的邏輯概念,可以認爲是一個消息集合(一個topic可以對應多條消息)。每息發送到 Kafka 集羣的消息都有一個類別。物理上來說,不同的Topic的消息是分開存儲的,每個 Topic可以有多個生產者向它發送消息,也可以有多個消費者去消費其中的消息。

每個Topic可以劃分多個分區(每個 Topic 至少有一個分區),同一Topic下的不同分區包含的消息是不同的。每個消息在被添加到分區時,都會被分配一個offset,它是消息在此分區中的唯一編號,Kafka 通過 offset 保證消息在分區內的順序,offset 的順序不跨分區,即 Kafka 只保證在同一個分區內的消息是有序的

消息是每次追加到對應的Partition的後面(按照順序追加)

Topic 是一個邏輯上的概念,具體的存儲還是基於 Partition 來的。

一般每個 Topic 都會有多個 partition(主要是用於數據分片,減少消息的容量,從而提升 I/O 性能)當然也可以使用多個 Consumer 從而提高消費能力,有一個消費組的概念。

如果 Consumer1、Consumer2和Consumer3都屬於group.id 爲1的消費組。那麼 Consumer1 就會消費 p0,Consumer2 就會消費 p1,Consumer3 就會消費 p2。

 

kafka爲什麼要在topic里加入分區的概念? topic是邏輯的概念,partition是物理的概念,對用戶來說是透明的。

producer只需要關心消息發往哪個topic,而consumer只關心自己訂閱哪個topic,並不關心每條消息存於整個集羣的哪個broker。爲了性能考慮,如果topic內的消息只存於一個broker,那這個broker會成爲瓶頸,無法做到水平擴展。

所以把topic內的數據分佈到整個集羣就是一個自然而然的設計方式。

每個partition可以被認爲是一個無限長度的數組,新數據順序追加進這個數組。

物理上,每個partition對應於一個文件夾。一個broker上可以存放多個partition

這樣,producer可以將數據發送給多個broker上的多個partition,consumer也可以並行從多個broker上的不同paritition上讀數據,實現了水平擴展。

 

同一個topic上的所有分區會均勻的分佈在不同的broker上。

假設一個topic可能分爲10個分區,kafka內部會根據一定的算法把10分區儘可能均勻分佈到不同的服務器上,比如:A服務器負責topic的分區1,B服務器負責topic的分區2,在此情況下,Producer發消息時若沒指定發送到哪個分區的時候,kafka就會根據一定算法上個消息可能分區1,下個消息可能在分區2。當然高級API也能自己實現其分發算法。

多個訂閱者同時訂閱一個區,那麼這個區的消息會被重複消費

 

主題的分區數設置

生產者發送消息到主題,消費者訂閱主題(以消費者組的名義訂閱),而主題下是分區,消息是存儲在分區中的,所以事實上生產者發送消息到分區,消費者則從分區讀取消息,那麼,這裏問題來了,生產者將消息投遞到哪個分區?消費者組中的消費者實例之間是怎麼分配分區的呢?

1、主題的分區數設置:在server.properties配置文件中可以指定一個全局的分區數設置,這是對每個主題下的分區數的默認設置,默認是1。

2、當然每個主題也可以自己設置分區數量,如果創建主題的時候沒有指定分區數量,則會使用server.properties中的設置

3、在創建主題的時候,可以使用--partitions選項指定主題的分區數量。

 

理解:每個topic下只有一個分區,所有的消息寫入到這個分區裏面。每個topic下分區的數量,可以自定義;如果不定義,就是用默認的。消息是存儲在分區裏面的。

 

broker與分區

在kafka中就是創建多個分區文件

消息傳來時根據參數存到不同的分區,分區文件存在當前broker所在的文件系統中;

kafka會盡量保持各個broker分區的均衡性;

比如有兩個broker,創建十個分區,每個broker被分配到的都是5個分區;

其實分區本質上就是文件夾

 

生產者與分區

生產者將消息投遞到分區有沒有規律?如果有,那麼它是如何決定一條消息該投遞到哪個分區的呢?

如何決定一條消息該投遞到哪個分區的?

默認的分區策略是:

  • 如果在發消息的時候指定了分區,則消息投遞到指定的分區;
  • 如果沒有指定分區,但是消息的key不爲空,則基於key的哈希值來選擇一個分區;
  • 如果既沒有指定分區,且消息的key也是空,則用輪詢的方式選擇一個分區

 

消費者與分區

消費者以組的名義訂閱主題,主題有多個分區,消費者組中有多個消費者實例,那麼消費者實例和分區之前的對應關係是怎樣的呢?

組中的每一個消費者負責哪些分區,這個分配關係是如何確定的呢?

 

kafka的消息分發策略

Kafka中最基本的數據單元就是消息,而一條消息其實是由 Key + Value 組成的(Key 是可選項,可傳空值,Value 也可以傳空值)

 

消費者分區分配策略

同一時刻,一條消息只能被組中的一個消費者實例消費

消費者組訂閱這個主題,意味着主題下的所有分區都會被組中的消費者消費到,如果按照從屬關係來說的話就是,主題下的每個分區只從屬於組中的一個消費者,不可能出現組中的兩個消費者負責同一個分區。一個消費者負責一個分區

那麼,問題來了。如果分區數大於或者等於組中的消費者實例數,那自然沒有什麼問題,無非一個消費者會負責多個分區,(PS:當然,最理想的情況是二者數量相等,這樣就相當於一個消費者負責一個分區);但是,如果消費者實例的數量大於分區數,那麼按照默認的策略(PS:之所以強調默認策略是因爲你也可以自定義策略),有一些消費者是多餘的,一直接不到消息而處於空閒狀態。

理解:分區數量和消費者數量的關係

我們知道,Kafka它在設計的時候就是要保證分區下消息的順序,也就是說消息在一個分區中的順序是怎樣的,那麼消費者在消費的時候看到的就是什麼樣的順序,那麼要做到這一點就首先要保證消息是由消費者主動拉取的(pull),其次還要保證一個分區只能由一個消費者負責。倘若,兩個消費者負責同一個分區,那麼就意味着兩個消費者同時讀取分區的消息(可能會被消費兩次,且不能保證消息消費的順序),由於消費者自己可以控制讀取消息的offset,就有可能C1纔讀到2,而C1讀到1,C1還沒處理完,C2已經讀到3了,則會造成很多浪費,因爲這就相當於多線程讀取同一個消息,會造成消息處理的重複,且不能保證消息的順序,這就跟主動推送(push)無異。

 

對於每個主題Topic,我們以數字順序排列可用分區,以字典順序排列消費者。然後,將分區數量除以消費者總數,以確定分配給每個消費者的分區數量。如果沒有平均劃分(PS:除不盡),那麼最初的幾個消費者將有一個額外的分區。

分配給消費者的分區應該是怎麼樣的?以組的形式訂閱某個topic。

分區的總數/消費者的總數

 

Kafka Manager

Kafka Manager是kafka集羣管理工具,用戶可以在Web界面執行一些簡單的集羣管理操作

1、集羣界面:在集羣界面顯示了主題和Broker的個數,點擊數字可以查看具體的信息。同時在頂部多了好幾個菜單,可以查看集羣、Broker、主題等信息。管理集羣的zookeeper地址

Summary:總結、概括、概要;

replication:複製、拷貝、副本;

2、新建主題:點擊【Topic】>【Create】可以方便的創建並配置主題。如下顯示。

點擊Topic名稱,查看這個Topic下的所有信息。

如果集羣中存在多個服務,在創建該主題時,不一定會分配到哪個Broker(多個服務器結點)。

3、添加集羣 :集羣名稱,管理集羣的zookeeper地址,kafka版本。

Enable JMX Polling

是否開啓 JMX 輪訓,該部分直接影響部分 kafka broker 和 topic 監控指標指標的獲取(生效的前提是 kafka 啓動時開啓了 JMX_PORT。

4、如何刪除topic?

 

consumer是和group綁定的, 創建consumer的時候,指定消費者所在的組;

接收消息和發送消息都要傳遞topic。

Kafka是目前主流的流處理平臺,同時作爲消息隊列家族的一員,其高吞吐性作爲很多場景下的主流選擇。

發佈了303 篇原創文章 · 獲贊 104 · 訪問量 51萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章