kafka 基礎(chǔ)知識大全

本文包括kafka的定義、安裝尺借、啟動(dòng)绊起、架構(gòu)、工作流程燎斩、原理虱歪、生產(chǎn)者、消費(fèi)者栅表、分區(qū)笋鄙、ISR節(jié)點(diǎn)、HW怪瓶、分區(qū)分配策略萧落、offset、高效讀寫機(jī)制洗贰。

1. Kafka 概述

1.1 定義

Kakfa 是一個(gè)分布式的基于發(fā)布/訂閱模式的消息隊(duì)列(message queue)铐尚,主要應(yīng)用于大數(shù)據(jù)的實(shí)時(shí)處理領(lǐng)域。

1.2 消息隊(duì)列

1.2.1 傳統(tǒng)消息隊(duì)列與新式消息隊(duì)列模式

上面是傳統(tǒng)的消息隊(duì)列哆姻,比如一個(gè)用戶要注冊信息宣增,當(dāng)用戶信息寫入數(shù)據(jù)庫后,后面還有一些其他流程矛缨,比如發(fā)送短信爹脾,則需要等這些流程處理完成后,再返回給用戶箕昭。而新式隊(duì)列灵妨,比如一個(gè)用戶注冊信息,數(shù)據(jù)直接丟進(jìn)數(shù)據(jù)庫落竹,就直接返回給用戶成功泌霍。

1.2.2 使用消息隊(duì)列的好處
  • 解耦
  • 可恢復(fù)性
  • 緩沖
  • 靈活性與峰值處理能力
  • 異步通信
1.2.3 消息隊(duì)列的模式

1) 點(diǎn)對點(diǎn)模式

消息生產(chǎn)者發(fā)送消息到消息隊(duì)列中,然后消息消費(fèi)者從隊(duì)列中取出并且消費(fèi)消息述召,消息被消費(fèi)后朱转,隊(duì)列中不在存儲(chǔ)蟹地。所以消息消費(fèi)者不可能消費(fèi)到已經(jīng)被消費(fèi)的消息;隊(duì)列支持存在多個(gè)消費(fèi)者藤为,但是對于一個(gè)消息而言怪与,只會(huì) 有一個(gè)消費(fèi)者可以消費(fèi);如果想發(fā)給多個(gè)消費(fèi)者缅疟,則需要多次發(fā)送該條消息分别。

2) 發(fā)布/訂閱模式(一對多,消費(fèi)者消費(fèi)數(shù)據(jù)之后不會(huì)清除消息)

消息生產(chǎn)者將消息發(fā)布到 topic 中存淫,同時(shí)有多個(gè)消息消費(fèi)者(訂閱)消費(fèi)該消息耘斩。和點(diǎn)對點(diǎn)的方式不同,發(fā)布到 topic 的消息會(huì)被所有的訂閱者消費(fèi)桅咆;但是數(shù)據(jù)保留是期限的括授,默認(rèn)是 7 天,因?yàn)樗皇谴鎯?chǔ)系統(tǒng)轧邪。Kafka 就是這種模式的。有兩種方式羞海,一種是是消費(fèi)者去主動(dòng)去消費(fèi)(拉燃捎蕖)消息,而不是生產(chǎn)者推送消息給消費(fèi)者却邓;另外一種就是生產(chǎn)者主動(dòng)推送消息給消費(fèi)者硕糊,類似公眾號。

1.3 Kafka 基礎(chǔ)架構(gòu)

Kafka 的基礎(chǔ)架構(gòu)主要有 broker腊徙、生產(chǎn)者简十、消費(fèi)者組構(gòu)成,當(dāng)前還包括 ZooKeeper撬腾。

生產(chǎn)者負(fù)責(zé)發(fā)送消息螟蝙,broker 負(fù)責(zé)緩沖消息,broker 中可以創(chuàng)建 topic民傻,每個(gè) topic 又有 partition 和 replication 的概念胰默。

