kafka原理

面試在即向图,對kafka和MetaQ做一個整理晾咪,復(fù)習一波碟嘴。

消息隊列作用 : 異步/解耦/削峰

概述

  1. Apache Kafka是一個開源消息系統(tǒng),由Scala寫成鼓拧。是由Apache軟件基金會開發(fā)的一個開源消息系統(tǒng)項目半火。
  2. 目標是為處理實時數(shù)據(jù)提供一個統(tǒng)一、高通量季俩、低等待的平臺钮糖。
  3. Kafka是一個分布式消息隊列。Kafka對消息保存時根據(jù)Topic進行歸類酌住,發(fā)送消息者稱為Producer店归,消息接受者稱為Consumer,此外kafka集群有多個kafka實例組成赂韵,每個實例(server)稱為broker娱节。
  4. 無論是kafka集群,還是consumer都依賴于zookeeper集群保存一些meta信息祭示,來保證系統(tǒng)可用性肄满。
架構(gòu)圖
整體架構(gòu)簡圖
詳細架構(gòu)圖

同一個組的消費者 不能消費同一個partition

名詞解析:

  • Producer :消息生產(chǎn)者,就是向kafka broker發(fā)消息的客戶端质涛;
  • Consumer :消息消費者稠歉,向kafka broker取消息的客戶端;
  • Topic :主題汇陆,可以理解為一個隊列怒炸;
  • Broker :一臺kafka服務(wù)器就是一個broker。一個集群由多個broker組成毡代。一個broker可以容納多個topic阅羹;
  • Partition:為了實現(xiàn)擴展性,一個非常大的topic可以分布到多個broker(即服務(wù)器)上教寂,一個topic可以分為多個partition捏鱼,每個partition是一個有序的隊列。partition中的每條消息都會被分配一個有序的id(offset)酪耕。\color{red}{kafka只保證按一個partition中的順序?qū)⑾l(fā)給consumer导梆,不保證一個topic的整體(多個partition間)的順序;}
  • Consumer Group (CG):這是kafka用來實現(xiàn)一個topic消息的廣播(發(fā)給所有的consumer)和單播(發(fā)給任意一個consumer)的手段迂烁。一個topic可以有多個CG看尼。topic的消息會復(fù)制(不是真的復(fù)制,是概念上的)到所有的CG盟步,但每個partion只會把消息發(fā)給該CG中的一個consumer藏斩。如果需要實現(xiàn)廣播,只要每個consumer有一個獨立的CG就可以了却盘。要實現(xiàn)單播只要所有的consumer在同一個CG狰域。用CG還可以將consumer進行自由的分組而不需要多次發(fā)送消息到不同的topic窜觉;
內(nèi)部實現(xiàn)原理
  • 點對點模式(一對一,消費者主動拉取數(shù)據(jù)北专,消息收到后消息清除)
    點對點模型通常是一個基于拉取或者輪詢的消息傳送模型,這種模型從隊列中請求信息旬陡,而不是將消息推送到客戶端拓颓。這個模型的特點是發(fā)送到隊列的消息被一個且只有一個接收者接收處理,即使有多個消息監(jiān)聽者也是如此描孟。
  • 發(fā)布/訂閱模式(一對多驶睦,數(shù)據(jù)生產(chǎn)后,推送給所有訂閱者)
    發(fā)布訂閱模型則是一個基于推送的消息傳送模型匿醒。發(fā)布訂閱模型可以有多種不同的訂閱者场航,臨時訂閱者只在主動監(jiān)聽主題時才接收消息,而持久訂閱者則監(jiān)聽主題的所有消息廉羔,即使當前訂閱者不可用溉痢,處于離線狀態(tài)。

安裝部署與常用客戶端命令:

此過程忽略憋他,準備單獨寫一篇文章整理孩饼。


生產(chǎn)過程分析

1. 寫入方式

producer采用推(push)模式將消息發(fā)布到broker,每條消息都被追加(append)到分區(qū)(patition)中竹挡,屬于順序?qū)懘疟P(順序?qū)懘疟P效率比隨機寫內(nèi)存要高镀娶,保障kafka吞吐率)。

2.分區(qū)(Partition)

消息發(fā)送時都被發(fā)送到一個topic揪罕,其本質(zhì)就是一個目錄梯码,而topic是由一些Partition Logs(分區(qū)日志)組成,其組織結(jié)構(gòu)如下圖所示:

分區(qū)示意圖

我們可以看到好啰,每個Partition中的消息都是有序的轩娶,生產(chǎn)的消息被不斷追加到Partition log上,其中的每一個消息都被賦予了一個唯一的offset值坎怪。

  • 分區(qū)原因:
    1. 方便在集群中擴展罢坝,每個Partition可以通過調(diào)整以適應(yīng)它所在的機器,而一個topic又可以有多個Partition組成搅窿,因此整個集群就可以適應(yīng)任意大小的數(shù)據(jù)了嘁酿;
    2. 可以提高并發(fā),因為可以以Partition為單位讀寫了男应。
  • 分區(qū)規(guī)則:
    1.指定了patition闹司,則直接使用;
    2.未指定patition但指定key沐飘,通過對key的value進行hash出一個patition游桩;
    3. patition和key都未指定牲迫,使用輪詢選出一個patition。
