kafka-01-基礎(chǔ)知識(shí)

[TOC]

1 簡(jiǎn)介

MQ滿天飛的時(shí)代,kafka也只是其中之一。

Kafka,一個(gè)基于分布式高吞吐量消息發(fā)布-訂閱系統(tǒng)。

具有快速、持久可擴(kuò)展、處理大量不同消費(fèi)者的特性。Kafka 不會(huì)關(guān)心消息的處理過程及消費(fèi)者隊(duì)列。

  • 磁盤線性讀寫,O(1)讀寫性能
  • 高吞吐量
  • 顯式的分布式架構(gòu)

詳細(xì)的介紹可以看這里:http://blog.cloudera.com/blog/2014/09/apache-kafka-for-beginners/

2 名詞解釋

  • broker

kafka集群中的服務(wù)器(一個(gè)或多個(gè))被稱為broker。

  • topic

顧名思義,topic就是主題的意思。也就是對(duì)消息的一個(gè)分類。kafka中的每個(gè)消息都有一個(gè)分類/類別,這個(gè)類別就是topic。

不同topic的消息在磁盤上是分開存儲(chǔ)的,同時(shí)對(duì)消費(fèi)者是透明的。也就是說當(dāng)你消費(fèi)消息的時(shí)候并不需要知道消息是怎么存儲(chǔ)的,也不需要知道存儲(chǔ)在哪里。

  • partition

可以認(rèn)為是topic的物理分組,一個(gè)topic可以分為一個(gè)或多個(gè)partition。partition一兩句話說不清,詳情見后面的小節(jié)。

  • producer

這個(gè)好理解,就是消息的生產(chǎn)者。

  • consumer

和producer相對(duì)應(yīng),consumer就是消息的消費(fèi)者。通常是各種高級(jí)語言寫的客戶端API,比如Java、Python甚至是JavaScript所寫的客戶端API。

  • consumer group

每個(gè)consumer都屬于一個(gè)消費(fèi)者組。不顯示地指定消費(fèi)者組的時(shí)候?qū)儆谀J(rèn)的消費(fèi)者組。

  • message

消息是通信的基本單位,producer可以向topic發(fā)布message。新發(fā)布的消息就會(huì)廣播給訂閱了這個(gè)主題de consumer。message只能傳輸給某個(gè)group中的某一個(gè)consumer。

3 partition

kafka作為一個(gè)MQ或者日志系統(tǒng),他的最終數(shù)據(jù)存儲(chǔ)還是離不開磁盤的。kafka對(duì)每個(gè)消息做了分類,即有了topic,每個(gè)topic當(dāng)然也是持久化在磁盤上的。當(dāng)消費(fèi)完之后太過于陳舊的消息(message/topic)將被刪除。

鑒于此,將所有topic都存儲(chǔ)在同一個(gè)目錄里將導(dǎo)致磁盤文件太過于龐大,這樣一來,管理不便,如果一個(gè)磁盤掛了,將導(dǎo)致所有數(shù)據(jù)丟失;而且磁盤的空間總是有限的。也就是說一個(gè)磁盤持久化所有數(shù)據(jù)在生成環(huán)境是不靠譜的。

所以,kafka可以將不同的topic分布式地存儲(chǔ)于不同的磁盤上,這就有了kafka所謂的partition的概念。

partition是一個(gè)有序的、不可變的消息隊(duì)列。每個(gè)消息都有一個(gè)連續(xù)的序列號(hào)即offset。每個(gè)partition又分為若干個(gè)segment

最簡(jiǎn)單的也就是kafka默認(rèn)的partition分布存儲(chǔ)策略就是hash了。簡(jiǎn)單理解就是所有可用的broker一次輪流一個(gè)一個(gè)地存儲(chǔ)partition。