消費(fèi)者組負(fù)責(zé)處理消息,同一個(gè)消費(fèi)者組的中消費(fèi)者不能消費(fèi)同一個(gè) partition 中的數(shù)據(jù)漓踢。消費(fèi)者組主要是提高消費(fèi)能力牵署,比如之前是一個(gè)消費(fèi)者消費(fèi) 100 條數(shù)據(jù),現(xiàn)在是 2 個(gè)消費(fèi)者消費(fèi) 100 條數(shù)據(jù)喧半,可以提高消費(fèi)能力奴迅。所以消費(fèi)者組的消費(fèi)者的個(gè)數(shù)要小于 partition 的個(gè)數(shù),不然就會(huì)有消費(fèi)者沒有 partition 可以消費(fèi)挺据,造成資源的浪費(fèi)取具。

注意:不同消費(fèi)者組的消費(fèi)者是可以消費(fèi)相同的 partition 數(shù)據(jù)脖隶。

Kakfa 如果要組件集群,則只需要注冊到一個(gè) ZooKeeper 中就可以了者填,ZooKeeper 中還保留消息消費(fèi)的進(jìn)度或者說偏移量或者消費(fèi)位置浩村。

  • 0.9 之前的版本偏移量存儲(chǔ)在 ZooKeeper;

  • 0.9 之后的版本偏移量存儲(chǔ)在 Kafka中占哟。Kafka 定義了一個(gè)系統(tǒng) topic心墅,專用用來存儲(chǔ)偏移量的數(shù)據(jù)。

為什么要改榨乎?

主要是考慮到頻繁更改偏移量怎燥,對 ZooKeeper 的壓力較大,而且 Kafka 本身自己的處理也較復(fù)雜蜜暑。

1.4 安裝 Kafka

  1. Kafka 的安裝只需要解壓安裝包就可以完成安裝铐姚。
tar -zxvf kafka_2.11-2.1.1.tgz -C /usr/local/
  1. 查看配置文件。
[root@es1 config]# pwd/usr/local/kafka/config[root@es1 config]# lltotal 84-rw-r--r--. 1 root root  906 Feb  8  2019 connect-console-sink.properties-rw-r--r--. 1 root root  909 Feb  8  2019 connect-console-source.properties-rw-r--r--. 1 root root 5321 Feb  8  2019 connect-distributed.properties-rw-r--r--. 1 root root  883 Feb  8  2019 connect-file-sink.properties-rw-r--r--. 1 root root  881 Feb  8  2019 connect-file-source.properties-rw-r--r--. 1 root root 1111 Feb  8  2019 connect-log4j.properties-rw-r--r--. 1 root root 2262 Feb  8  2019 connect-standalone.properties-rw-r--r--. 1 root root 1221 Feb  8  2019 consumer.properties-rw-r--r--. 1 root root 4727 Feb  8  2019 log4j.properties-rw-r--r--. 1 root root 1925 Feb  8  2019 producer.properties-rw-r--r--. 1 root root 6865 Jan 16 22:00 server-1.properties-rw-r--r--. 1 root root 6865 Jan 16 22:00 server-2.properties-rw-r--r--. 1 root root 6873 Jan 16 03:57 server.properties-rw-r--r--. 1 root root 1032 Feb  8  2019 tools-log4j.properties-rw-r--r--. 1 root root 1169 Feb  8  2019 trogdor.conf-rw-r--r--. 1 root root 1023 Feb  8  2019 zookeeper.properties
  1. 修改配置文件 server.properties肛捍。

設(shè)置 broker.id 這個(gè)是 Kafka 集群區(qū)分每個(gè)節(jié)點(diǎn)的唯一標(biāo)志符隐绵。

  1. 設(shè)置 Kafka 的數(shù)據(jù)存儲(chǔ)路徑。

注意:這個(gè)目錄下不能有其他非 Kafka 目錄拙毫,不然會(huì)導(dǎo)致 Kafka 集群無法啟動(dòng)依许。

  1. 設(shè)置是否可以刪除 topic,默認(rèn) Kafka 的 topic 是不允許刪除的缀蹄。
  1. Kafka 的數(shù)據(jù)保留的時(shí)間峭跳,默認(rèn)是 7 天。
  1. Log 文件最大的大小缺前,如果 log 文件超過 1 G 會(huì)創(chuàng)建一個(gè)新的文件蛀醉。
  1. Kafka 連接的 ZooKeeper 的地址和連接 Kafka 的超時(shí)時(shí)間。
  1. 默認(rèn)的 partition 的個(gè)數(shù)衅码。