//DefaultPartitioner類
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
        List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
        int numPartitions = partitions.size();
        if (keyBytes == null) {
            int nextValue = nextValue(topic);
            List<PartitionInfo> availablePartitions = cluster.availablePartitionsForTopic(topic);
            if (availablePartitions.size() > 0) {
                int part = Utils.toPositive(nextValue) % availablePartitions.size();
                return availablePartitions.get(part).partition();
            } else {
                // no partitions are available, give a non-available partition
                return Utils.toPositive(nextValue) % numPartitions;
            }
        } else {
            // hash the keyBytes to choose a partition
            return Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
        }
    }

3. 副本(Replication)

同一個partition可能會有多個replication(對應(yīng) server.properties 配置中的 default.replication.factor=N)借卧。沒有replication的情況下盹憎,一旦broker 宕機,其上所有 patition 的數(shù)據(jù)都不可被消費铐刘,同時producer也不能再將數(shù)據(jù)存于其上的patition陪每。引入replication之后,同一個partition可能會有多個replication镰吵,而這時需要在這些replication之間選出一個leader檩禾,producer和consumer只與這個leader交互,其它replication作為follower從leader 中復(fù)制數(shù)據(jù)疤祭。

4.寫入流程
producer寫入流程

1)producer先從zookeeper的 "/brokers/.../state"節(jié)點找到該partition的leader
2)producer將消息發(fā)送給該leader
3)leader將消息寫入本地log
4)followers從leader pull消息盼产,寫入本地log后向leader發(fā)送ACK
5)leader收到所有ISR中的replication的ACK后,增加HW(high watermark勺馆,最后commit 的offset)并向producer發(fā)送ACK


Broker 保存消息

1.存儲方式

物理上把topic分成一個或多個patition(對應(yīng) server.properties 中的num.partitions=3配置)戏售,每個patition物理上對應(yīng)一個文件夾(該文件夾存儲該patition的所有消息和索引文件),如下:


image.png
2.存儲策略

無論消息是否被消費草穆,kafka都會保留所有消息蜈项。有兩種策略可以刪除舊數(shù)據(jù):
1)基于時間:log.retention.hours=168
2)基于大小:log.retention.bytes=1073741824
需要注意的是续挟,因為Kafka讀取特定消息的時間復(fù)雜度為O(1)紧卒,即與文件大小無關(guān),所以這里刪除過期文件與提高 Kafka 性能無關(guān)诗祸。

3. Zookeeper存儲結(jié)構(gòu)

D5FED6A327594F818264133F86E26E36.jpg

producer不在zk中注冊跑芳,消費者在zk中注冊。


Kafka消費過程分析

kafka提供了兩套consumer API:高級Consumer API和低級Consumer API直颅。

1.高級API
  • 優(yōu)點:
    高級API 寫起來簡單
    不需要自行去管理offset博个,系統(tǒng)通過zookeeper自行管理。
    不需要管理分區(qū)功偿,副本等情況盆佣,.系統(tǒng)自動管理。
    消費者斷線會自動根據(jù)上一次記錄在zookeeper中的offset去接著獲取數(shù)據(jù)(默認設(shè)置1分鐘更新一下zookeeper中存的offset)
    可以使用group來區(qū)分對同一個topic 的不同程序訪問分離開來(不同的group記錄不同的offset械荷,這樣不同程序讀取同一個topic才不會因為offset互相影響)
  • 缺點:
    不能自行控制offset(對于某些特殊需求來說)
    不能細化控制如分區(qū)共耍、副本、zk等
2.低級API
  • 優(yōu)點:
    能夠讓開發(fā)者自己控制offset吨瞎,想從哪里讀取就從哪里讀取痹兜。
    自行控制連接分區(qū),對分區(qū)自定義進行負載均衡
    對zookeeper的依賴性降低(如:offset不一定非要靠zk存儲颤诀,自行存儲offset即可字旭,比如存在文件或者內(nèi)存中)
  • 缺點:
    太過復(fù)雜对湃,需要自行控制offset,連接哪個分區(qū)遗淳,找到分區(qū)leader 等拍柒。
2.消費者組
消費者組

