您好,登錄后才能下訂單哦!
在kafka中為什么高吞吐量是他的優(yōu)點(diǎn) 見(jiàn)下4點(diǎn)優(yōu)點(diǎn)
1、創(chuàng)建一個(gè)topic時(shí),同時(shí)可以指定分區(qū)數(shù)目,分區(qū)數(shù)越多,其吞吐量也越大,但是需要的資源也越多,同時(shí)也會(huì)導(dǎo)致更高的不可用性,kafka在接收到生產(chǎn)者發(fā)送的消息之后,會(huì)根據(jù)均衡策略將消息存儲(chǔ)到不同的分區(qū)中。因?yàn)槊織l消息都被append到該P(yáng)artition中,屬于順序?qū)懘疟P(pán),因此效率非常高(經(jīng)驗(yàn)證,順序?qū)懘疟P(pán)效率比隨機(jī)寫(xiě)內(nèi)存還要高,這是Kafka高吞吐率的一個(gè)很重要的保證)。
2、我們知道在kafaf中的數(shù)據(jù)不會(huì)一直保存著,一般默認(rèn)是存儲(chǔ)2周時(shí)間,2周時(shí)間之后會(huì)刪除數(shù)據(jù),當(dāng)然這些可以通關(guān)參數(shù)去調(diào)整,
因此Kafka提供兩種策略刪除舊數(shù)據(jù)。一是基于時(shí)間,二是基于Partition文件大小。例如可以通過(guò)配置$KAFKA_HOME/config/server.properties,讓Kafka刪除一周前的數(shù)據(jù),也可在Partition文件超過(guò)1GB時(shí)刪除舊數(shù)據(jù),
log.retention.hours=168
log.segment.bytes=1073741824
log.retention.check.interval.ms=300000
log.cleaner.enable=false
那既然刪除數(shù)據(jù)和kafka的性能無(wú)關(guān),怎么刪除數(shù)據(jù)就磁盤(pán)策略以及具體的需求有關(guān)。
offset由Consumer控制,因?yàn)閛ffet由Consumer控制,所以Kafka broker是無(wú)狀態(tài)的,它不需要標(biāo)記哪些消息被哪些消費(fèi)過(guò),也不需要通過(guò)broker去保證同一個(gè)Consumer Group只有一個(gè)Consumer能消費(fèi)某一條消息,因此也就不需要鎖機(jī)制,這也為Kafka的高吞吐率提供了有力保障。
3、有了Partition后,不同的消息可以并行寫(xiě)入不同broker的不同Partition里,極大的提高了吞吐率。
4、使用consumer high level api時(shí),同一個(gè)topic的一條消息只能被同一個(gè)consumer group內(nèi)的一個(gè)consumer消費(fèi),但多個(gè)consumer group可以同時(shí)消費(fèi)這一個(gè)消息。
https://blog.csdn.net/qq_36236890/article/details/81174504 //此鏈接非常的重要
kafka有幾種故障的轉(zhuǎn)移 //參考鏈接為 https://www.cnblogs.com/qingyunzong/p/9004593.html
有這么幾種可能的delivery guarantee:
At most once 消息可能會(huì)丟,但絕不會(huì)重復(fù)傳輸
At least one 消息絕不會(huì)丟,但可能會(huì)重復(fù)傳輸
Exactly once 每條消息肯定會(huì)被傳輸一次且僅傳輸一次,很多時(shí)候這是用戶(hù)所想要的。
丟數(shù)據(jù)可能性1
當(dāng)Producer向broker發(fā)送消息時(shí),一旦這條消息被commit,因數(shù)replication的存在,它就不會(huì)丟。但是如果Producer發(fā)送數(shù)據(jù)給broker后,遇到網(wǎng)絡(luò)問(wèn)題而造成通信中斷,那Producer就無(wú)法判斷該條消息是否已經(jīng)commit。雖然Kafka無(wú)法確定網(wǎng)絡(luò)故障期間發(fā)生了什么,但是Producer可以生成一種類(lèi)似于主鍵的東西,發(fā)生故障時(shí)冪等性的重試多次,這樣就做到了Exactly once。
//這一步是Producer生產(chǎn)者到kafka broker過(guò)程會(huì)出現(xiàn)的消息丟失的可能性和解決方法
丟數(shù)據(jù)可能性2
接下來(lái)討論的是消息從broker到Consumer的delivery guarantee語(yǔ)義。(僅針對(duì)Kafka consumer high level API)。Consumer在從broker讀取消息后,可以選擇commit,該操作會(huì)在Zookeeper中保存該Consumer在該P(yáng)artition中讀取的消息的offset。該Consumer下一次再讀該P(yáng)artition時(shí)會(huì)從下一條開(kāi)始讀取。
如未commit,下一次讀取的開(kāi)始位置會(huì)跟上一次commit之后的開(kāi)始位置相同。當(dāng)然可以將Consumer設(shè)置為autocommit//自動(dòng)提交,即Consumer一旦讀到數(shù)據(jù)立即自動(dòng)commit。如果只討論這一讀取消息的過(guò)程,那Kafka是確保了Exactly once。
但實(shí)際使用中應(yīng)用程序并非在Consumer讀取完數(shù)據(jù)就結(jié)束了,而是要進(jìn)行進(jìn)一步處理,而數(shù)據(jù)處理與commit的順序在很大程度上決定了消息從broker和consumer的delivery guarantee semantic(交付保證語(yǔ)義)。
//這一步是Consumer消費(fèi)者到kafka broker過(guò)程會(huì)出現(xiàn)的消息丟失的可能性和解決方法
Kafka默認(rèn)保證At least once//消息絕不會(huì)丟,但可能會(huì)重復(fù)傳輸,并且允許通過(guò)設(shè)置Producer異步提交來(lái)實(shí)現(xiàn)At most once。而Exactly once要求與外部存儲(chǔ)系統(tǒng)協(xié)作,幸運(yùn)的是Kafka提供的offset可以非常直接非常容易得使用這種方式。
生產(chǎn)者傳遞消息到broker過(guò)程
1、Producer在發(fā)布消息到某個(gè)Partition時(shí),先通過(guò)ZooKeeper找到該P(yáng)artition的Leader,然后無(wú)論該Topic的Replication Factor為多少,Producer只將該消息發(fā)送到該P(yáng)artition的Leader。
2、Leader會(huì)將該消息寫(xiě)入其本地Log。
3、每個(gè)Follower都從Leader pull數(shù)據(jù)。這種方式上,F(xiàn)ollower存儲(chǔ)的數(shù)據(jù)順序與Leader保持一致。
4、Follower在收到該消息并寫(xiě)入其Log后,向Leader發(fā)送ACK。
5、一旦Leader收到了ISR中的所有Replica的ACK,該消息就被認(rèn)為已經(jīng)commit了,
6、Leader將增加HW并且向Producer發(fā)送ACK。
提示:
為了提高性能,每個(gè)Follower在接收到數(shù)據(jù)后就立馬向Leader發(fā)送ACK,而非等到數(shù)據(jù)寫(xiě)入Log中。
注意:
因此,對(duì)于已經(jīng)commit的消息,Kafka只能保證它被存于多個(gè)Replica的內(nèi)存中,而不能保證它們被持久化到磁盤(pán)中,也就不能完全保證異常發(fā)生后該條消息一定能被Consumer消費(fèi)。Consumer讀消息也是從Leader讀取,只有被commit過(guò)的消息才會(huì)暴露給Consumer。 //這里就有可能存在丟數(shù)據(jù)的可能性 丟數(shù)據(jù)可能性3
什么是producer的同步模式和異步模式?
同步模式
如果Producer使用同步模式則Producer會(huì)在嘗試重新發(fā)送message.send.max.retries(默認(rèn)值為3)次后拋出Exception,用戶(hù)可以選擇停止發(fā)送后續(xù)數(shù)據(jù)也可選擇繼續(xù)選擇發(fā)送。而前者會(huì)造成數(shù)據(jù)的阻塞,后者會(huì)造成本應(yīng)發(fā)往該Broker的數(shù)據(jù)的丟失。
異步模式
如果Producer使用異步模式,則Producer會(huì)嘗試重新發(fā)送message.send.max.retries(默認(rèn)值為3)次后記錄該異常并繼續(xù)發(fā)送后續(xù)數(shù)據(jù),這會(huì)造成數(shù)據(jù)丟失并且用戶(hù)只能通過(guò)日志發(fā)現(xiàn)該問(wèn)題。同時(shí),Kafka的Producer并未對(duì)異步模式提供callback接口。
提示:
kafka是非同步和非異步之間的一種模式(replication)策略,同步模式和異步模式都有很大的可能出現(xiàn)數(shù)據(jù)丟失。
同步:都完成了才可以結(jié)束;異步:丟失數(shù)據(jù)用戶(hù)不知道,只能通過(guò)日志記錄
Kafka的高可靠性的保障來(lái)源于其健壯的副本(replication)策略。
參考鏈接:https://www.cnblogs.com/qingyunzong/p/9004703.html
Leader會(huì)跟蹤與其保持同步的Replica列表,該列表稱(chēng)為ISR(即in-sync Replica)。
Kafka的復(fù)制機(jī)制既不是完全的同步復(fù)制,也不是單純的異步復(fù)制。
而Kafka的這種使用ISR的方式則很好的均衡了確保數(shù)據(jù)不丟失以及吞吐率。Follower可以批量的從Leader復(fù)制數(shù)據(jù),這樣極大的提高復(fù)制性能(批量寫(xiě)磁盤(pán)),極大減少了Follower與Leader的差距。 //批量復(fù)制數(shù)據(jù)方式,防止數(shù)據(jù)丟失1
一條消息只有被ISR里的所有Follower都從Leader復(fù)制過(guò)去才會(huì)被認(rèn)為已提交。這樣就避免了部分?jǐn)?shù)據(jù)被寫(xiě)進(jìn)了Leader,還沒(méi)來(lái)得及被任何Follower復(fù)制就宕機(jī)了,而造成數(shù)據(jù)丟失(Consumer無(wú)法消費(fèi)這些數(shù)據(jù))。 //防止數(shù)據(jù)丟失2
zookeeper在kafka中會(huì)記錄哪些信息
1、記錄broker信息 比如有哪些kafka節(jié)點(diǎn)
2、記錄了topic的partitions分區(qū)信息,poartitions的leader
3、controller注冊(cè)信息
4、controller_epoch信息
[zk: 192.168.0.151(CONNECTED) 39] get /kafkagroup/controller_epoch
1 //此值為一個(gè)數(shù)字,kafka集群中第一個(gè)broker第一次啟動(dòng)時(shí)為1,以后只要集群中center controller中央控制器所在broker變更或掛掉,就會(huì)重新選舉新的center controller,每次center controller變更c(diǎn)ontroller_epoch值就會(huì) + 1;
cZxid = 0x1500000049
ctime = Sun Jan 27 16:33:22 CST 2019
mZxid = 0x1500000049
mtime = Sun Jan 27 16:33:22 CST 2019
pZxid = 0x1500000049
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 1
numChildren = 0
5、[zk: 192.168.0.151(CONNECTED) 41] ls /kafkagroup/admin/delete_topics
6、會(huì)記錄消費(fèi)者和消費(fèi)組信息consumers consumers group
如何保證kafka消費(fèi)topic的時(shí)候,數(shù)據(jù)完全有序的,也就是不同partition之間也是有序的。
1、我們知道當(dāng)前paritition內(nèi)部的順序,但是我們不能比較來(lái)自不同的兩個(gè)partition的順序,這是沒(méi)有意義的。partition中的數(shù)據(jù)是有序的,不同partition間的數(shù)據(jù)丟失了數(shù)據(jù)的順序。如果topic有多個(gè)partition,消費(fèi)數(shù)據(jù)時(shí)就不能保證數(shù)據(jù)的順序。在需要嚴(yán)格保證消息的消費(fèi)順序的場(chǎng)景下,需要將partition數(shù)目設(shè)為1。
2、對(duì)于每一個(gè)寫(xiě)入kafka中的數(shù)據(jù),他們會(huì)隨機(jī)的寫(xiě)入到當(dāng)前topic中的某一個(gè)partition內(nèi),有一個(gè)例外,你提供一個(gè)key給當(dāng)前的數(shù)據(jù),這個(gè)時(shí)候,你就可以用當(dāng)前的key去控制當(dāng)前數(shù)據(jù)應(yīng)該傳入到哪個(gè)partition中。
kafka默認(rèn)是消費(fèi)者可以分組(Consumer Group),比如有兩個(gè)消費(fèi)者組A 和B,共同消費(fèi)一個(gè)topic:order_info,A 和B所消費(fèi)的消息不會(huì)重復(fù)
比如order_info 中有100 個(gè)消息,每個(gè)消息有一個(gè)id,編號(hào)從0-99,那么,如果A組消費(fèi)0-49 號(hào),B 組就消費(fèi)50-99 號(hào)
//生產(chǎn)環(huán)境中也可以讓多個(gè)consumer共同消費(fèi)同一個(gè)topic中的數(shù)據(jù)?需要設(shè)置調(diào)整
實(shí)現(xiàn)方法一:代碼段可以實(shí)現(xiàn)
使用Consumer high level API時(shí),同一Topic的一條消息只能被同一個(gè)Consumer Group內(nèi)的一個(gè)Consumer消費(fèi),但多個(gè)Consumer Group可同時(shí)消費(fèi)這一消息。
實(shí)現(xiàn)方法二:我們可以這樣,把A B兩個(gè)消費(fèi)者分為2個(gè)不同的組,不同的消費(fèi)組可以消費(fèi)同一個(gè)topic的數(shù)據(jù)。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。