1.5 啟動(dòng) Kafka

  1. 啟動(dòng)方式一拯刁,Kafka 只能單節(jié)點(diǎn)啟動(dòng),所以每個(gè) Kakfa 節(jié)點(diǎn)都需要手動(dòng)啟動(dòng)逝段,下面的方式阻塞的方式啟動(dòng)筛璧。
  1. 啟動(dòng)方式二,守護(hù)的方式啟動(dòng)惹恃,推薦使用夭谤。

1.6 Kafka 操作

  1. 查看當(dāng)前 Kafka 集群已有的 topic。

注意:這里連接的 ZooKeeper巫糙,而不是連接的 Kafka朗儒。

  1. 創(chuàng)建 topic,指定分片和副本個(gè)數(shù)。

說明:replication-factor 副本數(shù)醉锄,replication-factor 分區(qū)數(shù)乏悄,topic 主題名。

如果當(dāng)前 Kafka 集群只有 3 個(gè) broker 節(jié)點(diǎn)恳不,則 replication-factor 最大就是 3 了檩小,下面的例子創(chuàng)建副本為 4,則會(huì)報(bào)錯(cuò)烟勋。

  1. 刪除 topic规求。

4) 查看 topic 信息。

1.7 啟動(dòng)生產(chǎn)者生產(chǎn)消息卵惦,Kafka 自帶一個(gè)生產(chǎn)者和消費(fèi)者的客戶端

  1. 啟動(dòng)一個(gè)生產(chǎn)者阻肿,注意此時(shí)連的 9092 端口,連接的 Kafka 集群沮尿。
  1. 啟動(dòng)一個(gè)消費(fèi)者丛塌,注意此時(shí)連接的還是 9092 端口,在 0.9 版本之前連接的還是 2181 端口畜疾。

這里我們啟動(dòng) 2 個(gè)消費(fèi)者來測試一下赴邻。

說明:如果不指定的消費(fèi)者組的配置文件的話,默認(rèn)每個(gè)消費(fèi)者都屬于不同的消費(fèi)者組啡捶。

  1. 發(fā)送消息姥敛,可以看到每個(gè)消費(fèi)者都能收到消息。

4)Kakfa 中的實(shí)際數(shù)據(jù)届慈。

2. Kafka 架構(gòu)深入

Kafka 不能保證消息的全局有序徒溪,只能保證消息在 partition 內(nèi)有序忿偷,因?yàn)橄M(fèi)者消費(fèi)消息是在不同的 partition 中隨機(jī)的金顿。

2.1 Kafka 的工作流程

Kafka 中的消息是以 topic 進(jìn)行分類的,生產(chǎn)者生成消息鲤桥、消費(fèi)者消費(fèi)消息都面向 topic揍拆。

Topic 是一個(gè)邏輯上的概念,而 partition 是物理上的概念茶凳。每個(gè) partition 又有副本的概念嫂拴。每個(gè) partition 對應(yīng)于一個(gè) log 文件,該 log 文件中存儲(chǔ)的就是生產(chǎn)者生成的數(shù)據(jù)贮喧,生產(chǎn)者生成的數(shù)據(jù)會(huì)不斷的追加到該 log 的文件末端筒狠,且每條數(shù)據(jù)都有自己的 offset,消費(fèi)者都會(huì)實(shí)時(shí)記錄自己消費(fèi)到了那個(gè) offset箱沦,以便出錯(cuò)的時(shí)候從上次的位置繼續(xù)消費(fèi)辩恼,這個(gè) offset 就保存在 index 文件中。Kafka 的 offset 是分區(qū)內(nèi)有序的,但是在不同分區(qū)中是無順序的灶伊,Kafka 不保證數(shù)據(jù)的全局有序疆前。

2.2 Kafka 原理

由于生產(chǎn)者生產(chǎn)的消息會(huì)不斷追加到 log 文件的末尾,為防止 log 文件過大導(dǎo)致數(shù)據(jù)定位效率低下聘萨,Kafka 采用分片和索引的機(jī)制竹椒,將每個(gè) partition 分為多個(gè) segment,每個(gè) segment 對應(yīng)2個(gè)文件 — index 文件和 log 文件米辐,這 2 個(gè)文件位于一個(gè)相同的文件夾下胸完,文件夾的命名規(guī)則為:topic 名稱 + 分區(qū)序號。