這么一搞,最終結(jié)果就是:

  • 每臺(tái)可用的broker上的數(shù)據(jù)逗比總數(shù)據(jù)要少
  • 但是每個(gè)消息數(shù)據(jù)都有冗余
  • 一般情況下,一臺(tái)broker宕機(jī)并不影響整個(gè)系統(tǒng)(當(dāng)然如果你只有一臺(tái)broker那就另說了……)

日志文件的存儲(chǔ)位置(partition就在這里了)在server.properties中指定: log.dirs=/Users/hylexus/data/kafka/kafka-logs。

3.1 單機(jī)版partition的磁盤存儲(chǔ)

此處先從單機(jī)版kafka中partition存儲(chǔ)方式說起。

單機(jī)版并沒有partition帶來的好處。

本人此處的設(shè)置是kafka數(shù)據(jù)存儲(chǔ)在log.dirs=/Users/hylexus/data/kafka/kafka-logs。

創(chuàng)建一個(gè)測(cè)試用的topic名為topic01

$ bin/kafka-topics.sh --create \
--zookeeper localhost:2181 \
--replication-factor 1 \
--partitions 4 \ # 分區(qū)數(shù)為4
--topic topic01

查看磁盤上partition的存儲(chǔ)

hylexus@hylexusPC kafka-logs $ pwd
/Users/hylexus/data/kafka/kafka-logs
hylexus@hylexusPC kafka-logs $ ll
drwxr-xr-x  5 hylexus  staff   170  5  1 15:46 topic01-0
drwxr-xr-x  5 hylexus  staff   170  5  1 15:46 topic01-1
drwxr-xr-x  5 hylexus  staff   170  5  1 15:46 topic01-2
drwxr-xr-x  5 hylexus  staff   170  5  1 15:46 topic01-3
hylexus@hylexusPC kafka-logs $ 

單機(jī)版由于只有一個(gè)目錄,partition分布較為簡(jiǎn)單。

3.2 多broker下partition的磁盤存儲(chǔ)

此處的多broker是如下形式:

多broker

單機(jī)上啟動(dòng)三個(gè)broker,注冊(cè)到同一個(gè)zookeeper。

創(chuàng)建一個(gè)topic名為topic02,用以測(cè)試

bin/kafka-topics.sh --create \
--zookeeper localhost:2181 \
--replication-factor 2 \ # 2份拷貝
--partitions 4 \ # 4個(gè)partition
--topic topic02

查看磁盤磁盤上partition存儲(chǔ)

hylexus@hylexusPC kafka-logs $ pwd
/Users/hylexus/data/kafka/kafka-logs
hylexus@hylexusPC kafka-logs $ ll
drwxr-xr-x  5 hylexus  staff   170  5  1 16:29 topic02-0
drwxr-xr-x  5 hylexus  staff   170  5  1 16:29 topic02-2
drwxr-xr-x  5 hylexus  staff   170  5  1 16:29 topic02-3

hylexus@hylexusPC kafka-logs-02 $ pwd
/Users/hylexus/data/kafka/kafka-logs-02
hylexus@hylexusPC kafka-logs-02 $ ll
drwxr-xr-x  5 hylexus  staff  170  5  1 16:29 topic02-0
drwxr-xr-x  5 hylexus  staff  170  5  1 16:29 topic02-1
drwxr-xr-x  5 hylexus  staff  170  5  1 16:29 topic02-3

hylexus@hylexusPC kafka-logs-03 $ pwd
/Users/hylexus/data/kafka/kafka-logs-03
hylexus@hylexusPC kafka-logs-03 $ ll
drwxr-xr-x  5 hylexus  staff  170  5  1 16:29 topic02-1
drwxr-xr-x  5 hylexus  staff  170  5  1 16:29 topic02-2

此時(shí)的partition磁盤分布如下:

partitions

記broker個(gè)數(shù)為n,則有:

  • 第i個(gè)partition分配到第(i % n)個(gè)broker
  • 第i個(gè)Partition的第j個(gè)拷貝分配到第((i + j) % n)個(gè)broker