消費者是以consumer group消費者組的方式工作,由一個或者多個消費者組成一個組屈暗,共同消費一個topic斤儿。每個分區(qū)在同一時間只能由group中的一個消費者讀取,但是多個group可以同時消費這個partition恐锦。在圖中,有一個由三個消費者組成的group疆液,有一個消費者讀取主題中的兩個分區(qū)一铅,另外兩個分別讀取一個分區(qū)。某個消費者讀取某個分區(qū)堕油,也可以叫做某個消費者是某個分區(qū)的擁有者潘飘。
在這種情況下,消費者可以通過水平擴展的方式同時讀取大量的消息掉缺。另外卜录,如果一個消費者失敗了,那么其他的group成員會自動負載均衡讀取之前失敗的消費者讀取的分區(qū)眶明。

3. 消費方式

\color{red}{consumer采用pull(拉)模式從broker中讀取數(shù)據(jù)艰毒。}
push(推)模式很難適應(yīng)消費速率不同的消費者,因為消息發(fā)送速率是由broker決定的搜囱。它的目標是盡可能以最快速度傳遞消息丑瞧,但是這樣很容易造成consumer來不及處理消息,典型的表現(xiàn)就是拒絕服務(wù)以及網(wǎng)絡(luò)擁塞蜀肘。而pull模式則可以根據(jù)consumer的消費能力以適當?shù)乃俾氏M消息绊汹。
對于Kafka而言,pull模式更合適扮宠,它可簡化broker的設(shè)計西乖,consumer可自主控制消費消息的速率,同時consumer可以自己控制消費方式——即可批量消費也可逐條消費坛增,同時還能選擇不同的提交方式從而實現(xiàn)不同的傳輸語義获雕。
pull模式不足之處是,如果kafka沒有數(shù)據(jù)收捣,消費者可能會陷入循環(huán)中典鸡,一直等待數(shù)據(jù)到達。為了避免這種情況坏晦,我們在我們的拉請求中有參數(shù)萝玷,允許消費者請求在等待數(shù)據(jù)到達的“長輪詢”中進行阻塞(并且可選地等待到給定的字節(jié)數(shù)嫁乘,以確保大的傳輸大小)球碉。

4. 消費者組案例
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蜓斧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子睁冬,更是在濱河造成了極大的恐慌挎春,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件豆拨,死亡現(xiàn)場離奇詭異直奋,居然都是意外死亡,警方通過查閱死者的電腦和手機施禾,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進店門脚线,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人弥搞,你說我怎么就攤上這事邮绿。” “怎么了攀例?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵船逮,是天一觀的道長。 經(jīng)常有香客問我粤铭,道長挖胃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任梆惯,我火速辦了婚禮冠骄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘加袋。我一直安慰自己凛辣,他們只是感情好,可當我...
    茶點故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布职烧。 她就那樣靜靜地躺著扁誓,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚀之。 梳的紋絲不亂的頭發(fā)上蝗敢,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天,我揣著相機與錄音足删,去河邊找鬼寿谴。 笑死,一個胖子當著我的面吹牛失受,可吹牛的內(nèi)容都是我干的讶泰。 我是一名探鬼主播咏瑟,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼痪署!你這毒婦竟也來了码泞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤狼犯,失蹤者是張志新(化名)和其女友劉穎余寥,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體悯森,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡宋舷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了瓢姻。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片祝蝠。...
    茶點故事閱讀 38,646評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖汹来,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情改艇,我是刑警寧澤收班,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站谒兄,受9級特大地震影響摔桦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜承疲,卻給世界環(huán)境...
    茶點故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一邻耕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧燕鸽,春花似錦兄世、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至党远,卻和暖如春削解,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背沟娱。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工氛驮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人济似。 一個月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓矫废,卻偏偏與公主長得像盏缤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子磷脯,可洞房花燭夜當晚...
    茶點故事閱讀 43,514評論 2 348

推薦閱讀更多精彩內(nèi)容

  • Kafka的基本介紹 Kafka最初由Linkedin公司開發(fā)蛾找,是一個分布式、分區(qū)赵誓、多副本涮雷、多訂閱者甘有,基于zook...
    join_a922閱讀 1,403評論 0 1
  • 一、為什么需要消息系統(tǒng) 1.解耦:允許你獨立的擴展或修改兩邊的處理過程,只要確保它們遵守同樣的接口約束贴汪。2.冗余:...
    piziyang12138閱讀 270評論 0 0
  • 一、為什么需要消息系統(tǒng) 1.解耦:允許你獨立的擴展或修改兩邊的處理過程诽表,只要確保它們遵守同樣的接口約束猎塞。2.冗余:...
    數(shù)據(jù)萌新閱讀 246評論 0 0
  • 一、為什么需要消息系統(tǒng) 1.解耦:允許你獨立的擴展或修改兩邊的處理過程蔓罚,只要確保它們遵守同樣的接口約束椿肩。2.冗余:...
    小豬Harry閱讀 195評論 0 0
  • 1?,不是因為有了希望才堅持,而是因為堅持才有了希望.? 2?豺谈,不是因為有了機會才爭取,而是因為爭取了才有機會.?...
    公爵在路上閱讀 282評論 0 1