Index 和 log 的文件的文件名是當(dāng)前這個(gè)索引是最小的數(shù)據(jù)的 offset儡循。Kafka 如何快速的消費(fèi)數(shù)據(jù)呢舶吗?

Index 文件中存儲(chǔ)的數(shù)據(jù)的索引信息,第一列是 offset择膝,第二列這這個(gè)數(shù)據(jù)所對應(yīng)的 log 文件中的偏移量誓琼,就像我們?nèi)プx文件,使用 seek() 設(shè)置當(dāng)前鼠標(biāo)的位置一樣肴捉,可以更快的找到數(shù)據(jù)腹侣。

如果要去消費(fèi) offset 為 3 的數(shù)據(jù),首先通過二分法找到數(shù)據(jù)在哪個(gè) index 文件中齿穗,然后在通過 index 中 offset 找到數(shù)據(jù)在 log 文件中的 offset傲隶;這樣就可以快速的定位到數(shù)據(jù),并消費(fèi)窃页。

所以跺株,Kakfa 雖然把數(shù)據(jù)存儲(chǔ)在磁盤中,但是他的讀取速度還是非巢甭簦快的乒省。

3. Kafka 生產(chǎn)者和消費(fèi)者

3.1 Kafka 生產(chǎn)者

Kafka 的 partition 分區(qū)的作用

Kafka 分區(qū)的原因主要就是提供并發(fā)提高性能,因?yàn)樽x寫是 partition 為單位讀寫的畦木;那生產(chǎn)者發(fā)送消息是發(fā)送到哪個(gè) partition 中呢袖扛?

  1. 在客戶端中指定 partition;

  2. 輪詢(推薦)消息1去 p1十籍,消息2去 p2蛆封,消息3去 p3,消息4去 p1勾栗,消息5去 p2惨篱,消息6去 p3……

3.2 Kafka 如何保證數(shù)據(jù)可靠性呢?****通過 ack 來保證

為保證生產(chǎn)者發(fā)送的數(shù)據(jù)围俘,能可靠的發(fā)送到指定的 topic砸讳,topic 的每個(gè) partition 收到生產(chǎn)者發(fā)送的數(shù)據(jù)后机断,都需要向生產(chǎn)者發(fā)送 ack(確認(rèn)收到),如果生產(chǎn)者收到 ack绣夺,就會(huì)進(jìn)行下一輪的發(fā)送吏奸,否則重新發(fā)送數(shù)據(jù)。

那么 Kafka 什么時(shí)候向生產(chǎn)者發(fā)送 ack陶耍?

確保 follower 和 leader 同步完成奋蔚,leader 在發(fā)送 ack 給生產(chǎn)者,這樣才能確保 leader 掛掉之后烈钞,能在 follower 中選舉出新的 leader 后泊碑,數(shù)據(jù)不會(huì)丟失。

那多少個(gè) follower 同步完成后發(fā)送 ack毯欣?

  • 方案1:半數(shù)已經(jīng)完成同步馒过,就發(fā)送 ack;

  • 方案2:全部完成同步酗钞,才發(fā)送 ack(Kafka采用這種方式)

采用第二種方案后腹忽,設(shè)想以下場景:leader 收到數(shù)據(jù),所有的 follower 都開始同步數(shù)據(jù)砚作,但是有一個(gè) follower 因?yàn)槟撤N故障窘奏,一直無法完成同步,那 leader 就要一直等下葫录,直到他同步完成着裹,才能發(fā)送 ack。這樣就非常影響效率米同,這個(gè)問題怎么解決骇扇?

Leader 維護(hù)了一個(gè)動(dòng)態(tài)的 ISR 列表(同步副本的作用),只需要這個(gè)列表的中的 follower 和 leader 同步面粮;當(dāng) ISR 中的 follower 完成數(shù)據(jù)的同步之后少孝,leader 就會(huì)給生產(chǎn)者發(fā)送 ack,如果 follower 長時(shí)間未向 leader 同步數(shù)據(jù)但金,則該 follower 將被剔除ISR韭山,這個(gè)時(shí)間閾值也是自定義的郁季;同樣 leader 故障后冷溃,就會(huì)從 ISR 中選舉新的 leader。

怎么選擇 ISR 的節(jié)點(diǎn)呢梦裂?

首先通信的時(shí)間要快似枕,要和 leader 要可以很快的完成通信,這個(gè)時(shí)間默認(rèn)是 10s

