kafka

Kafka的優(yōu)點如下:

①解耦:在項目啟動之初來預(yù)測將來項目會碰到什么需求,是極其困難的。

消息系統(tǒng)在處理過程中間插入了一個隱含的、基于數(shù)據(jù)的接口層,兩邊的處理過程都要實現(xiàn)這一接口。

這允許你獨立的擴(kuò)展或修改兩邊的處理過程,只要確保它們遵守同樣的接口約束。

②冗余(副本):有些情況下,處理數(shù)據(jù)的過程會失敗。除非數(shù)據(jù)被持久化,否則將造成丟失。

消息隊列把數(shù)據(jù)進(jìn)行持久化直到它們已經(jīng)被完全處理,通過這一方式規(guī)避了數(shù)據(jù)丟失風(fēng)險。

許多消息隊列所采用的"插入-獲取-刪除"范式中,在把一個消息從隊列中刪除之前,需要你的處理系統(tǒng)明確的指出該消息已經(jīng)被處理完畢,從而確保你的數(shù)據(jù)被安全的保存直到你使用完畢。

③擴(kuò)展性:因為消息隊列解耦了你的處理過程,所以增大消息入隊和處理的頻率是很容易的,只要另外增加處理過程即可。不需要改變代碼、不需要調(diào)節(jié)參數(shù)。擴(kuò)展就像調(diào)大電力按鈕一樣簡單。

④靈活性&峰值處理能力:在訪問量劇增的情況下,應(yīng)用仍然需要繼續(xù)發(fā)揮作用,但是這樣的突發(fā)流量并不常見;如果為以能處理這類峰值訪問為標(biāo)準(zhǔn)來投入資源隨時待命無疑是巨大的浪費(fèi)。

使用消息隊列能夠使關(guān)鍵組件頂住突發(fā)的訪問壓力,而不會因為突發(fā)的超負(fù)荷的請求而完全崩潰。

⑤可恢復(fù)性:系統(tǒng)的一部分組件失效時,不會影響到整個系統(tǒng)。消息隊列降低了進(jìn)程間的耦合度,所以即使一個處理消息的進(jìn)程掛掉,加入隊列中的消息仍然可以在系統(tǒng)恢復(fù)后被處理。

⑥順序保證:在大多使用場景下,數(shù)據(jù)處理的順序都很重要。大部分消息隊列本來就是排序的,并且能保證數(shù)據(jù)會按照特定的順序來處理。Kafka 保證一個 Partition 內(nèi)的消息的有序性。

⑦緩沖:在任何重要的系統(tǒng)中,都會有需要不同的處理時間的元素。例如,加載一張圖片比應(yīng)用過濾器花費(fèi)更少的時間。

消息隊列通過一個緩沖層來幫助任務(wù)最高效率的執(zhí)行,寫入隊列的處理會盡可能的快速。該緩沖有助于控制和優(yōu)化數(shù)據(jù)流經(jīng)過系統(tǒng)的速度。

⑧異步通信:很多時候,用戶不想也不需要立即處理消息。消息隊列提供了異步處理機(jī)制,允許用戶把一個消息放入隊列,但并不立即處理它。想向隊列中放入多少消息就放多少,然后在需要的時候再去處理它們。

一.Receiver模式

1.會開啟一個Receiver接收器接收Kafka的數(shù)據(jù),但是一個Receiver效率低,多個Receiver又需要手動合并union數(shù)據(jù),很麻煩

2.如果Receiver掛了,會導(dǎo)致數(shù)據(jù)丟失,如果開啟WAL預(yù)寫日志,效率又低

3.Receiver使用的是Kafka的高階(高層/封裝)API,offset由Receiver維護(hù)在ZK中, Spark也會維護(hù)一份在Checkpoint中,可能會不一致

二.Direct模式

1.SparkStreaming直接連接Kafka的各個分區(qū),速度非常快

2.Direct模式使用的是Kafka的低階(底層)API,offset默認(rèn)由Spark維護(hù)在Checkpoint中,offset也可以由程序員手動維護(hù)在MySQL/Redis中, 這樣可以保證數(shù)據(jù)Exactly Once(精準(zhǔn)一次)

問題

就是副本分區(qū)當(dāng)中的數(shù)據(jù)與leader當(dāng)中的數(shù)據(jù)存在差別的問題如何解決,這個就是Partition tolerance的問題。

kafka為了解決Partition tolerance的問題,使用了ISR的同步策略,來盡最大可能減少Partition tolerance的問題

