kafka:topic为什么要进行分区?副本机制是如何做的?
kafka為什么要在topic里加入分區(qū)的概念?如果沒有分區(qū),topic中的segment消息寫滿后,直接給訂閱者不是也可以嗎?
Kafka可以將主題劃分為多個(gè)分區(qū)(Partition),會(huì)根據(jù)分區(qū)規(guī)則選擇把消息存儲(chǔ)到哪個(gè)分區(qū)中,只要如果分區(qū)規(guī)則設(shè)置的合理,那么所有的消息將會(huì)被均勻的分布到不同的分區(qū)中,這樣就實(shí)現(xiàn)了負(fù)載均衡和水平擴(kuò)展。另外,多個(gè)訂閱者可以從一個(gè)或者多個(gè)分區(qū)中同時(shí)消費(fèi)數(shù)據(jù),以支撐海量數(shù)據(jù)處理能力:
Kafka的設(shè)計(jì)也是源自生活,好比是為公路運(yùn)輸,不同的起始點(diǎn)和目的地需要修不同高速公路(主題),高速公路上可以提供多條車道(分區(qū)),流量大的公路多修幾條車道保證暢通,流量小的公路少修幾條車道避免浪費(fèi)。收費(fèi)站好比消費(fèi)者,車多的時(shí)候多開幾個(gè)一起收費(fèi)避免堵在路上,車少的時(shí)候開幾個(gè)讓汽車并道就好了,嗯……
順便說一句,由于消息是以追加到分區(qū)中的,多個(gè)分區(qū)順序?qū)懘疟P的總效率要比隨機(jī)寫內(nèi)存還要高(引用Apache Kafka – A High Throughput Distributed Messaging System的觀點(diǎn)),是Kafka高吞吐率的重要保證之一。
為了保證數(shù)據(jù)的可靠性,Kafka會(huì)給每個(gè)分區(qū)找一個(gè)節(jié)點(diǎn)當(dāng)帶頭大哥(Leader),以及若干個(gè)節(jié)點(diǎn)當(dāng)隨從(Follower)。消息寫入分區(qū)時(shí),帶頭大哥除了自己復(fù)制一份外還會(huì)復(fù)制到多個(gè)隨從。如果隨從掛了,Kafka會(huì)再找一個(gè)隨從從帶頭大哥那里同步歷史消息;如果帶頭大哥掛了,隨從中會(huì)選舉出新一任的帶頭大哥,繼續(xù)笑傲江湖。
詳見下:卡夫卡的副本機(jī)制。?
觀點(diǎn)2:
這里其實(shí)有2個(gè)問題,可以逐一回答 ?
1.kafka為什么要在topic里加入分區(qū)的概念? topic是邏輯的概念,partition是物理的概念,對(duì)用戶來說是透明的。
producer只需要關(guān)心消息發(fā)往哪個(gè)topic,而consumer只關(guān)心自己訂閱哪個(gè)topic,并不關(guān)心每條消息存于整個(gè)集群的哪個(gè)broker。 ?為了性能考慮,如果topic內(nèi)的消息只存于一個(gè)broker,那這個(gè)broker會(huì)成為瓶頸,無法做到水平擴(kuò)展。
所以把topic內(nèi)的數(shù)據(jù)分布到整個(gè)集群就是一個(gè)自然而然的設(shè)計(jì)方式。
Partition的引入就是解決水平擴(kuò)展問題的一個(gè)方案。 ?
如同我在Kafka設(shè)計(jì)解析(一)里所講,每個(gè)partition可以被認(rèn)為是一個(gè)無限長度的數(shù)組,新數(shù)據(jù)順序追加進(jìn)這個(gè)數(shù)組。
物理上,每個(gè)partition對(duì)應(yīng)于一個(gè)文件夾。一個(gè)broker上可以存放多個(gè)partition。
這樣,producer可以將數(shù)據(jù)發(fā)送給多個(gè)broker上的多個(gè)partition,consumer也可以并行從多個(gè)broker上的不同paritition上讀數(shù)據(jù),實(shí)現(xiàn)了水平擴(kuò)展 ?
2.如果沒有分區(qū),topic中的segment消息寫滿后,直接給訂閱者不是也可以嗎 ?
“segment消息寫滿后”,consume消費(fèi)數(shù)據(jù)并不需要等到segment寫滿,只要有一條數(shù)據(jù)被commit,就可以立馬被消費(fèi) ?
segment對(duì)應(yīng)一個(gè)文件(實(shí)現(xiàn)上對(duì)應(yīng)2個(gè)文件,一個(gè)數(shù)據(jù)文件,一個(gè)索引文件),一個(gè)partition對(duì)應(yīng)一個(gè)文件夾,一個(gè)partition里理論上可以包含任意多個(gè)segment。
所以partition可以認(rèn)為是在segment上做了一層包裝。
?這個(gè)問題換個(gè)角度問可能更好,“為什么有了partition還需要segment”。
如果不引入segment,一個(gè)partition直接對(duì)應(yīng)一個(gè)文件(應(yīng)該說兩個(gè)文件,一個(gè)數(shù)據(jù)文件,一個(gè)索引文件),那這個(gè)文件會(huì)一直增大。
同時(shí),在做data purge時(shí),需要把文件的前面部分給刪除,不符合kafka對(duì)文件的順序?qū)憙?yōu)化設(shè)計(jì)方案。
引入segment后,每次做data purge,只需要把舊的segment整個(gè)文件刪除即可,保證了每個(gè)segment的順序?qū)?#xff0c;?
參考:kafka中的topic為什么要進(jìn)行分區(qū)? - 知乎?
卡夫卡的副本機(jī)制
? ? 由于Producer和Consumer都只會(huì)與Leader角色的分區(qū)副本相連,所以kafka需要以集群的組織形式提供主題下的消息高可用。kafka支持主備復(fù)制,所以消息具備高可用和持久性。
? ? 一個(gè)分區(qū)可以有多個(gè)副本,這些副本保存在不同的broker上。每個(gè)分區(qū)的副本中都會(huì)有一個(gè)作為Leader。當(dāng)一個(gè)broker失敗時(shí),Leader在這臺(tái)broker上的分區(qū)都會(huì)變得不可用,kafka會(huì)自動(dòng)移除Leader,再其他副本中選一個(gè)作為新的Leader。
在通常情況下,增加分區(qū)可以提供kafka集群的吞吐量。然而,也應(yīng)該意識(shí)到集群的總分區(qū)數(shù)或是單臺(tái)服務(wù)器上的分區(qū)數(shù)過多,會(huì)增加不可用及延遲的風(fēng)險(xiǎn)。
創(chuàng)建副本的2種模式——同步復(fù)制和異步復(fù)制
kafka動(dòng)態(tài)維護(hù)了一個(gè)同步狀態(tài)的副本的集合(a set of In-Sync Replicas),簡稱ISR。
在這個(gè)集合中的節(jié)點(diǎn)都是和leader保持高度一致的,任何一條消息只有被這個(gè)集合中的每個(gè)節(jié)點(diǎn)讀取并追加到日志中,才會(huì)向外部通知說“這個(gè)消息已經(jīng)被提交”。
只有當(dāng)消息被所有的副本加入到日志中時(shí),才算是“committed”,只有committed的消息才會(huì)發(fā)送給consumer,這樣就不用擔(dān)心一旦leader down掉了消息會(huì)丟失。
消息從leader復(fù)制到follower, 我們可以通過決定producer是否等待消息被提交的通知(ack)來區(qū)分同步復(fù)制和異步復(fù)制。
如果等待ack則為同步,如果不需要等待所有follower復(fù)制完成即回傳ack則為異步模式。
同步復(fù)制:
????????????? 1.producer聯(lián)系z(mì)k識(shí)別leader
????????????? 2.向leader發(fā)送消息
????????????? 3.leadr收到消息寫入到本地log
????????????? 4.follower從leader pull消息
????????????? 5.follower向本地寫入log
????????????? 6.follower向leader發(fā)送ack消息
????????????? 7.leader收到所有follower的ack消息
????????????? 8.leader向producer回傳ack
異步復(fù)制:
????????????? 和同步復(fù)制的區(qū)別在于,leader寫入本地log之后,
????????????? 直接向client回傳ack消息,不需要等待所有follower復(fù)制完成。
卡夫卡支持副本模式,那么其中一個(gè)broker里的掛掉,一個(gè)新的leader就能通過ISR機(jī)制推選出來,繼續(xù)處理讀寫請(qǐng)求。
Kafka集群partition?replication默認(rèn)自動(dòng)分配分析
下面以一個(gè)Kafka集群中4個(gè)Broker舉例,創(chuàng)建1個(gè)topic包含4個(gè)Partition,2 Replication;數(shù)據(jù)Producer流動(dòng)如圖所示:
(1)
(2)當(dāng)集群中新增2節(jié)點(diǎn),Partition增加到6個(gè)時(shí)分布情況如下:
副本分配邏輯規(guī)則如下:
- 在Kafka集群中,每個(gè)Broker都有均等分配Partition的Leader機(jī)會(huì)。
- 上述圖Broker Partition中,箭頭指向?yàn)楦北?#xff0c;以Partition-0為例:broker1中parition-0為Leader,Broker2中Partition-0為副本。
- 上述圖中每個(gè)Broker(按照BrokerId有序)依次分配主Partition,下一個(gè)Broker為副本,如此循環(huán)迭代分配,多副本都遵循此規(guī)則。
副本分配算法如下:
- 將所有N Broker和待分配的i個(gè)Partition排序.
- 將第i個(gè)Partition分配到第(i mod n)個(gè)Broker上.
- 將第i個(gè)Partition的第j個(gè)副本分配到第((i + j) mod n)個(gè)Broker上.
總結(jié)
以上是生活随笔為你收集整理的kafka:topic为什么要进行分区?副本机制是如何做的?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ES学习笔记之-ClusterState
- 下一篇: zcmu-1958