然后就看 leader 數(shù)據(jù)差距年柠,消息條數(shù)默認(rèn)是 10000 條(后面版本被移除)

為什么移除:因?yàn)?Kafka 發(fā)送消息是批量發(fā)送的凿歼,所以會(huì)一瞬間 leader 接受完成,但是 follower 還沒有拉取,所以會(huì)頻繁踢出和加入ISR答憔,這個(gè)數(shù)據(jù)會(huì)保存到 ZooKeeper 和內(nèi)存中味赃,所以會(huì)頻繁更新 ZooKeeper 和內(nèi)存。

但是對于某些不太重要的數(shù)據(jù)虐拓,對數(shù)據(jù)的可靠性要求不是很高,能夠容忍數(shù)據(jù)的少量丟失,所以沒必要等 ISR 中的 follower 全部接受成功甘畅。所以 Kafka 為用戶提供了三種可靠性級別搂橙,用戶可以根據(jù)可靠性和延遲進(jìn)行權(quán)衡,這個(gè)設(shè)置在kafka的生成中設(shè)置:ack 參數(shù)設(shè)置态兴。

1) acks 為 0

生產(chǎn)者不等 ack狠持,只管往 topic 丟數(shù)據(jù)就可以了,這個(gè)丟數(shù)據(jù)的概率非常高瞻润。

2) ack為 1

leader 落盤后就會(huì)返回 ack喘垂,會(huì)有數(shù)據(jù)丟失的現(xiàn)象,如果 leader 在同步完成后出現(xiàn)故障绍撞,則會(huì)出現(xiàn)數(shù)據(jù)丟失王污。

3) ack為-1(all)

leader 和 follower(ISR)落盤才會(huì)返回 ack,會(huì)有數(shù)據(jù)重復(fù)現(xiàn)象楚午,如果在 leader 已經(jīng)寫完成昭齐,且 follower 同步完成,但是在返回ack的出現(xiàn)故障矾柜,則會(huì)出現(xiàn)數(shù)據(jù)重復(fù)現(xiàn)象阱驾;極限情況下,這個(gè)也會(huì)有數(shù)據(jù)丟失的情況怪蔑,比如 follower 和 leader 通信都很慢里覆,所以 ISR 中只有一個(gè) leader 節(jié)點(diǎn),這個(gè)時(shí)候缆瓣,leader 完成落盤喧枷,就會(huì)返回 ack,如果此時(shí) leader 故障后弓坞,就會(huì)導(dǎo)致丟失數(shù)據(jù)隧甚。

3.3 Kafka 如何保證消費(fèi)數(shù)據(jù)的一致性?****通過HW來保證

  • LEO:指每個(gè) follower 的最大的 offset渡冻;

  • HW(高水位):指消費(fèi)者能見到的最大的 offset戚扳,LSR 隊(duì)列中最小的 LEO,也就是說消費(fèi)者只能看到1~6的數(shù)據(jù)族吻,后面的數(shù)據(jù)看不到帽借,也消費(fèi)不了珠增。

避免 leader 掛掉后,比如當(dāng)前消費(fèi)者消費(fèi)8這條數(shù)據(jù)后砍艾,leader 掛了蒂教,此時(shí)比如 f2 成為 leader,f2 根本就沒有9這條數(shù)據(jù)脆荷,那么消費(fèi)者就會(huì)報(bào)錯(cuò)悴品,所以設(shè)計(jì)了 HW 這個(gè)參數(shù),只暴露最少的數(shù)據(jù)給消費(fèi)者简烘,避免上面的問題苔严。

3.3.1 HW 保證數(shù)據(jù)存儲(chǔ)的一致性

1) follower 故障

follower 發(fā)生故障后會(huì)被臨時(shí)提出 LSR,待該 follower 恢復(fù)后孤澎,follower 會(huì)讀取本地的磁盤記錄的上次的 HW届氢,并將該 log 文件高于 HW 的部分截取掉,從 HW 開始向 leader 進(jìn)行同步覆旭,等該 follower 的 LEO 大于等于該 partition 的 hw退子,即 follower 追上leader后,就可以重新加入 LSR型将。

2) leader 故障