每個leader會維護(hù)一個ISR(a set of in-sync replicas,基本同步)列表

? ISR列表主要的作用就是決定哪些副本分區(qū)是可用的,也就是說可以將leader分區(qū)里面的數(shù)據(jù)同步到副本分區(qū)里面去,決定一個副本分區(qū)是否可用的條件有兩個

replica.lag.time.max.ms=10000? ? 副本分區(qū)與主分區(qū)心跳時間延遲

replica.lag.max.messages=4000? ? 副本分區(qū)與主分區(qū)消息同步最大差

什么情況下一個 broker 會從 isr中踢出去

leader會維護(hù)一個與其基本保持同步的Replica列表,該列表稱為ISR(in-sync Replica),每個Partition都會有一個ISR,而且是由leader動態(tài)維護(hù) ,如果一個follower比一個leader落后太多,或者超過一定時間未發(fā)起數(shù)據(jù)復(fù)制請求,則leader將其重ISR中移除 。

kafka 為什么那么快(實現(xiàn)高吞吐率)

順序讀寫:Kafka 將消息寫入到了分區(qū) Partition 中,而分區(qū)中的消息又是順序讀寫的。順序讀寫要快于隨機(jī)讀寫。

零拷貝:生產(chǎn)者、消費(fèi)者對于 Kafka 中的消息是采用零拷貝實現(xiàn)的。

批量發(fā)送:Kafka 允許批量發(fā)送模式。

消息壓縮:Kafka 允許對消息集合進(jìn)行壓縮。

kafka producer如何優(yōu)化打入速度

增加線程

提高 batch.size

增加更多 producer 實例

增加 partition 數(shù)

設(shè)置 acks=-1 時,如果延遲增大:可以增大 num.replica.fetchers(follower 同步數(shù)據(jù)的線程數(shù))來調(diào)解;

跨數(shù)據(jù)中心的傳輸:增加 socket 緩沖區(qū)設(shè)置以及 OS tcp 緩沖區(qū)設(shè)置。

kafka的message格式是什么樣的

一個Kafka的Message由一個固定長度的header和一個變長的消息體body組成

header部分由一個字節(jié)的magic(文件格式)和四個字節(jié)的CRC32(用于判斷body消息體是否正常)構(gòu)成。

當(dāng)magic的值為1的時候,會在magic和crc32之間多一個字節(jié)的數(shù)據(jù):attributes(保存一些相關(guān)屬性,

比如是否壓縮、壓縮格式等等);如果magic的值為0,那么不存在attributes屬性

body是由N個字節(jié)構(gòu)成的一個消息體,包含了具體的key/value消息

kafka中consumer group 是什么概念

同樣是邏輯上的概念,是Kafka實現(xiàn)單播和廣播兩種消息模型的手段。同一個topic的數(shù)據(jù),會廣播給不同的group;同一個group中的worker,只有一個worker能拿到這個數(shù)據(jù)。換句話說,對于同一個topic,每個group都可以拿到同樣的所有數(shù)據(jù),但是數(shù)據(jù)進(jìn)入group后只能被其中的一個worker消費(fèi)。group內(nèi)的worker可以使用多線程或多進(jìn)程來實現(xiàn),也可以將進(jìn)程分散在多臺機(jī)器上,worker的數(shù)量通常不超過partition的數(shù)量,且二者最好保持整數(shù)倍關(guān)系,因為Kafka在設(shè)計時假定了一個partition只能被一個worker消費(fèi)(同一group內(nèi))。

Kafka中的消息是否會丟失和重復(fù)消費(fèi)?

要確定Kafka的消息是否丟失或重復(fù),從兩個方面分析入手:消息發(fā)送和消息消費(fèi)。

1、消息發(fā)送

? ? ? ? ?Kafka消息發(fā)送有兩種方式:同步(sync)和異步(async),默認(rèn)是同步方式,可通過producer.type屬性進(jìn)行配置。Kafka通過配置request.required.acks屬性來確認(rèn)消息的生產(chǎn):

0---表示不進(jìn)行消息接收是否成功的確認(rèn);

1---表示當(dāng)Leader接收成功時確認(rèn);

-1---表示Leader和Follower都接收成功時確認(rèn);

綜上所述,有6種消息生產(chǎn)的情況,下面分情況來分析消息丟失的場景:

(1)acks=0,不和Kafka集群進(jìn)行消息接收確認(rèn),則當(dāng)網(wǎng)絡(luò)異常、緩沖區(qū)滿了等情況時,消息可能丟失;

