https://zhuanlan.zhihu.com/p/76073581
1. 什么是 Kafka?
答:Kafka是一個發(fā)布 - 訂閱的消息隊(duì)列中間件灵寺。這個消息傳遞應(yīng)用程序是用“scala”編碼的曼库。 kafka 支持的協(xié)議是防AMQP協(xié)議,支持集群略板,負(fù)載均衡和動態(tài)擴(kuò)容(zk), 不支持事務(wù)毁枯;
它有這么三個比較關(guān)鍵的能力:
發(fā)布訂閱,可以當(dāng)做消息隊(duì)列用
記錄的容錯持久化
流處理
優(yōu)點(diǎn)是: 高吞吐叮称,低延時种玛,可擴(kuò)展
2. 使用消息隊(duì)列的好處
- 解耦
允許獨(dú)立的修改或者擴(kuò)展兩邊的處理過程,只要確保其遵循同樣的約束接口瓤檐。
- 可恢復(fù)性
系統(tǒng)的一部分組件失效時赂韵,不會影響整個系統(tǒng)。即使部分處理消息的線程掛掉挠蛉,消息加入隊(duì)列祭示,也能在系統(tǒng)恢復(fù)后被處理。
- 緩沖
用于解決生產(chǎn)者和消費(fèi)者速度不一致的情況谴古。
- 靈活性和峰值處理
在流量激增的情況下不會導(dǎo)致系統(tǒng)奔潰
- 異步處理
用戶收到消息不想立即處理质涛,需要的時候再進(jìn)行處理。
3. 消費(fèi)隊(duì)列模式
- 點(diǎn)對點(diǎn)
只有一個消費(fèi)者 flume
- 發(fā)布訂閱
只要不刪消息都在
隊(duì)列主動推送:缺點(diǎn)推送的速度統(tǒng)一掰担,但是每一個訂閱者的處理速度不一
消費(fèi)者主動拉取的模式:缺點(diǎn)需要消費(fèi)者進(jìn)行長輪詢看有沒有新消息汇陆,浪費(fèi)資源
kafka 是主動拉取模式,消費(fèi)者的消費(fèi)速度可以由自己決
被動拉取的模式恩敌, 維護(hù)一個用戶列表瞬测,消息來到,通知消費(fèi)者,消費(fèi)隊(duì)列的兩端是可以不同時在線月趟,但是被動通知還需實(shí)時監(jiān)測消費(fèi)者是否在線
4. Kafka中有哪幾個組件?
主題:Kafka主題是一堆或一組消息灯蝴。
生產(chǎn)者:在Kafka,生產(chǎn)者發(fā)布通信以及向Kafka主題發(fā)布消息孝宗。
消費(fèi)者:Kafka消費(fèi)者訂閱了一個主題穷躁,并且還從主題中讀取和處理消息。
經(jīng)紀(jì)人:在管理主題中的消息存儲時因妇,我們使用Kafka Brokers问潭。
zookeeper :
5. 不同組件在kafka中的作用
zookeeper 幫助kafka 維護(hù)集群 ,存儲 topic 信息婚被, topic 分區(qū)的 leader ,follow 位置 等信息狡忙。消費(fèi)者會在zookeeper中存儲消費(fèi)的偏移量。0.9 之前址芯。0.9后將偏移量保存在kafka集群topic,存在磁盤灾茁。默認(rèn)存7天。
topic 主題會存在 分區(qū) 和 副本數(shù)谷炸, 分區(qū)存在 leader 和 follower
分區(qū)的好處北专,提高讀寫的并行度,提高負(fù)載旬陡。 副本的作用拓颓,用于容災(zāi)處理
- 同一個消費(fèi)者組里的消費(fèi)者同一時刻不能消費(fèi)同一個topic的同一個分區(qū)。
消費(fèi)者組描孟,提高消費(fèi)數(shù)據(jù)的能力驶睦。消費(fèi)者組里的消費(fèi)者個數(shù)和分區(qū)一致是最好。消費(fèi)者數(shù)不要超過分區(qū)數(shù)画拾。
消費(fèi)者組分配的策略問題啥繁。
- 生產(chǎn)者將數(shù)據(jù)交付分區(qū),存在策略問題青抛。
kafka中的副本數(shù)不能超過 可用broker,分區(qū)數(shù)可以超過酬核。
6. Kafka 為什么那么快蜜另?
- 頁緩存
Kafka并不太依賴JVM內(nèi)存大小,而是主要利用Page Cache嫡意,如果使用應(yīng)用層緩存(JVM堆內(nèi)存)举瑰,會增加GC負(fù)擔(dān),增加停頓時間和延遲蔬螟,創(chuàng)建對象的開銷也會比較高此迅。
讀取操作可以直接在Page Cache上進(jìn)行,如果消費(fèi)和生產(chǎn)速度相當(dāng),甚至不需要通過物理磁盤直接交換數(shù)據(jù)耸序,這是Kafka高吞吐量的一個重要原因忍些。
這么做還有一個優(yōu)勢,如果Kafka重啟坎怪,JVM內(nèi)的Cache會失效罢坝,Page Cache依然可用。
- 零拷貝
Kafka中存在大量的網(wǎng)絡(luò)數(shù)據(jù)持久化到磁盤(Producer到Broker)和磁盤文件通過網(wǎng)絡(luò)發(fā)送(Broker到Consumer)的過程搅窿。這一過程的性能直接影響Kafka的整體吞吐量嘁酿。
傳統(tǒng)四次拷貝:首先通過系統(tǒng)調(diào)用將文件數(shù)據(jù)讀入到內(nèi)核態(tài)Buffer(DMA拷貝),然后應(yīng)用程序?qū)?nèi)存態(tài)Buffer數(shù)據(jù)讀入到用戶態(tài)Buffer(CPU拷貝)男应,接著用戶程序通過Socket發(fā)送數(shù)據(jù)時將用戶態(tài)Buffer數(shù)據(jù)拷貝到內(nèi)核態(tài)Buffer(CPU拷貝)闹司,最后通過DMA拷貝將數(shù)據(jù)拷貝到NIC Buffer。伴隨四次切換沐飘。
sendfile和transferTo實(shí)現(xiàn)零拷貝
Linux 2.4+內(nèi)核通過sendfile系統(tǒng)調(diào)用开仰,提供了零拷貝。數(shù)據(jù)通過DMA拷貝到內(nèi)核態(tài)Buffer后薪铜,直接通過DMA拷貝到NIC Buffer众弓,無需CPU拷貝。這也是零拷貝這一說法的來源隔箍。除了減少數(shù)據(jù)拷貝外谓娃,因?yàn)檎麄€讀文件-網(wǎng)絡(luò)發(fā)送由一個sendfile調(diào)用完成,整個過程只有兩次上下文切換蜒滩,因此大大提高了性能滨达。
Java NIO的FileChannel的transferTo和transferFrom方法實(shí)現(xiàn)零拷貝。
- 磁盤的順序?qū)懭?/li>
即使是普通的機(jī)械磁盤俯艰,順序訪問速率也接近了內(nèi)存的隨機(jī)訪問速率捡遍。
Kafka的每條消息都是append的,不會從中間寫入和刪除消息竹握,保證了磁盤的順序訪問画株。
即使是順序讀寫,過于頻繁的大量小IO操作一樣會造成磁盤的瓶頸啦辐,此時又變成了隨機(jī)讀寫谓传。Kafka的策略是把消息集合在一起,批量發(fā)送芹关,盡可能減少對磁盤的訪問续挟。所以,Kafka的Topic和Partition數(shù)量不宜過多侥衬。
超過64個Topic/Partition以后诗祸,Kafka性能會急劇下降跑芳。
RocketMQ存儲模型與Kafka有些差異,RocketMQ會把所有的數(shù)據(jù)存放在相同的日志文件直颅,所以單機(jī)可以支持非常多的隊(duì)列博个。
- 全異步
Kafka基本上是沒有阻塞操作的,調(diào)用發(fā)送方法會立即返回际乘,等待buffer滿了以后交給輪詢線程坡倔,發(fā)送和接收消息,復(fù)制數(shù)據(jù)也是都是通過NetworkClient封裝的poll方式脖含。
- 批量操作
結(jié)合磁盤順序?qū)懭胱锼繜o疑是非常有必要(如果用的時候每發(fā)送一條消息都調(diào)用future.get等待,性能至少下降2個數(shù)量級)养葵。寫入的時候放到RecordAccumulator進(jìn)行聚合征堪,批量壓縮,還有批量刷盤等...
- reactor 網(wǎng)絡(luò)模型
Kafka 的網(wǎng)絡(luò)層使用 reactor 的線程模型关拒,單個 acceptor 線程負(fù)責(zé)處理所有客戶端的連接佃蚜,建立連接后將 socket 的輪詢分發(fā)給多個 processor 線程處理讀寫請求,processor 只負(fù)責(zé)數(shù)據(jù)的接收和發(fā)送着绊,其后還有多個 handler 線程進(jìn)行具體的邏輯操作谐算,通過這樣的異步線程模型,kafka 能夠與成千上萬的客戶端交互而毫無壓力
7. kafka 的工作流程
1 寫入方式
producer采用推(push)模式將消息發(fā)布到broker归露,每條消息都被追加(append)到分區(qū)(patition)中洲脂,屬于順序?qū)懘疟P(順序?qū)懘疟P效率比隨機(jī)寫內(nèi)存要高,保障kafka吞吐率)剧包。
2 分區(qū)(Partition)
Kafka集群有多個消息代理服務(wù)器(broker-server)組成恐锦,發(fā)布到Kafka集群的每條消息都有一個類別,用主題(topic)來表示疆液。
- 偏移量
集群為每個主題維護(hù)了分布式的分區(qū)(partition)日志文件一铅,物理意義上可以把主題(topic)看作進(jìn)行了分區(qū)的日志文件(partition log)。主題的每個分區(qū)都是一個有序的堕油、不可變的記錄序列潘飘,新的消息會不斷追加到日志中。分區(qū)中的每條消息都會按照時間順序分配到一個單調(diào)遞增的順序編號馍迄,叫做偏移量(offset)福也,這個偏移量能夠唯一地定位當(dāng)前分區(qū)中的每一條消息。
每個Partition中的消息都是有序的攀圈,生產(chǎn)的消息被不斷追加到Partition log上,其中的每一個消息都被賦予了一個唯一的offset值峦甩。
消費(fèi)者 offset 是按照 組 + 分區(qū) + topic 來進(jìn)行維護(hù)
發(fā)布到Kafka主題的每條消息包括鍵值和時間戳赘来。消息到達(dá)服務(wù)器端的指定分區(qū)后现喳,都會分配到一個自增的偏移量。原始的消息內(nèi)容和分配的偏移量以及其他一些元數(shù)據(jù)信息最后都會存儲到分區(qū)日志文件中犬辰。
- 寫入流程
1)producer先從zookeeper的 “/brokers/…/state”節(jié)點(diǎn)找到該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
存儲策略
無論消息是否被消費(fèi)灸促,kafka都會保留所有消息。有兩種策略可以刪除舊數(shù)據(jù):
1)基于時間:log.retention.hours=168
2)基于大泻选:log.retention.bytes=1073741824消費(fèi)策略
Kafka采用拉取模型浴栽,由消費(fèi)者自己記錄消費(fèi)狀態(tài),每個消費(fèi)者互相獨(dú)立地順序讀取每個分區(qū)的消息轿偎。如下圖所示典鸡,有兩個消費(fèi)者(不同消費(fèi)者組)拉取同一個主題的消息,消費(fèi)者A的消費(fèi)進(jìn)度是3坏晦,消費(fèi)者B的消費(fèi)進(jìn)度是6萝玷。消費(fèi)者拉取的最大上限通過最高水位(watermark)控制,生產(chǎn)者最新寫入的消息如果還沒有達(dá)到備份數(shù)量昆婿,對消費(fèi)者是不可見的球碉。這種由消費(fèi)者控制偏移量的優(yōu)點(diǎn)是:消費(fèi)者可以按照任意的順序消費(fèi)消息。比如仓蛆,消費(fèi)者可以重置到舊的偏移量睁冬,重新處理之前已經(jīng)消費(fèi)過的消息;或者直接跳到最近的位置多律,從當(dāng)前的時刻開始消費(fèi)痴突。
8. 生產(chǎn)者策略?
分區(qū):默認(rèn)是 RR 的輪詢分區(qū)劃分規(guī)則, 若指定了Key 則將key的hash值 % 分區(qū)號進(jìn)行分區(qū)
kafka數(shù)據(jù)的可靠性: 分區(qū)必須確認(rèn)收到狼荞,同時副本備份成功辽装。 ack
半數(shù)以上follower完成備份 發(fā)送 ACK, 問題是選舉新的leader ,容忍 n 臺故障,需要 2n + 1 個副本
全部完成相味, 問題是延遲長拾积, Kafka 選擇這種,但是問題是 存在一個慢 丰涉,或者掛掉拓巧,
- ISR 代表同步副本,leader 從 ISR 中選新 leader, 通信時間 一死,在延遲時間內(nèi)去掉
kafka 中維護(hù) ISR 的隊(duì)列
當(dāng)leader 接受到消息后肛度,通知 ISR 中的follow 完成備份
- acks 0 收到, 1 leader 完成 -1 leader,follower所有follow完成投慈,(重復(fù)數(shù)據(jù))
產(chǎn)生同步數(shù)據(jù) 承耿,follower 備份完成后冠骄, 這是leader 掛掉, producer 任務(wù)沒收到加袋,向follewer備份選舉后的重復(fù)發(fā)送數(shù)據(jù)
一致性: follower還沒同步完成凛辣,同步一半 leader 掛了,選舉后作為leader 后原leader 活了职烧,導(dǎo)致數(shù)據(jù)不一致
消費(fèi)數(shù)據(jù)一致性:Leo: 每一個分區(qū)副本的最大 offset 扁誓,設(shè)置一個 HW 指的是高水位,所有分區(qū)leo的最小位置,HW之前的數(shù)據(jù)才對消費(fèi)者可見
存儲數(shù)據(jù)一致性: 重新選leader 給所有分區(qū)發(fā)生消息蚀之,直接截取數(shù)據(jù)到HW.
- exactly-once : ack 為0 at-less-most
冪等性 + 至少一次 為精準(zhǔn)一次
使用冪等性蝗敢,在kafka 的 broker 消除數(shù)據(jù)的重復(fù), kafka使用冪等性恬总,默認(rèn) ack 為-1
首先給每一個生產(chǎn)者 添加一個 id , 給每一個消息 添加一個序列號前普, 如果同一個 生產(chǎn)者, 同一個消息序列號壹堰, 發(fā)往同一個分區(qū)拭卿,如果已經(jīng)接受過,就進(jìn)行去重贱纠。
但是生產(chǎn)者掛了重啟峻厚,那么它的id 號也就變了,也就不能保證精準(zhǔn) 一致性
9. 消費(fèi)者策略?
- 分區(qū) 谆焊, RR 輪詢惠桃,將當(dāng)前消費(fèi)者組不同的主題,當(dāng)做一個整體辖试,經(jīng)輪詢辜王。好處,消費(fèi)者組里面的消費(fèi)最多差一個罐孝。
保證消費(fèi)者組里面消費(fèi)的topic 是一樣的呐馆。 Range 是按照單個主題進(jìn)行劃分,將不同的topic 不當(dāng)做一個整體進(jìn)行考慮莲兢。
觸發(fā)時在消費(fèi)者組里面消費(fèi)者個數(shù)變化時會觸發(fā)分區(qū)汹来,重新設(shè)置分配分配策略酷鸦。
Range 分區(qū)不會把主題看做一個整體進(jìn)行劃分
假設(shè) 有兩個主題式廷, T1(0,1,2), T2(0,1,2), 兩個消費(fèi)者組 (A伍派,B) (C)
A 消費(fèi)者 訂閱 T1 , B 訂閱 T1程癌, T2 ,C 訂閱了 T1
RR : 如果采用的RR 發(fā)現(xiàn) A,B 消費(fèi)者共用同一個組笑诅, 則會把 A,B 訂閱的topic 當(dāng)做一個整體進(jìn)行考慮愕秫。
A,B 進(jìn)行輪詢的分區(qū)有: T1 0 T1 1 T1 2 T2 0 T2 1 T2 3
Range : 按主題劃分好芭,先考慮誰訂閱了這個主題承疲,然后再進(jìn)行劃分
- offset
消費(fèi)者組 + 主題 + 分區(qū) 決定 offset, 消費(fèi)者連接
Kafka 可以順序?qū)懘疟P酣溃, 零拷貝技術(shù)
9 是什么確保了Kafka中服務(wù)器的負(fù)載平衡瘦穆?
答:使用消費(fèi)者策略和生產(chǎn)者策略保證負(fù)載均衡
10. 副本和ISR扮演什么角色纪隙?
答:基本上赊豌,復(fù)制日志的節(jié)點(diǎn)列表就是副本。特別是對于特定的分區(qū)绵咱。但是碘饼,無論他們是否扮演領(lǐng)導(dǎo)者的角色,他們都是如此悲伶。
此外艾恼,ISR指的是同步副本。在定義ISR時麸锉,它是一組與領(lǐng)導(dǎo)者同步的消息副本钠绍。
11. 有哪些情形會造成重復(fù)消費(fèi)?
消費(fèi)者消費(fèi)后沒有commit offset(程序崩潰/強(qiáng)行kill/消費(fèi)耗時/自動提交偏移情況下unscrible)
https://www.cnblogs.com/wangzhuxing/p/10124308.html
(1)生產(chǎn)者發(fā)送重復(fù)解決方案
1花沉、啟動kafka的冪等性
要啟動kafka的冪等性柳爽,無需修改代碼,默認(rèn)為關(guān)閉碱屁,需要修改配置文件:enable.idempotence=true 同時要求 ack=all 且 retries>1磷脯。
冪等原理:每個producer有一個producer id,服務(wù)端會通過這個id關(guān)聯(lián)記錄每個producer的狀態(tài)娩脾,每個producer的每條消息會帶上一個遞增的sequence赵誓,服務(wù)端會記錄每個producer對應(yīng)的當(dāng)前最大sequence,producerId + sequence 柿赊,如果新的消息帶上的sequence不大于當(dāng)前的最大sequence就拒絕這條消息俩功,如果消息落盤會同時更新最大sequence,這個時候重發(fā)的消息會被服務(wù)端拒掉從而避免消息重復(fù)碰声。該配置同樣應(yīng)用于kafka事務(wù)中诡蜓。
2、ack=0奥邮,不重試万牺。
可能會丟消息,適用于吞吐量指標(biāo)重要性高于數(shù)據(jù)丟失洽腺,例如:日志收集脚粟。
(2)消費(fèi)者重復(fù)消費(fèi)解決方案
1、取消自動自動提交
每次消費(fèi)完或者程序退出時手動提交蘸朋。這可能也沒法保證一條重復(fù)核无。
2、下游做冪等
一般的解決方案是讓下游做冪等或者盡量每消費(fèi)一條消息都記錄offset藕坯,對于少數(shù)嚴(yán)格的場景可能需要把offset或唯一ID,例如訂單ID和下游狀態(tài)更新放在同一個數(shù)據(jù)庫里面做事務(wù)來保證精確的一次更新或者在下游數(shù)據(jù)表里面同時記錄消費(fèi)offset团南,然后更新下游數(shù)據(jù)的時候用消費(fèi)位點(diǎn)做樂觀鎖拒絕掉舊位點(diǎn)的數(shù)據(jù)更新噪沙。
flink 使用 upset 來保證數(shù)據(jù)的冪等性,每一個數(shù)據(jù)都有一個唯一的id, 不存在插入吐根,存在更新
https://www.cnblogs.com/bigshark/p/11210876.html
https://www.cnblogs.com/kevingrace/p/9443270.html
https://blog.csdn.net/CoderBoom/article/details/84845197
12. follower 故障 和 leader 故障的情況下可靠性保證正歼?
- follower故障會被踢出ISR,待follower恢復(fù)后,follower會讀取本地磁盤記錄的上次HW, 并將log高于HW的截去拷橘,從HW開始向leader同步局义,等待follower的LEO大于partition的HW,可以重新加入ISR
- leader 故障,會從ISR中選出新的leader,為保證多副本間數(shù)據(jù)的一致性冗疮,其余的follower將log高于HW部分截去萄唇,從新的leader開始進(jìn)行同步;
13. exactly once 語義
at least once + 冪等性 = exactly once
12. 在生產(chǎn)者中术幔,何時發(fā)生QueueFullException另萤?
答:每當(dāng)Kafka生產(chǎn)者試圖以代理的身份在當(dāng)時無法處理的速度發(fā)送消息時,通常都會發(fā)生QueueFullException诅挑。但是四敞,為了協(xié)作處理增加的負(fù)載,用戶需要添加足夠的代理揍障,因?yàn)樯a(chǎn)者不會阻止目养。
15. 在Kafka集群中保留期的目的是什么?
答:保留期限保留了Kafka群集中的所有已發(fā)布記錄毒嫡。它不會檢查它們是否已被消耗癌蚁。此外,可以通過使用保留期的配置設(shè)置來丟棄記錄兜畸。而且努释,它可以釋放一些空間。
16. 解釋Kafka可以接收的消息最大為多少咬摇?
答:Kafka可以接收的最大消息大小約為1000000字節(jié)伐蒂。
問題24:傳統(tǒng)的消息傳遞方法有哪些類型?
答:基本上肛鹏,傳統(tǒng)的消息傳遞方法有兩種逸邦,如:
排隊(duì):這是一種消費(fèi)者池可以從服務(wù)器讀取消息并且每條消息轉(zhuǎn)到其中一個消息的方法。
發(fā)布-訂閱:在發(fā)布-訂閱中在扰,消息被廣播給所有消費(fèi)者缕减。
17. ISR在Kafka環(huán)境中代表什么?
答:ISR指的是同步副本芒珠。這些通常被分類為一組消息副本桥狡,它們被同步為領(lǐng)導(dǎo)者。
18. 什么是Kafka中的地域復(fù)制?
答:對于我們的集群裹芝,Kafka MirrorMaker提供地理復(fù)制部逮。基本上嫂易,消息是通過MirrorMaker跨多個數(shù)據(jù)中心或云區(qū)域復(fù)制的兄朋。因此,它可以在主動/被動場景中用于備份和恢復(fù)炬搭;也可以將數(shù)據(jù)放在離用戶更近的位置蜈漓,或者支持?jǐn)?shù)據(jù)位置要求。
19. 解釋多租戶是什么宫盔?
答:我們可以輕松地將Kafka部署為多租戶解決方案。但是享完,通過配置主題可以生成或使用數(shù)據(jù)灼芭,可以啟用多租戶。此外般又,它還為配額提供操作支持彼绷。
20. Kafka中的數(shù)據(jù)日志是什么?
答:我們知道茴迁,在Kafka中寄悯,消息會保留相當(dāng)長的時間。此外堕义,消費(fèi)者還可以根據(jù)自己的方便進(jìn)行閱讀猜旬。盡管如此,有一種可能的情況是倦卖,如果將Kafka配置為將消息保留24小時洒擦,并且消費(fèi)者可能停機(jī)超過24小時,則消費(fèi)者可能會丟失這些消息怕膛。但是熟嫩,我們?nèi)匀豢梢詮纳洗我阎钠浦凶x取這些消息,但僅限于消費(fèi)者的部分停機(jī)時間僅為60分鐘的情況褐捻。此外掸茅,關(guān)于消費(fèi)者從一個話題中讀到什么,Kafka不會保持狀態(tài)柠逞。
21. Apache Kafka的缺陷
答:Kafka的局限性是:
沒有完整的監(jiān)控工具集
消息調(diào)整的問題
不支持通配符主題選擇
速度問題
22. 什么是kafka 消費(fèi)者重平衡昧狮?會造成什么影響?
重平衡本質(zhì)上是一種協(xié)議边苹,規(guī)定了 消費(fèi)者組下的所有消費(fèi)者陵且,按照什么策略消費(fèi) Topic
就是 給消費(fèi)組 中的每一個消費(fèi)者分配消費(fèi) 任務(wù)的過程。
重平衡的發(fā)生在啟動一個消費(fèi)者組前,但是在某些情況下慕购,會正在運(yùn)行消費(fèi)的時聊疲,再次發(fā)生,可能會導(dǎo)致整個集群的暫時性的癱瘓沪悲,影響kafka的高可用获洲。
23. 消費(fèi)者重平衡的發(fā)生時機(jī)?
訂閱主題數(shù)發(fā)生變化殿如,這種一般發(fā)生在業(yè)務(wù)改變贡珊,數(shù)據(jù)一定變化
主題的分區(qū)發(fā)生變化, 啟動集群前設(shè)置分區(qū)數(shù)涉馁, 之后調(diào)節(jié)门岔,也是人為調(diào)節(jié),可以在半夜
消費(fèi)端消費(fèi)組成員的變化烤送, 這個原因產(chǎn)生較大影響寒随,消費(fèi)者處理消息超時,Kafka集群配置的 max.poll.interval.ms 的值帮坚,那么該消費(fèi)者將會自動離組. 心跳超時妻往,如果消費(fèi)者在指定的session.timeout.ms時間內(nèi)沒有匯報心跳,
那么Kafka就會認(rèn)為該消費(fèi)已經(jīng)dead了
24. Kafka 的 副本備份策略是什么试和?
kafka 采用的是同步和異步共同優(yōu)點(diǎn)的備份策略讯泣,即將leader 的所有 follower 進(jìn)行同步完畢才返回,ack. 只不過這個全部的副本是指的是 在 ISR 隊(duì)列中的副本阅悍。
ISR 隊(duì)列好渠,是指 follower 副本存活且和 zookeeper 保持連接,同時其響應(yīng)時間 較快溉箕。不滿足條件的會被踢出去晦墙,滿足的會被加入。
HW 高水位肴茄,表明 所有副本都同步到的 offset 晌畅,所有分區(qū)的最小offset ,那么 leader 也向 消費(fèi)者提供的 HW.
LEO 每一個分區(qū)上的最新(大) offset
kafka采取同步和異步的共同優(yōu)點(diǎn),所以使用ISR的方法寡痰。把Follow中同步慢的節(jié)點(diǎn)從ISR中進(jìn)行T除抗楔,從而保證了復(fù)制數(shù)據(jù)的速度。如果leader副本宕機(jī)拦坠,那么從ISR中選舉出來新的leader副本连躏。因?yàn)閒ollow副本中都有記錄HW。這樣也會減少數(shù)據(jù)的丟失贞滨。Follow副本能夠從leader中批量的讀取數(shù)據(jù)并批量寫入入热,從而減少了I/0的開銷拍棕。
25. kafka 處理請求方案?
kafka 處理請求 類似于 Reactor 模式勺良。
網(wǎng)絡(luò)線程負(fù)責(zé)接受 請求绰播, 然后將請求放入共享的請求隊(duì)列中。
broker 有個 IO線程池尚困, 負(fù)責(zé)從共享隊(duì)列中取出請求蠢箩, 執(zhí)行真正的處理, 如果是 produce ,將消息寫入底層磁盤的日志中事甜, 如果是 fetch 谬泌,則從磁盤讀取消息。
當(dāng) IO線程 處理完請求逻谦,將生成的響應(yīng) 發(fā)送到 網(wǎng)絡(luò) 線程池的響應(yīng)隊(duì)列中
請求隊(duì)列是所有網(wǎng)絡(luò)線程共享的掌实,而響應(yīng)隊(duì)列是每個網(wǎng)絡(luò)線程專屬的
26. kafka controller 的作用?什么是腦裂怎么解決跨跨?
早期的版本并沒有采用 kafka Controller 對分區(qū)和副本進(jìn)行管理潮峦,而是依賴于 zookeeper, 每一個 broker 都會在 zookeeper 上為分區(qū)和副本注冊大量的監(jiān)聽器勇婴。這種嚴(yán)重依賴于zookeeper 會有腦裂和 羊群效應(yīng)。
只有kafka 的 controller 監(jiān)控 zookeeper , 其他的 node 再和 controller 通信嘱腥,減少 zookeeper的 壓力耕渴。
什么是腦裂?
kafka中只有一個控制器controller 負(fù)責(zé)分區(qū)的leader選舉齿兔,同步broker的新增或刪除消息橱脸,但有時由于網(wǎng)絡(luò)問題,可能同時有兩個broker認(rèn)為自己是controller分苇,這時候其他的broker就會發(fā)生腦裂添诉,不知道該聽從誰的。
如何解決医寿?controller epoch
每當(dāng)新的controller產(chǎn)生的時候就會在zk中生成一個全新的栏赴、數(shù)值更大的controller epoch的標(biāo)識,并同步給其他的broker進(jìn)行保存靖秩,這樣當(dāng)?shù)诙€controller發(fā)送指令時须眷,其他的broker就會自動忽略。
27. kafka controller 的競選策略沟突?
在任意時刻花颗,集群中有且僅有一個控制器。
每個broker啟動的時候會去嘗試去讀取zookeeper 中/controller節(jié)點(diǎn)的brokerid的值惠拭,如果讀取到brokerid的值不為-1扩劝,則表示已經(jīng)有其它broker節(jié)點(diǎn)成功競選為控制器,所以當(dāng)前broker就會放棄競選;如果Zookeeper中不存在/controller這個節(jié)點(diǎn)棒呛,或者這個節(jié)點(diǎn)中的數(shù)據(jù)異常聂示,那么就會嘗試去創(chuàng)建/controller這個節(jié)點(diǎn),當(dāng)前broker去創(chuàng)建節(jié)點(diǎn)的時候条霜,也有可能其他broker同時去嘗試創(chuàng)建這個節(jié)點(diǎn)催什,只有創(chuàng)建成功的那個broker才會成為控制器,而創(chuàng)建失敗的broker則表示競選失敗宰睡。每個broker都會在內(nèi)存中保存當(dāng)前控制器的brokerid值蒲凶,這個值可以標(biāo)識為activeControllerId。
28. 生產(chǎn)者冪等性和事務(wù)是什么拆内?
目的: 進(jìn)行retry重試時旋圆,只會生成一個消息。
為了實(shí)現(xiàn)Producer的冪等性麸恍,Kafka引入了Producer ID(即PID)和Sequence Number灵巧。
PID。每個新的Producer在初始化的時候會被分配一個唯一的PID抹沪,這個PID對用戶是不可見的刻肄。
Sequence Numbler。(對于每個PID融欧,該P(yáng)roducer發(fā)送數(shù)據(jù)的每個<Topic, Partition>都對應(yīng)一個從0開始單調(diào)遞增的Sequence Number敏弃。不是offset
實(shí)現(xiàn)原理: broker 在緩存中保存 序列號, 對于接受的每一條消息噪馏,如果序列號 比 緩存中的大 1 則接受麦到,否則丟棄。但是者只能保證單個生產(chǎn)者對分區(qū)的 exactly once 語義欠肾。
瓶颠,kafka事務(wù)屬性是指一系列的生產(chǎn)者生產(chǎn)消息和消費(fèi)者提交偏移量的操作在一個事務(wù),或者說是是一個原子操作)刺桃,同時成功或者失敗粹淋。
在事務(wù)屬性之前先引入了生產(chǎn)者冪等性,它的作用為:
生產(chǎn)者多次發(fā)送消息可以封裝成一個原子操作虏肾,要么都成功廓啊,要么失敗
consumer-transform-producer模式下,因?yàn)橄M(fèi)者提交偏移量出現(xiàn)問題封豪,導(dǎo)致在重復(fù)消費(fèi)消息時谴轮,生產(chǎn)者重復(fù)生產(chǎn)消息。需要將這個模式下消費(fèi)者提交偏移量操作和生成者一系列生成消息的操作封裝成一個原子操作吹埠。
事務(wù)屬性實(shí)現(xiàn)前提是冪等性第步,即在配置事務(wù)屬性transaction id時疮装,必須還得配置冪等性;但是冪等性是可以獨(dú)立使用的粘都,不需要依賴事務(wù)屬性廓推。
29. 什么是kafka 消費(fèi)者組?
消費(fèi)者組是 kafka 提供的可以擴(kuò)展且具有容錯性的消費(fèi)者機(jī)制翩隧。 一個分區(qū)樊展,只能被消費(fèi)者組中的一個消費(fèi)者進(jìn)行消費(fèi)。
當(dāng)消費(fèi)者數(shù)量多于分區(qū)數(shù)量時堆生,多于的消費(fèi)者空閑专缠。
當(dāng)消費(fèi)者數(shù)量少于分區(qū)數(shù)量時,一個消費(fèi)者可能訂閱多個分區(qū)淑仆。
發(fā)揮 consumer 最大的效果就是涝婉,consumer 數(shù)和topic 下的 partitions 數(shù)相等。
30. Kafka中是怎么體現(xiàn)消息順序性的蔗怠?
kafka每個partition中的消息在寫入時都是有序的墩弯,消費(fèi)時,每個partition只能被每一個group中的一個消費(fèi)者消費(fèi)寞射,保證了消費(fèi)時也是有序的渔工。
整個topic不保證有序。如果為了保證topic整個有序桥温,那么將partition調(diào)整為1.
31. Kafka生產(chǎn)者客戶端中使用了幾個線程來處理涨缚?分別是什么?
2個策治,主線程和Sender線程。主線程負(fù)責(zé)創(chuàng)建消息兰吟,然后通過分區(qū)器通惫、序列化器、攔截器作用之后緩存到累加器RecordAccumulator中混蔼。Sender線程負(fù)責(zé)將RecordAccumulator中消息發(fā)送到kafka中.
32. 消費(fèi)者提交消費(fèi)位移時提交的是當(dāng)前消費(fèi)到的最新消息的offset還是offset+1?
offset+1
34. 有哪些情形會造成重復(fù)消費(fèi)履腋?
消費(fèi)者消費(fèi)后沒有commit offset(程序崩潰/強(qiáng)行kill/消費(fèi)耗時/自動提交偏移情況下unscrible)
35. KafkaConsumer是非線程安全的,那么怎么樣實(shí)現(xiàn)多線程消費(fèi)惭嚣?
1.在每個線程中新建一個KafkaConsumer
2.單線程創(chuàng)建KafkaConsumer遵湖,多個處理線程處理消息(難點(diǎn)在于是否要考慮消息順序性,offset的提交方式)
39. Kafka 如何保證數(shù)據(jù)的順序性晚吞?
kafka:一個topic延旧,一個partition,一個consumer槽地,內(nèi)部多線程.
kafka寫到一個partition中的數(shù)據(jù)一定是有數(shù)據(jù)的迁沫。
解決辦法: 一個topic芦瘾,一個partition,一個consumer集畅,內(nèi)部單線程消費(fèi)近弟,寫N個內(nèi)存queue,然后N個線程分別消費(fèi)一個內(nèi)存queue即可挺智,既消費(fèi)者不要使用多線程進(jìn)行處理祷愉。或者你想多線程進(jìn)行處理赦颇,你可以建立一個內(nèi)存隊(duì)列二鳄,通過hash進(jìn)任務(wù)id相同分到一個內(nèi)存隊(duì)列,每一個內(nèi)存隊(duì)列對應(yīng)一個線程沐扳。
40. 常見MQ 的區(qū)別泥从?
ActiveMQ :最早大家都用ActiveMQ,但是現(xiàn)在確實(shí)大家用的不多了沪摄,沒經(jīng)過大規(guī)模吞吐量場景的驗(yàn)證躯嫉,社區(qū)也不是很活躍,單機(jī)吞吐量杨拐,萬級祈餐,吞吐量比RocketMQ和Kafka要低了一個數(shù)量級,響應(yīng)為ms級別哄陶,有較低的概率丟失數(shù)據(jù)帆阳。
RabbitMQ :單機(jī)吞吐率萬級,吞吐量比RocketMQ和Kafka要低了一個數(shù)量級屋吨,但是適合于中小型企業(yè)蜒谤,因?yàn)樽詭Я擞押玫谋O(jiān)控和維護(hù)界面,社區(qū)相對比較活躍至扰,幾乎每個月都發(fā)布幾個版本分鳍徽,在國內(nèi)一些互聯(lián)網(wǎng)公司近幾年用rabbitmq也比較多一些,但是問題也是顯而易見的敢课,RabbitMQ確實(shí)吞吐量會低一些阶祭,這是因?yàn)樗龅膶?shí)現(xiàn)機(jī)制比較重,同時語言在國內(nèi)很少有人會直秆。
RocketMQ :單機(jī)吞吐量10萬級濒募,RocketMQ也是可以支撐高吞吐的一種MQ,topic可以達(dá)到幾百圾结,幾千個的級別瑰剃,吞吐量會有較小幅度的下降,這是RocketMQ的一大優(yōu)勢疫稿,在同等機(jī)器下培他,可以支撐大量的topic鹃两,可用性非常高,分布式架構(gòu)舀凛,在阿里大規(guī)模應(yīng)用過俊扳,有阿里品牌保障,日處理消息上百億之多猛遍,可以做到大規(guī)模吞吐馋记,性能也非常好,分布式擴(kuò)展也很方便懊烤,源碼是JAVA.
Kafka : 單機(jī)吞吐量10萬級別梯醒,這是kafka最大的優(yōu)點(diǎn),就是吞吐量高腌紧。一般配合大數(shù)據(jù)類的系統(tǒng)來進(jìn)行實(shí)時數(shù)據(jù)計(jì)算茸习、日志采集等場景.topic從幾十個到幾百個的時候,吞吐量會大幅度下降
所以在同等機(jī)器下壁肋,kafka盡量保證topic數(shù)量不要過多号胚。如果要支撐大規(guī)模topic,需要增加更多的機(jī)器資源,可用性非常高浸遗,kafka是分布式的猫胁,一個數(shù)據(jù)多個副本,少數(shù)機(jī)器宕機(jī)跛锌,不會丟失數(shù)據(jù)弃秆,不會導(dǎo)致不可用。