leader 發(fā)生故障后寂祥,會(huì)從 ISR 中選出一個(gè)新的 leader,之后七兜,為了保證多個(gè)副本之間的數(shù)據(jù)一致性丸凭,其余的 follower 會(huì)先將各自的 log 文件高于 hw 的部分截掉(新 leader 自己不會(huì)截掉),然后從新的 leader 同步數(shù)據(jù)腕铸。

注意:這個(gè)是為了保證多個(gè)副本間的數(shù)據(jù)存儲(chǔ)的一致性惜犀,并不能保證數(shù)據(jù)不丟失或者不重復(fù)。

3.3.2 精準(zhǔn)一次(冪等性)狠裹,保證數(shù)據(jù)不重復(fù)
  • ack 設(shè)置為 -1虽界,則可以保證數(shù)據(jù)不丟失,但是會(huì)出現(xiàn)數(shù)據(jù)重復(fù)(at least once)

  • ack 設(shè)置為 0涛菠,則可以保證數(shù)據(jù)不重復(fù)莉御,但是不能保證數(shù)據(jù)不丟失(at most once)

但是如果魚和熊掌兼得,該怎么辦俗冻?這個(gè)時(shí)候就就引入了 Exact once(精準(zhǔn)一次)礁叔。

在 0.11 版本后,引入冪等性解決 Kakfa 集群內(nèi)部的數(shù)據(jù)重復(fù)言疗,在 0.11 版本之前晴圾,在消費(fèi)者處自己做處理颂砸。如果啟用了冪等性噪奄,則 ack 默認(rèn)就是-1死姚,Kafka 就會(huì)為每個(gè)生產(chǎn)者分配一個(gè) pid,并未每條消息分配 seqnumber勤篮,如果 pid都毒、partition、seqnumber 三者一樣碰缔,則 Kafka 認(rèn)為是重復(fù)數(shù)據(jù)账劲,就不會(huì)落盤保存;但是如果生產(chǎn)者掛掉后金抡,也會(huì)出現(xiàn)有數(shù)據(jù)重復(fù)的現(xiàn)象瀑焦;所以冪等性解決在單次會(huì)話的單個(gè)分區(qū)的數(shù)據(jù)重復(fù),但是在分區(qū)間或者跨會(huì)話的是數(shù)據(jù)重復(fù)的是無法解決的梗肝。

3.4 Kafka 消費(fèi)者

3.4.1 消費(fèi)方式

消息隊(duì)列有兩種消費(fèi)消息的方式榛瓮,push(微信公眾號)、pull(kafka)巫击。push 模式很難適應(yīng)消費(fèi)速率不同的消費(fèi)者禀晓,因?yàn)橄M(fèi)發(fā)送速率是由 broker 決定的,他的目標(biāo)是盡可能以最快的的速度傳遞消息坝锰,但是這樣很容易造成消費(fèi)者來不及處理消息粹懒,典型的表現(xiàn)就是拒絕服務(wù)以及網(wǎng)絡(luò)擁塞。而 pull 的方式可以消費(fèi)者的消費(fèi)能力以適當(dāng)?shù)乃俾氏M(fèi)消息顷级。

pull 模式的不足之處是如果 Kafka 沒有數(shù)據(jù)凫乖,消費(fèi)者可能會(huì)陷入死循環(huán),一直返回空數(shù)據(jù)弓颈,針對這一點(diǎn)拣凹,Kafka 消費(fèi)者在消費(fèi)數(shù)據(jù)時(shí)候回傳遞一個(gè) timeout 參數(shù),如果當(dāng)時(shí)沒有數(shù)據(jù)可供消費(fèi)恨豁,消費(fèi)者會(huì)等待一段時(shí)間在返回嚣镜。

3.4.2 分區(qū)分配策略

一個(gè)消費(fèi)者組有多個(gè)消費(fèi)者,一個(gè) topic 有多個(gè) partition橘蜜。所以必然會(huì)涉及到 partition 的分配問題菊匿,即確定哪個(gè) partition 由哪個(gè)消費(fèi)者來消費(fèi)。Kafka 提供兩種方式计福,一種是輪詢(RountRobin)對于 topic 組生效跌捆,一種是(Range)對于單個(gè)topic生效

輪詢:前置條件是需要一個(gè)消費(fèi)者里的消費(fèi)者訂閱的是相同的 topic。不然就會(huì)出現(xiàn)問題象颖;非默認(rèn)的的方式佩厚。