(2)acks=1、同步模式下,只有Leader確認(rèn)接收成功后但掛掉了,副本沒有同步,數(shù)據(jù)可能丟失;

2、消息消費(fèi)

Kafka消息消費(fèi)有兩個consumer接口,Low-level?API和High-level?API:

Low-level?API:消費(fèi)者自己維護(hù)offset等值,可以實現(xiàn)對Kafka的完全控制;

High-level?API:封裝了對parition和offset的管理,使用簡單;

如果使用高級接口High-level API,可能存在一個問題就是當(dāng)消息消費(fèi)者從集群中把消息取出來、并提交了新的消息offset值后,還沒來得及消費(fèi)就掛掉了,那么下次再消費(fèi)時之前沒消費(fèi)成功的消息就“詭異”的消失了;

解決辦法:

????????針對消息丟失:同步模式下,確認(rèn)機(jī)制設(shè)置為-1,即讓消息寫入Leader和Follower之后再確認(rèn)消息發(fā)送成功;異步模式下,為防止緩沖區(qū)滿,可以在配置文件設(shè)置不限制阻塞超時時間,當(dāng)緩沖區(qū)滿時讓生產(chǎn)者一直處于阻塞狀態(tài);

????????針對消息重復(fù):將消息的唯一標(biāo)識保存到外部介質(zhì)中,每次消費(fèi)時判斷是否處理過即可。

為什么Kafka不支持讀寫分離?

在 Kafka 中,生產(chǎn)者寫入消息、消費(fèi)者讀取消息的操作都是與 leader 副本進(jìn)行交互的,從 而實現(xiàn)的是一種主寫主讀的生產(chǎn)消費(fèi)模型。

Kafka 并不支持主寫從讀,因為主寫從讀有 2 個很明 顯的缺點:

(1)數(shù)據(jù)一致性問題。數(shù)據(jù)從主節(jié)點轉(zhuǎn)到從節(jié)點必然會有一個延時的時間窗口,這個時間 窗口會導(dǎo)致主從節(jié)點之間的數(shù)據(jù)不一致。某一時刻,在主節(jié)點和從節(jié)點中 A 數(shù)據(jù)的值都為 X, 之后將主節(jié)點中 A 的值修改為 Y,那么在這個變更通知到從節(jié)點之前,應(yīng)用讀取從節(jié)點中的 A 數(shù)據(jù)的值并不為最新的 Y,由此便產(chǎn)生了數(shù)據(jù)不一致的問題。

(2)延時問題。類似 Redis 這種組件,數(shù)據(jù)從寫入主節(jié)點到同步至從節(jié)點中的過程需要經(jīng) 歷網(wǎng)絡(luò)→主節(jié)點內(nèi)存→網(wǎng)絡(luò)→從節(jié)點內(nèi)存這幾個階段,整個過程會耗費(fèi)一定的時間。而在 Kafka 中,主從同步會比 Redis 更加耗時,它需要經(jīng)歷網(wǎng)絡(luò)→主節(jié)點內(nèi)存→主節(jié)點磁盤→網(wǎng)絡(luò)→從節(jié) 點內(nèi)存→從節(jié)點磁盤這幾個階段。對延時敏感的應(yīng)用而言,主寫從讀的功能并不太適用。

Kafka中是怎么體現(xiàn)消息順序性的?

kafka每個partition中的消息在寫入時都是有序的,消費(fèi)時,每個partition只能被每一個group中的一個消費(fèi)者消費(fèi),保證了消費(fèi)時也是有序的。

整個topic不保證有序。如果為了保證topic整個有序,那么將partition調(diào)整為1.

消費(fèi)者提交消費(fèi)位移時提交的是當(dāng)前消費(fèi)到的最新消息的offset還是offset+1?

offset+1

Kafka 判斷一個節(jié)點是否還活著有那兩個條件?

(1)節(jié)點必須可以維護(hù)和 ZooKeeper 的連接,Zookeeper 通過心跳機(jī)制檢查每個節(jié)點的連接

(2)如果節(jié)點是個 follower,他必須能及時的同步 leader 的寫操作,延時不能太久

Kafka 消息是采用 Pull 模式,還是 Push 模式?

Kafka 最初考慮的問題是,customer 應(yīng)該從 brokes 拉取消息還是 brokers 將消息推送到

consumer,也就是 pull 還 push。在這方面,Kafka 遵循了一種大部分消息系統(tǒng)共同的傳統(tǒng)

