Kafka教程(一)Kafka入門教程
Kafka教程(一)Kafka入門教程
1 Kafka入門教程
1.1 訊息佇列(Message Queue)
Message Queue訊息傳送系統提供傳送服務。訊息傳送依賴於大量支援元件,這些元件負責處理連線服務、訊息的路由和傳送、永續性、安全性以及日誌記錄。訊息伺服器可以使用一個或多個代理例項。
JMS(Java Messaging Service)是Java平臺上有關面向訊息中介軟體(MOM)的技術規範,它便於訊息系統中的Java應用程式進行訊息交換,並且通過提供標準的產生、傳送、接收訊息的介面簡化企業應用的開發,翻譯為Java訊息服務。
1.2 MQ訊息模型
KafkaMQ訊息模型圖1-1
1.3 MQ訊息佇列分類
訊息佇列分類:點對點和釋出/訂閱兩種:
1、點對點:
訊息生產者生產訊息傳送到queue中,然後訊息消費者從queue中取出並且消費訊息。
訊息被消費以後,queue中不再有儲存,所以訊息消費者不可能消費到已經被消費的訊息。Queue支援存在多個消費者,但是對一個訊息而言,只會有一個消費者可以消費。
2、釋出/訂閱:
訊息生產者(釋出)將訊息釋出到topic中,同時有多個訊息消費者(訂閱)消費該訊息。和點對點方式不同,釋出到topic的訊息會被所有訂閱者消費。
1.4 MQ訊息佇列對比
1、RabbitMQ:支援的協議多,非常重量級訊息佇列,對路由(Routing),負載均衡(Loadbalance)或者資料持久化都有很好的支援。
2、ZeroMQ:號稱最快的訊息佇列系統,尤其針對大吞吐量的需求場景,擅長的高階/複雜的佇列,但是技術也複雜,並且只提供非永續性的佇列。
3、ActiveMQ:Apache下的一個子項,類似ZeroMQ,能夠以代理人和點對點的技術實現佇列。
4、Redis:是一個key-Value的NOSql資料庫,但也支援MQ功能,資料量較小,效能優於RabbitMQ,資料超過10K就慢的無法忍受。
1.5 Kafka簡介
Kafka是分散式釋出-訂閱訊息系統,它最初由 LinkedIn 公司開發,使用 Scala語言編寫,之後成為 Apache 專案的一部分。在Kafka叢集中,沒有“中心主節點”的概念,叢集中所有的伺服器都是對等的,因此,可以在不做任何配置的更改的情況下實現伺服器的的新增與刪除,同樣的訊息的生產者和消費者也能夠做到隨意重啟和機器的上下線。
Kafka訊息系統生產者和消費者部署關係圖1-2
Kafka訊息系統架構圖1-3
1.6 Kafka術語介紹
1、訊息生產者:即:Producer,是訊息的產生的源頭,負責生成訊息併傳送到Kafka
伺服器上。
2、訊息消費者:即:Consumer,是訊息的使用方,負責消費Kafka伺服器上的訊息。
3、主題:即:Topic,由使用者定義並配置在Kafka伺服器,用於建立生產者和訊息者之間的訂閱關係:生產者傳送訊息到指定的Topic下,訊息者從這個Topic下消費訊息。
4、訊息分割槽:即:Partition,一個Topic下面會分為很多分割槽,例如:“kafka-test”這個Topic下可以分為6個分割槽,分別由兩臺伺服器提供,那麼通常可以配置為讓每臺伺服器提供3個分割槽,假如伺服器ID分別為0、1,則所有的分割槽為0-0、0-1、0-2和1-0、1-1、1-2。Topic物理上的分組,一個 topic可以分為多個 partition,每個 partition 是一個有序的佇列。partition中的每條訊息都會被分配一個有序的 id(offset)。
5、Broker:即Kafka的伺服器,使用者儲存訊息,Kafa叢集中的一臺或多臺伺服器統稱為 broker。
6、消費者分組:Group,用於歸組同類消費者,在Kafka中,多個消費者可以共同訊息一個Topic下的訊息,每個消費者消費其中的部分訊息,這些消費者就組成了一個分組,擁有同一個分組名稱,通常也被稱為消費者叢集。
7、Offset:訊息儲存在Kafka的Broker上,消費者拉取訊息資料的過程中需要知道訊息在檔案中的偏移量,這個偏移量就是所謂的Offset。
1.7 Kafka中Broker
1、Broker:即Kafka的伺服器,使用者儲存訊息,Kafa叢集中的一臺或多臺伺服器統稱為 broker。
2、Message在Broker中通Log追加的方式進行持久化儲存。並進行分割槽(patitions)。
3、為了減少磁碟寫入的次數,broker會將訊息暫時buffer起來,當訊息的個數(或尺寸)達到一定閥值時,再flush到磁碟,這樣減少了磁碟IO呼叫的次數。
4、Broker沒有副本機制,一旦broker當機,該broker的訊息將都不可用。Message訊息是有多份的。
5、Broker不儲存訂閱者的狀態,由訂閱者自己儲存。
6、無狀態導致訊息的刪除成為難題(可能刪除的訊息正在被訂閱),kafka採用基於時間的SLA(服務水平保證),訊息儲存一定時間(通常為7天)後會被刪除。
7、訊息訂閱者可以rewind back到任意位置重新進行消費,當訂閱者故障時,可以選擇最小的offset(id)進行重新讀取消費訊息。
1.8 Kafka的Message組成
1、Message訊息:是通訊的基本單位,每個 producer 可以向一個 topic(主題)釋出一些訊息。
2、Kafka中的Message是以topic為基本單位組織的,不同的topic之間是相互獨立的。每個topic又可以分成幾個不同的partition(每個topic有幾個partition是在建立topic時指定的),每個partition儲存一部分Message。
3、partition中的每條Message包含了以下三個屬性:
offset 即:訊息唯一標識:對應型別:long
MessageSize 對應型別:int32
data 是message的具體內容。
1.9 Kafka的Partitions分割槽
1、Kafka基於檔案儲存.通過分割槽,可以將日誌內容分散到多個server上,來避免檔案尺寸達到單機磁碟的上限,每個partiton都會被當前server(kafka例項)儲存。
2、可以將一個topic切分多任意多個partitions,來訊息儲存/消費的效率。
3、越多的partitions意味著可以容納更多的consumer,有效提升併發消費的能力。
1.10 Kafka的Consumers
1、訊息和資料消費者,訂閱 topics並處理其釋出的訊息的過程叫做 consumers。
2、在 kafka中,我們可以認為一個group是一個“訂閱者”,一個Topic中的每個partions,只會被一個“訂閱者”中的一個consumer消費,不過一個 consumer可以消費多個partitions中的訊息(消費者資料小於Partions的數量時)。注意:kafka的設計原理決定,對於一個topic,同一個group中不能有多於partitions個數的consumer同時消費,否則將意味著某些consumer將無法得到訊息。
3、一個partition中的訊息只會被group中的一個consumer訊息。每個group中consumer訊息消費互相獨立。
1.11 Kafka的持久化
1、一個Topic可以認為是一類訊息,每個topic將被分成多partition(區),每個partition在儲存層面是append log檔案。任何釋出到此partition的訊息都會被直接追加到log檔案的尾部,每條訊息在檔案中的位置稱為offset(偏移量),partition是以檔案的形式儲存在檔案系統中。
2、Logs檔案根據broker中的配置要求,保留一定時間後刪除來釋放磁碟空間。
Kafka訊息分割槽Partition圖1-4
Partition:
Topic物理上的分組,一個 topic可以分為多個 partition,每個 partition 是一個有序的佇列。partition中的每條訊息都會被分配一個有序的 id(offset)。
3、為資料檔案建索引:稀疏儲存,每隔一定位元組的資料建立一條索引。下圖為一個partition的索引示意圖:
Kafka訊息分割槽Partition索引圖1-5
1.12 Kafka的分散式實現:
Kafka分散式關係圖1-6
Kafka生產環境關係圖1-7
1.13 Kafka的通訊協議:
1、Kafka的Producer、Broker和Consumer之間採用的是一套自行設計基於TCP層的協議,根據業務需求定製,而非實現一套類似ProtocolBuffer的通用協議。
2、基本資料型別:(Kafka是基於Scala語言實現的,型別也是Scala中的資料型別)
定長資料型別:int8,int16,int32和int64,對應到Java中就是byte, short, int和long。
變長資料型別:bytes和string。變長的資料型別由兩部分組成,分別是一個有符號整數N(表示內容的長度)和N個位元組的內容。其中,N為-1表示內容為null。bytes的長度由int32表示,string的長度由int16表示。
陣列:陣列由兩部分組成,分別是一個由int32型別的數字表示的陣列長度N和N個元素。
3、Kafka通訊的基本單位是Request/Response。
4、基本結構:
RequestOrResponse => MessageSize(RequestMessage | ResponseMessage)
名稱 |
型別 |
描術 |
MessageSize |
int32 |
表示RequestMessage或者ResponseMessage的長度
|
RequestMessage ResponseMessage |
— |
|
5、通訊過程:
客戶端開啟與伺服器端的Socket
往Socket寫入一個int32的數字(數字表示這次傳送的Request有多少位元組)
伺服器端先讀出一個int32的整數從而獲取這次Request的大小
然後讀取對應位元組數的資料從而得到Request的具體內容
伺服器端處理了請求後,也用同樣的方式來傳送響應。
6、RequestMessage結構:
RequestMessage => ApiKey ApiVersionCorrelationId ClientId Request
名稱 |
型別 |
描術 |
ApiKey |
int16 |
表示這次請求的API編號 |
ApiVersion |
int16 |
表示請求的API的版本,有了版本後就可以做到後向相容 |
CorrelationId |
int32 |
由客戶端指定的一個數字唯一標示這次請求的id,伺服器端在處理完請求後也會把同樣的CorrelationId寫到Response中,這樣客戶端就能把某個請求和響應對應起來了。 |
ClientId |
string |
客戶端指定的用來描述客戶端的字串,會被用來記錄日誌和監控,它唯一標示一個客戶端。 |
Request |
— |
Request的具體內容。 |
7、ResponseMessage結構:
ResponseMessage => CorrelationId Response
名稱 |
型別 |
描術 |
CorrelationId |
int32 |
對應Request的CorrelationId。 |
Response |
— |
對應Request的Response,不同的Request的Response的欄位是不一樣的。 |
Kafka採用是經典的Reactor(同步IO)模式,也就是1個Acceptor響應客戶端的連線請求,N個Processor來讀取資料,這種模式可以構建出高效能的伺服器。
8、Message結構:
Message:Producer生產的訊息,鍵-值對
Message => Crc MagicByte Attributes KeyValue
名稱 |
型別 |
描術 |
CRC |
int32 |
表示這條訊息(不包括CRC欄位本身)的校驗碼。 |
MagicByte |
int8 |
表示訊息格式的版本,用來做後向相容,目前值為0。 |
Attributes |
int8 |
表示這條訊息的後設資料,目前最低兩位用來表示壓縮格式。 |
Key |
bytes |
表示這條訊息的Key,可以為null。 |
Value |
bytes |
表示這條訊息的Value。Kafka支援訊息巢狀,也就是把一條訊息作為Value放到另外一條訊息裡面。 |
9、MessageSet結構:
MessageSet:用來組合多條Message,它在每條Message的基礎上加上了Offset和MessageSize
MessageSet => [Offset MessageSize Message]
名稱 |
型別 |
描術 |
Offset |
int64 |
它用來作為log中的序列號,Producer在生產訊息的時候還不知道具體的值是什麼,可以隨便填個數字進去。 |
MessageSize |
int32 |
表示這條Message的大小。 |
Message |
- |
表示這條Message的具體內容,其格式見上一小節。 |
10、 Request/Respone和Message/MessageSet的關係:
Request/Response是通訊層的結構,和網路的7層模型對比的話,它類似於TCP層。
Message/MessageSet定義的是業務層的結構,類似於網路7層模型中的HTTP層。Message/MessageSet只是Request/Response的payload中的一種資料結構。
備註:Kafka的通訊協議中不含Schema,格式也比較簡單,這樣設計的好處是協議自身的Overhead小,再加上把多條Message放在一起做壓縮,提高壓縮比率,從而在網路上傳輸的資料量會少一些。
1.14 資料傳輸的事務定義:
1、at most once:最多一次,這個和JMS中"非持久化"訊息類似.傳送一次,無論成敗,將不會重發。
at most once:消費者fetch訊息,然後儲存offset,然後處理訊息;當client儲存offset之後,但是在訊息處理過程中出現了異常,導致部分訊息未能繼續處理.那麼此後"未處理"的訊息將不能被fetch到,這就是"atmost once"。
2、at least once:訊息至少傳送一次,如果訊息未能接受成功,可能會重發,直到接收成功。
at least once:消費者fetch訊息,然後處理訊息,然後儲存offset.如果訊息處理成功之後,但是在儲存offset階段zookeeper異常導致儲存操作未能執行成功,這就導致接下來再次fetch時可能獲得上次已經處理過的訊息,這就是"atleast once",原因offset沒有及時的提交給zookeeper,zookeeper恢復正常還是之前offset狀態。
3、exactly once:訊息只會傳送一次。
exactly once: kafka中並沒有嚴格的去實現(基於2階段提交,事務),我們認為這種策略在kafka中是沒有必要的。
注:通常情況下"at-least-once"是我們首選。(相比at most once而言,重複接收資料總比丟失資料要好)。
1.15 學習Kafka推薦書籍:
1. 《Apache Kafka》
2. 《從Paxos到Zookeeper分散式一致性原理與實踐》
——厚積薄發(yuanxw)
相關文章
- Apache Kafka教程--Kafka新手入門ApacheKafka
- Kafka入門經典教程Kafka
- Apache Kafka安裝和使用(入門教程輕鬆學)ApacheKafka
- Kafka 入門Kafka
- Kafka除錯入門(一)Kafka除錯
- Kafka從入門到放棄(一) —— 初識KafkaKafka
- kafka入門案例Kafka
- Kafka 主題 CLI 教程Kafka
- Kafka 入門(一)--安裝配置和 kafka-python 呼叫KafkaPython
- Kafka入門(1):概述Kafka
- kafka(docker) 入門分享KafkaDocker
- Kafka基礎入門Kafka
- Kafka簡單入門Kafka
- Kafka入門例項Kafka
- Kafka實戰-入門Kafka
- kafka 安裝部署,使用教程Kafka
- Kafka【入門】就這一篇!Kafka
- kafka從入門到關門Kafka
- Kafka 入門(三)--為什麼 Kafka 依賴 ZooKeeper?Kafka
- Kafka 入門(四)-- Python Kafka Client 效能測試KafkaPythonclient
- 超詳細kafka教程來啦Kafka
- Kafka詳細教程加面試題Kafka面試題
- kafka快速入門到精通Kafka
- Kafka基礎入門篇Kafka
- Kafka 入門與實踐Kafka
- Spring Boot的Kafka入門Spring BootKafka
- kafka入門安裝和使用Kafka
- Kafka Streams開發入門(1)Kafka
- Scala入門教程 (一)
- NSIS 入門教程 (一)
- Kafka教程大全指引 - DZone Big DataKafka
- Windows下Kafka2.8環境搭建教程WindowsKafka
- Kafka入門(2):消費與位移Kafka
- Kafka入門(4):深入消費者Kafka
- kafka之一:kafka簡介Kafka
- Docker(一):Docker入門教程Docker
- 真的,kafka 入門看這一篇準沒錯!Kafka
- Linux系統安裝和使用Kafka教程。LinuxKafka