同一個(gè)消費(fèi)者組里的消費(fèi)者不能同時(shí)消費(fèi)同一個(gè)分區(qū),比如三個(gè)消費(fèi)者消費(fèi)一個(gè) topic 的 9 個(gè)分區(qū)说订。

如果一個(gè)消費(fèi)者組里有2個(gè)消費(fèi)者抄瓦,這個(gè)消費(fèi)者組里同時(shí)消費(fèi) 2 個(gè) topic潮瓶,每個(gè) topic 又有三個(gè) partition。首先會(huì)把 2 個(gè) topic 當(dāng)做一個(gè)主題钙姊,然后根據(jù) topic 和 partition 做 hash毯辅,然后在按照 hash 排序。然后輪詢分配給一個(gè)消費(fèi)者組中的 2 個(gè)消費(fèi)者煞额。

如果是下面這樣的方式訂閱的呢思恐?

比如有 3 個(gè) topic,每個(gè) topic 有 3 個(gè) partition膊毁,一個(gè)消費(fèi)者組中有 2 個(gè)消費(fèi)者胀莹。消費(fèi)者1訂閱 topic1 和 topic2,消費(fèi)者2訂閱 topic2 和 topic3婚温。那么這樣的場景嗜逻,使用輪訓(xùn)的方式訂閱 topic 就會(huì)有問題。

如果是下面這種方式訂閱呢缭召?

比如有2個(gè) topic栈顷,每個(gè) topic 有3個(gè) partition,一個(gè)消費(fèi)者組 有2個(gè)消費(fèi)者嵌巷,消費(fèi)者1訂閱 topic1萄凤,消費(fèi)者2訂閱 topic2,這樣使用輪訓(xùn)的方式訂閱 topic 也會(huì)有問題搪哪。

所以我們一直強(qiáng)調(diào)靡努,使用輪訓(xùn)的方式訂閱 topic 的前提是一個(gè)消費(fèi)者組中的所有消費(fèi)者訂閱的主題是一樣的;所以輪詢的方式不是 Kafka 默認(rèn)的方式晓折;Range 是按照單個(gè) topic 來劃分的惑朦,默認(rèn)的分配方式。

Range 的問題會(huì)出現(xiàn)消費(fèi)者數(shù)據(jù)不均衡的問題漓概。比如下面的例子漾月,一個(gè)消費(fèi)者組訂閱了 2 個(gè) topic,就會(huì)出現(xiàn)消費(fèi)者1消費(fèi) 4 個(gè) partition胃珍,而另外一個(gè)消費(fèi)者只消費(fèi) 2 個(gè) partition梁肿。

分區(qū)策略什么時(shí)候會(huì)觸發(fā)呢?當(dāng)消費(fèi)者組里的消費(fèi)者個(gè)數(shù)變化的時(shí)候觅彰,會(huì)觸發(fā)分區(qū)策略調(diào)整吩蔑,比如消費(fèi)者里增加消費(fèi)者,或者減少消費(fèi)者填抬。

3.4.3 維護(hù) offset

由于消費(fèi)者在消費(fèi)過程中可能會(huì)出現(xiàn)斷電宕機(jī)等故障烛芬,消費(fèi)者恢復(fù)后,需要從故障前的位置繼續(xù)消費(fèi),所以消費(fèi)者需要實(shí)施記錄自己消費(fèi)哪個(gè) offset赘娄,以便故障恢復(fù)后繼續(xù)消費(fèi)仆潮。

Offset保存的位置有2個(gè),一個(gè) ZooKeeper擅憔,一個(gè)是 Kafka鸵闪。首先看下 offset 保存到 ZooKeeper檐晕,由消費(fèi)者組暑诸、topic、partition 三個(gè)元素確定唯一的 offset辟灰。

所以消費(fèi)者組中的某個(gè)消費(fèi)者掛掉之后个榕,或者的消費(fèi)者還是可以拿到這個(gè) offset。

Controller 這個(gè)節(jié)點(diǎn)和 ZooKeeper 通信芥喇,同步數(shù)據(jù)西采,這個(gè)節(jié)點(diǎn)就是誰先起來,誰就先注冊 controller继控,誰就是 controller械馆。其他節(jié)點(diǎn)和 controller 信息保持同步。

3.4.5 消費(fèi)者組的案例