的設(shè)計:producer 將消息推送到 broker,consumer 從 broker 拉取消息

一些消息系統(tǒng)比如 Scribe 和 Apache Flume 采用了 push 模式,將消息推送到下游的

consumer。這樣做有好處也有壞處:由 broker 決定消息推送的速率,對于不同消費(fèi)速率的

consumer 就不太好處理了。消息系統(tǒng)都致力于讓 consumer 以最大的速率最快速的消費(fèi)消

息,但不幸的是,push 模式下,當(dāng) broker 推送的速率遠(yuǎn)大于 consumer 消費(fèi)的速率時,

consumer 恐怕就要崩潰了。最終 Kafka 還是選取了傳統(tǒng)的 pull 模式

Pull 模式的另外一個好處是 consumer 可以自主決定是否批量的從 broker 拉取數(shù)據(jù)。Push

模式必須在不知道下游 consumer 消費(fèi)能力和消費(fèi)策略的情況下決定是立即推送每條消息還

是緩存之后批量推送。如果為了避免 consumer 崩潰而采用較低的推送速率,將可能導(dǎo)致一

次只推送較少的消息而造成浪費(fèi)。Pull 模式下,consumer 就可以根據(jù)自己的消費(fèi)能力去決

定這些策略

Pull 有個缺點是,如果 broker 沒有可供消費(fèi)的消息,將導(dǎo)致 consumer 不斷在循環(huán)中輪詢,

直到新消息到 t 達(dá)。為了避免這點,Kafka 有個參數(shù)可以讓 consumer 阻塞知道新消息到達(dá)

(當(dāng)然也可以阻塞知道消息的數(shù)量達(dá)到某個特定的量這樣就可以批量發(fā)

Kafka 存儲在硬盤上的消息格式是什么?

消息由一個固定長度的頭部和可變長度的字節(jié)數(shù)組組成。頭部包含了一個版本號和 CRC32校驗碼。

?消息長度: 4 bytes (value: 1+4+n)

?版本號: 1 byte

?CRC 校驗碼: 4 bytes

?具體的消息: n bytes

一個Kafka的Message由一個固定長度的header和一個變長的消息體body組成

header部分由一個字節(jié)的magic(文件格式)和四個字節(jié)的CRC32(用于判斷body消息體是否正常)構(gòu)成。

當(dāng)magic的值為1的時候,會在magic和crc32之間多一個字節(jié)的數(shù)據(jù):attributes(保存一些相關(guān)屬性,

比如是否壓縮、壓縮格式等等);如果magic的值為0,那么不存在attributes屬性

body是由N個字節(jié)構(gòu)成的一個消息體,包含了具體的key/value消息

數(shù)據(jù)有序

一個消費(fèi)者組里它的內(nèi)部是有序的

消費(fèi)者組與消費(fèi)者組之間是無序的

kafaka 生產(chǎn)數(shù)據(jù)時數(shù)據(jù)的分組策略

生產(chǎn)者決定數(shù)據(jù)產(chǎn)生到集群的哪個 partition 中

每一條消息都是以(key,value)格式

Key 是由生產(chǎn)者發(fā)送數(shù)據(jù)傳入

所以生產(chǎn)者(key)決定了數(shù)據(jù)產(chǎn)生到集群的哪個 partition

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

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

  • 1 kafka簡介 ??Kafka是最初由Linkedin公司開發(fā),是一個分布式、支持分區(qū)的(partition)...
    火山_6c7b閱讀 649評論 0 6
  • 應(yīng)用往Kafka寫數(shù)據(jù)的原因有很多:用戶行為分析、日志存儲、異步通信等。多樣化的使用場景帶來了多樣化的需求:消息是...
    醉舞經(jīng)閣半卷書A閱讀 1,290評論 0 2
  • Kafka是當(dāng)前分布式系統(tǒng)中最流行的消息中間件之一,憑借著其高吞吐量的設(shè)計,在日志收集系統(tǒng)和消息系統(tǒng)的應(yīng)用場景中深...
    Dali王閱讀 524評論 0 0
  • 0 消息隊列使用場景 消息通訊 異步處理 應(yīng)用解耦 流量削峰 日志處理 1 消息中間件怎么保證消息冪等性/一致性?...
    allen鍋閱讀 750評論 0 0
  • Kafka Kafka是最初由Linkedin公司開發(fā),是一個分布式、支持分區(qū)的(partition)、多副本的(...
    redleaf閱讀 378評論 0 2

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