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