3.3 partition磁盤存儲(chǔ)總結(jié)

  • 每個(gè)partition為一個(gè)目錄
  • partiton命名規(guī)則為topic名稱-有序序號(hào)
    • 第一個(gè)partiton有序序號(hào)從0開始
    • 序號(hào)最大值為partitions數(shù)量減1
  • 如果你只是調(diào)用kafka提供的客戶端程序的話,你沒有必要清楚每個(gè)partition是怎么分布的,因?yàn)槟阒皇钦{(diào)用客戶端消費(fèi)數(shù)據(jù)而已

3.4 partition中segment磁盤存儲(chǔ)

接著上面說的,其實(shí)每個(gè)partition就相當(dāng)于一個(gè)大型文件(整個(gè)消息記錄)被分配到多個(gè)大小相等的文件中存儲(chǔ)。大小相等但是消息個(gè)數(shù)不一定相等了,這樣利于管理,可以快速的刪除陳舊的文件,有效地提高了磁盤的利用率。

此處所說的每個(gè)大小相等的文件就是segment(partition的再次細(xì)分)了。

既然數(shù)據(jù)是存儲(chǔ)在磁盤上的,即便比不上磁盤高效,但也要在一個(gè)MQ系統(tǒng)能接受的范圍內(nèi)。

所以,索引就必不可少了,kafka的segment文件分為兩個(gè)主要部分:index+log

  • index主要是索引文件,log才是真正的消息數(shù)據(jù)。
  • segment文件命名時(shí):
    • 第一個(gè)segment文件名稱從零開始,前導(dǎo)零填充至19位
    • 其他每個(gè)segment文件名為上一個(gè)segment文件最后一個(gè)message的offset

此處就以單機(jī)版的kafka為例:

為測(cè)試方便,此處我將log.segment.bytes=1024調(diào)整為1024,以便快速看到效果,生成一些message之后,topic01-0磁盤存儲(chǔ)如下:

hylexus@hylexusPC topic01-0 $ pwd
/Users/hylexus/data/kafka/kafka-logs/topic01-0
hylexus@hylexusPC kafka-logs $ ll topic01-0
-rw-r--r--  1 hylexus  staff         0  5  1 19:43 00000000000000000000.index
-rw-r--r--  1 hylexus  staff       990  5  1 19:43 00000000000000000000.log

-rw-r--r--  1 hylexus  staff         0  5  1 19:43 00000000000000000012.index
-rw-r--r--  1 hylexus  staff       990  5  1 19:43 00000000000000000012.log

-rw-r--r--  1 hylexus  staff         0  5  1 19:43 00000000000000000024.index
-rw-r--r--  1 hylexus  staff       998  5  1 19:43 00000000000000000024.log

-rw-r--r--  1 hylexus  staff         0  5  1 19:43 00000000000000000036.index
-rw-r--r--  1 hylexus  staff       994  5  1 19:43 00000000000000000036.log

-rw-r--r--  1 hylexus  staff         0  5  1 19:43 00000000000000000048.index
-rw-r--r--  1 hylexus  staff      1004  5  1 19:43 00000000000000000048.log

3.5 通過offset查找message

就拿上面的segment來說,第一個(gè)segment的命名為零(前導(dǎo)零).{index,log}。

另外,上面我將每個(gè)segment的大小設(shè)置為1024即log.segment.bytes=1024。

00000000000000000000 offset=0
00000000000000000012 offset=12+1==13
00000000000000000024 offset=24+1==25
……

因此,通過offset查找具體消息步驟如下:

  • 二分查找定位到segment
  • 在某個(gè)具體的segment文件中順序查找到具體message
  • 另外,為效率考慮,index所以文件是直接映射到內(nèi)存的

例如:查找offset==23的message

  • 二分查找到具體segment為00000000000000000012
  • 在00000000000000000012內(nèi)部順序找到offset=23的message
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容