ISR、OSR、AR 是什么?
ISR、OSR、AR 是什么?
ISR:In-Sync Replicas 副本同步隊(duì)列
OSR:Out-of-Sync Replicas
AR:Assigned Replicas 所有副本
ISR是由leader維護(hù),follower從leader同步數(shù)據(jù)有一些延遲(具體可以參見 圖文了解 Kafka 的副本復(fù)制機(jī)制),超過相應(yīng)的閾值會(huì)把 follower 剔除出 ISR, 存入OSR(Out-of-Sync Replicas )列表,新加入的follower也會(huì)先存放在OSR中。AR=ISR+OSR。
LEO、HW、LSO、LW等分別代表什么
LEO:是 LogEndOffset 的簡(jiǎn)稱,代表當(dāng)前日志文件中下一條
HW:水位或水?。╳atermark)一詞,也可稱為高水位(high watermark),通常被用在流式處理領(lǐng)域(比如Apache Flink、Apache Spark等),以表征元素或事件在基于時(shí)間層面上的進(jìn)度。在Kafka中,水位的概念反而與時(shí)間無關(guān),而是與位置信息相關(guān)。嚴(yán)格來說,它表示的就是位置信息,即位移(offset)。取 partition 對(duì)應(yīng)的 ISR中 最小的 LEO 作為 HW,consumer 最多只能消費(fèi)到 HW 所在的位置上一條信息。
LSO:是 LastStableOffset 的簡(jiǎn)稱,對(duì)未完成的事務(wù)而言,LSO 的值等于事務(wù)中第一條消息的位置(firstUnstableOffset),對(duì)已完成的事務(wù)而言,它的值同 HW 相同
LW:Low Watermark 低水位, 代表 AR 集合中最小的 logStartOffset 值。
數(shù)據(jù)傳輸?shù)氖聞?wù)有幾種?
數(shù)據(jù)傳輸?shù)氖聞?wù)定義通常有以下三種級(jí)別:
(1)最多一次: 消息不會(huì)被重復(fù)發(fā)送,最多被傳輸一次,但也有可能一次不傳輸
(2)最少一次: 消息不會(huì)被漏發(fā)送,最少被傳輸一次,但也有可能被重復(fù)傳輸.
(3)精確的一次(Exactly once): 不會(huì)漏傳輸也不會(huì)重復(fù)傳輸,每個(gè)消息都傳輸被
Kafka 消費(fèi)者是否可以消費(fèi)指定分區(qū)消息?
Kafa consumer消費(fèi)消息時(shí),向broker發(fā)出fetch請(qǐng)求去消費(fèi)特定分區(qū)的消息,consumer指定消息在日志中的偏移量(offset),就可以消費(fèi)從這個(gè)位置開始的消息,customer擁有了offset的控制權(quán),可以向后回滾去重新消費(fèi)之前的消息,這是很有意義的。
Kafka消息是采用Pull模式,還是Push模式?
Kafka最初考慮的問題是,customer應(yīng)該從brokes拉取消息還是brokers將消息推送到consumer,也就是pull還push。在這方面,Kafka遵循了一種大部分消息系統(tǒng)共同的傳統(tǒng)的設(shè)計(jì):producer將消息推送到broker,consumer從broker拉取消息。
一些消息系統(tǒng)比如Scribe和Apache Flume采用了push模式,將消息推送到下游的consumer。這樣做有好處也有壞處:由broker決定消息推送的速率,對(duì)于不同消費(fèi)速率的consumer就不太好處理了。消息系統(tǒng)都致力于讓consumer以最大的速率最快速的消費(fèi)消息,但不幸的是,push模式下,當(dāng)broker推送的速率遠(yuǎn)大于consumer消費(fèi)的速率時(shí),consumer恐怕就要崩潰了。最終Kafka還是選取了傳統(tǒng)的pull模式。
Pull模式的另外一個(gè)好處是consumer可以自主決定是否批量的從broker拉取數(shù)據(jù)。Push模式必須在不知道下游consumer消費(fèi)能力和消費(fèi)策略的情況下決定是立即推送每條消息還是緩存之后批量推送。如果為了避免consumer崩潰而采用較低的推送速率,將可能導(dǎo)致一次只推送較少的消息而造成浪費(fèi)。Pull模式下,consumer就可以根據(jù)自己的消費(fèi)能力去決定這些策略。
Pull有個(gè)缺點(diǎn)是,如果broker沒有可供消費(fèi)的消息,將導(dǎo)致consumer不斷在循環(huán)中輪詢,直到新消息到t達(dá)。為了避免這點(diǎn),Kafka有個(gè)參數(shù)可以讓consumer阻塞知道新消息到達(dá)(當(dāng)然也可以阻塞知道消息的數(shù)量達(dá)到某個(gè)特定的量這樣就可以批量發(fā)
Kafka 高效文件存儲(chǔ)設(shè)計(jì)特點(diǎn)
Kafka把topic中一個(gè)parition大文件分成多個(gè)小文件段,通過多個(gè)小文件段,就容易定期清除或刪除已經(jīng)消費(fèi)完文件,減少磁盤占用。
通過索引信息可以快速定位message和確定response的最大大小。
通過index元數(shù)據(jù)全部映射到memory,可以避免segment file的IO磁盤操作。
通過索引文件稀疏存儲(chǔ),可以大幅降低index文件元數(shù)據(jù)占用空間大小
Kafka創(chuàng)建Topic時(shí)如何將分區(qū)放置到不同的Broker中
副本因子不能大于 Broker 的個(gè)數(shù);
第一個(gè)分區(qū)(編號(hào)為0)的第一個(gè)副本放置位置是隨機(jī)從 brokerList 選擇的;
其他分區(qū)的第一個(gè)副本放置位置相對(duì)于第0個(gè)分區(qū)依次往后移。也就是如果我們有5個(gè) Broker,5個(gè)分區(qū),假設(shè)第一個(gè)分區(qū)放在第四個(gè) Broker 上,那么第二個(gè)分區(qū)將會(huì)放在第五個(gè) Broker 上;第三個(gè)分區(qū)將會(huì)放在第一個(gè) Broker 上;第四個(gè)分區(qū)將會(huì)放在第二個(gè) Broker 上,依次類推;
剩余的副本相對(duì)于第一個(gè)副本放置位置其實(shí)是由 nextReplicaShift 決定的,而這個(gè)數(shù)也是隨機(jī)產(chǎn)生的
談一談 Kafka 的再均衡
在Kafka中,當(dāng)有新消費(fèi)者加入或者訂閱的topic數(shù)發(fā)生變化時(shí),會(huì)觸發(fā)Rebalance(再均衡:在同一個(gè)消費(fèi)者組當(dāng)中,分區(qū)的所有權(quán)從一個(gè)消費(fèi)者轉(zhuǎn)移到另外一個(gè)消費(fèi)者)機(jī)制,Rebalance顧名思義就是重新均衡消費(fèi)者消費(fèi)。Rebalance的過程如下:
第一步:所有成員都向coordinator發(fā)送請(qǐng)求,請(qǐng)求入組。一旦所有成員都發(fā)送了請(qǐng)求,coordinator會(huì)從中選擇一個(gè)consumer擔(dān)任leader的角色,并把組成員信息以及訂閱信息發(fā)給leader。
第二步:leader開始分配消費(fèi)方案,指明具體哪個(gè)consumer負(fù)責(zé)消費(fèi)哪些topic的哪些partition。一旦完成分配,leader會(huì)將這個(gè)方案發(fā)給coordinator。coordinator接收到分配方案之后會(huì)把方案發(fā)給各個(gè)consumer,這樣組內(nèi)的所有成員就都知道自己應(yīng)該消費(fèi)哪些分區(qū)了。
所以對(duì)于Rebalance來說,Coordinator起著至關(guān)重要的作用
Kafka 是如何實(shí)現(xiàn)高吞吐率的?
Kafka是分布式消息系統(tǒng),需要處理海量的消息,Kafka的設(shè)計(jì)是把所有的消息都寫入速度低容量大的硬盤,以此來換取更強(qiáng)的存儲(chǔ)能力,但實(shí)際上,使用硬盤并沒有帶來過多的性能損失。kafka主要使用了以下幾個(gè)方式實(shí)現(xiàn)了超高的吞吐率:
順序讀寫;
零拷貝
文件分段
批量發(fā)送
數(shù)據(jù)壓縮。
Kafka 缺點(diǎn)?
由于是批量發(fā)送,數(shù)據(jù)并非真正的實(shí)時(shí);
對(duì)于mqtt協(xié)議不支持;
不支持物聯(lián)網(wǎng)傳感數(shù)據(jù)直接接入;
僅支持統(tǒng)一分區(qū)內(nèi)消息有序,無法實(shí)現(xiàn)全局消息有序;
監(jiān)控不完善,需要安裝插件;
依賴zookeeper進(jìn)行元數(shù)據(jù)管理;
Kafka 新舊消費(fèi)者的區(qū)別
舊的 Kafka 消費(fèi)者 API 主要包括:SimpleConsumer(簡(jiǎn)單消費(fèi)者) 和 ZookeeperConsumerConnectir(高級(jí)消費(fèi)者)。SimpleConsumer 名字看起來是簡(jiǎn)單消費(fèi)者,但是其實(shí)用起來很不簡(jiǎn)單,可以使用它從特定的分區(qū)和偏移量開始讀取消息。高級(jí)消費(fèi)者和現(xiàn)在新的消費(fèi)者有點(diǎn)像,有消費(fèi)者群組,有分區(qū)再均衡,不過它使用 ZK 來管理消費(fèi)者群組,并不具備偏移量和再均衡的可操控性。
現(xiàn)在的消費(fèi)者同時(shí)支持以上兩種行為,所以為啥還用舊消費(fèi)者 API 呢?
Kafka 分區(qū)數(shù)可以增加或減少嗎?為什么?
我們可以使用 bin/kafka-topics.sh 命令對(duì) Kafka 增加 Kafka 的分區(qū)數(shù)據(jù),但是 Kafka 不支持減少分區(qū)數(shù)。
Kafka 分區(qū)數(shù)據(jù)不支持減少是由很多原因的,比如減少的分區(qū)其數(shù)據(jù)放到哪里去?是刪除,還是保留?刪除的話,那么這些沒消費(fèi)的消息不就丟了。如果保留這些消息如何放到其他分區(qū)里面?追加到其他分區(qū)后面的話那么就破壞了 Kafka 單個(gè)分區(qū)的有序性。如果要保證刪除分區(qū)數(shù)據(jù)插入到其他分區(qū)保證有序性,那么實(shí)現(xiàn)起來邏輯就會(huì)非常復(fù)雜。