修改消費(fèi)者組 id

啟動(dòng)一個(gè)消費(fèi)者發(fā)送 3 條數(shù)據(jù)武通。

指定消費(fèi)者組啟動(dòng)消費(fèi)者霹崎,啟動(dòng)三個(gè)消費(fèi)者,可以看到每個(gè)消費(fèi)者消費(fèi)了一條數(shù)據(jù)冶忱。

在演示下不同組可以消費(fèi)同一個(gè) topic 的尾菇,我們看到 2 個(gè)消費(fèi)者的消費(fèi)者都消費(fèi)到同一條數(shù)據(jù)。再次啟動(dòng)一個(gè)消費(fèi)者囚枪,這個(gè)消費(fèi)者屬于另外一個(gè)消費(fèi)者組派诬。

4 Kafka 的高效讀寫機(jī)制

4.1 分布式部署

多節(jié)點(diǎn)并行操作。

4.2链沼、順序?qū)懘疟P

Kafka 的 producer 生產(chǎn)數(shù)據(jù)默赂,要寫入到 log 文件中,寫的過程中一直追加到文件末尾括勺,為順序?qū)懛趴桑倬W(wǎng)有數(shù)據(jù)表明。同樣的磁盤朝刊,順序?qū)懩艿?600M/S耀里,而隨機(jī)寫只有 100K/S。這與磁盤的機(jī)械結(jié)構(gòu)有關(guān)拾氓,順序?qū)懼钥旆肟妫且驗(yàn)槠涫∪チ舜罅看蓬^尋址的時(shí)間。

4.3、零復(fù)制技術(shù)

正常情況下房官,先把數(shù)據(jù)讀到內(nèi)核空間趾徽,在從內(nèi)核空間把數(shù)據(jù)讀到用戶空間,然后在調(diào)操作系統(tǒng)的 IO 接口寫到內(nèi)核空間翰守,最終在寫到硬盤中孵奶。

Kafka 是這樣做的,直接在內(nèi)核空間流轉(zhuǎn) IO 流蜡峰,所以 Kafka 的性能非常高了袁。

5. ZooKeeper 在 Kafka 中的作用

Kafka 集群中有一個(gè) broker 會(huì)被選舉為 controller,負(fù)責(zé)管理集群 broker 的上下線湿颅,所有的 topic 的分區(qū)副本分配和 leader 選舉等工作载绿。

引用鏈接:https://www.cnblogs.com/bainianminguo/p/12247158.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市油航,隨后出現(xiàn)的幾起案子崭庸,更是在濱河造成了極大的恐慌,老刑警劉巖谊囚,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件怕享,死亡現(xiàn)場離奇詭異,居然都是意外死亡镰踏,警方通過查閱死者的電腦和手機(jī)函筋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來余境,“玉大人驻呐,你說我怎么就攤上這事》祭矗” “怎么了含末?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長即舌。 經(jīng)常有香客問我佣盒,道長,這世上最難降的妖魔是什么顽聂? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任肥惭,我火速辦了婚禮,結(jié)果婚禮上紊搪,老公的妹妹穿的比我還像新娘蜜葱。我一直安慰自己,他們只是感情好耀石,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布牵囤。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪揭鳞。 梳的紋絲不亂的頭發(fā)上炕贵,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機(jī)與錄音野崇,去河邊找鬼称开。 笑死,一個(gè)胖子當(dāng)著我的面吹牛乓梨,可吹牛的內(nèi)容都是我干的鳖轰。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼督禽,長吁一口氣:“原來是場噩夢啊……” “哼脆霎!你這毒婦竟也來了总处?” 一聲冷哼從身側(cè)響起狈惫,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鹦马,沒想到半個(gè)月后胧谈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡荸频,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年菱肖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旭从。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡稳强,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出和悦,到底是詐尸還是另有隱情退疫,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布鸽素,位于F島的核電站褒繁,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏馍忽。R本人自食惡果不足惜棒坏,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望遭笋。 院中可真熱鬧坝冕,春花似錦、人聲如沸瓦呼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至谎替,卻和暖如春偷溺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钱贯。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工挫掏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人秩命。 一個(gè)月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓尉共,卻偏偏與公主長得像,于是被迫代替她去往敵國和親弃锐。 傳聞我的和親對象是個(gè)殘疾皇子袄友,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

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