1. 程式人生 > >Kafka基礎知識(二)

Kafka基礎知識(二)

net pic 知識 2個 先後 orm 進行 進制 機器

Kafka進階知識

消息概念

消息指的是通信的基本單位。由消息生產者(producer)發布關於某個話題(topic)的消息。簡單來說:消息以一種物理方式被發送給了作為代理(broker)的服務器(可能是另外一臺機器)。若幹的消息使用者(consumer)訂閱(subscribe)某個話題,然後生產者所發布的每條消息都會被發送給所有的使用者。

Kafka的生產者、使用者和代理都可以運行在作為一個邏輯單位的、進行相互協作的集群中不同的機器上。生產者和代理沒有什麽關系,但是使用者都是屬於一個使用者小組的。準確地說,每條消息都只會發送給每個使用者小組中的一個進程。因此,使用者小組使得許多進程或多臺機器在邏輯上作為一個單個的使用者出現

Kafka的broker

因為Kafka生產了消息後,Kafka不會直接把消息傳遞給消費者,而是要先在broker中進行存儲,持久化是保存在kafka的日誌文件中的。消息在Broker中通過Log追加(保存在文件的最後面,是有序的)。為了減少磁盤寫入的次數,broker會將消息暫時存在buffer中,當消息的個數(或尺寸)達到一定閥值時,再flush到磁盤,以此來減少磁盤IO調用的次數。

需要註意的是:

  • Broker沒有副本一說,但是消息本身是有副本的,因此不會丟失。Broker在宕機後,再讀取消息的日誌就可以了。
  • Broker不保存訂閱者的狀態,由訂閱者自己保存。
  • 無狀態導致消息的刪除成為難題(可能刪除的消息正在被訂閱),kafka采用基於時間的SLA(服務水平保證),消息保存一定時間(通常為7天)後會被刪除。這個地方的無狀態感覺指的是消息本身,對於消費者而言,zookeeper會幫助記錄哪條信息已經消費了,哪條消息沒有消費。
  • 消息訂閱者可以rewind back到任意位置重新進行消費,當訂閱者故障時,可以選擇最小的offset(id,即偏移量)進行重新讀取消費消息。

Message組成

Kafka中的Message是以topic為基本單位組織的,不同的topic之間是相互獨立的。每個topic又可以分成幾個不同的partition(每個topic有幾個partition是在創建topic時指定的),每個partition存儲一部分Message。

1.消息是無狀態的,消息的消費先後順序是沒有關系的

2.每一個partition只能由一個consumer來進行消費,但是一個consumer是可 以消費多個partition,是一對多的關系。

假設有2個分區的主題“my_topic”,它將由2個目錄構成(my_topic_0和my_topic_1),用於存放該主題消息的數據文件。日誌文件的格式是一個“日誌條目”序列。每條日誌條目都由一個存儲消息長度的4字節整型N和緊跟著的N字節消息組成。其中每條消息都有一個64位整型的唯一標識offset,offset(偏移量)代表了topic分區中所有消息流中該消息的起始字節位置。每條消息在磁盤上的格式如下:每個日誌文件用第一條消息的offset來命名的,因此,創建的第一個文件將是00000000000.kafka,並且每個附加文件都將是上一個文件S字節的整數命名,其中S是配置中設置的最大日誌文件大小。

消息是二進制格式並作為一個標準接口,所以消息可以在producer,broker,client之間傳輸,無需再copy或轉換。
格式如下:

On-disk format of a message
message length : 4 bytes (value: 1+4+n) 
"magic" value  : 1 byte
crc            : 4 bytes
payload        : n bytes

技術分享圖片
一個叫做“my_topic”且有兩個分區的的topic,它的日誌有兩個文件夾組成,my_topic_0和my_topic_1,每個文件夾裏放著具體的數據文件,每個數據文件都是一系列的日誌實體,每個日誌實體有一個4個字節的整數N標註消息的長度,後邊跟著N個字節的消息。每個消息都可以由一個64位的整數offset標註,offset標註了這條消息在發送到這個分區的消息流中的起始位置。每個日誌文件的名稱都是這個文件第一條日誌的offset.所以第一個日誌文件的名字就是00000000000.kafka.所以每相鄰的兩個文件名字的差就是一個數字S,S差不多就是配置文件中指定的日誌文件的最大容量。
消息的格式都由一個統一的接口維護,所以消息可以在producer,broker和consumer之間無縫的傳遞

寫操作

消息被不斷的追加到最後一個日誌的末尾,當日誌的大小達到一個指定的值時就會產生一個新的文件。對於寫操作有兩個參數,一個規定了消息的數量達到這個值時必須將數據刷新到硬盤上,另外一個規定了刷新到硬盤的時間間隔,這對數據的持久性是個保證,在系統崩潰的時候只會丟失一定數量的消息或者一個時間段的消息。

讀操作

讀取是通過定義的64位邏輯的消息和S-byte塊大小的offset來完成。返回一個叠代器,它包含在S-byte緩沖區的消息。S比單個消息大,但是在消息很大的情況下,讀取可重試多次,每次的緩沖區大小加倍,直到消息被成功的讀取。可以指定最大消息和緩沖區的大小,使服務器拒絕一些超過這個大小的消息。

在實際執行讀取操縱時,首先需要定位數據所在的日誌文件,然後根據offset計算出在這個日誌中的offset(前面的的offset是整個分區的offset),然後在這個offset的位置進行讀取。定位操作是由二分查找法完成的,Kafka在內存中為每個文件維護了offset的範圍。

參考文檔:[http://orchome.com/28]
http://blog.csdn.net/looklook5/article/details/42008079
http://blog.csdn.net/honglei915/article/details/37760631

Kafka基礎知識(二)