怎么保证读取最新数据_Kafka怎么保证数据不丢失?
Kafka怎么保證數(shù)據(jù)不丟失?
這個(gè)問題要從3個(gè)方面來保證數(shù)據(jù)不丟失:生產(chǎn)者、服務(wù)端、消費(fèi)者。
01
producer 生產(chǎn)端是如何保證數(shù)據(jù)不丟失的
1.ack的配置策略
acks = all (或-1)
生產(chǎn)者在發(fā)送消息之后,需要等待ISR中所有的副本都成功寫入消息之后才能夠收到來自服務(wù)端的成功響應(yīng),在配置環(huán)境相同的情況下此種配置可以達(dá)到最強(qiáng)的可靠性。
即:在發(fā)送消息時(shí),需要leader 向fllow 同步完數(shù)據(jù)之后,也就是ISR隊(duì)列中所有的broker全部保存完這條消息后,才會(huì)向ack發(fā)送消息,表示發(fā)送成功。
2.retries的配置策略
在kafka中錯(cuò)誤分為2種,一種是可恢復(fù)的,另一種是不可恢復(fù)的。
可恢復(fù)性的錯(cuò)誤:
如遇到在leader的選舉、網(wǎng)絡(luò)的抖動(dòng)等這些異常時(shí),如果我們?cè)谶@個(gè)時(shí)候配置的retries大于0的,也就是可以進(jìn)行重試操作,那么等到leader選舉完成后、網(wǎng)絡(luò)穩(wěn)定后,這些異常就會(huì)消息,錯(cuò)誤也就可以恢復(fù),數(shù)據(jù)再次重發(fā)時(shí)就會(huì)正常發(fā)送到broker端。需要注意retries(重試)之間的時(shí)間間隔,以確保在重試時(shí)可恢復(fù)性錯(cuò)誤都已恢復(fù)。不可恢復(fù)性的錯(cuò)誤:
如:超過了發(fā)送消息的最大值(max.request.size)時(shí),這種錯(cuò)誤是不可恢復(fù)的,如果不做處理,那么數(shù)據(jù)就會(huì)丟失,因此我們需要注意在發(fā)生異常時(shí)把這些消息寫入到DB、緩存本地文件中等等,把這些不成功的數(shù)據(jù)記錄下來,等錯(cuò)誤修復(fù)后,再把這些數(shù)據(jù)發(fā)送到broker端。
3.如何選取
(1)高可用型
配置:acks = all,retries > 0 retry.backoff.ms=100(毫秒) (并根據(jù)實(shí)際情況設(shè)置retry可能恢復(fù)的間隔時(shí)間)
優(yōu)點(diǎn):這樣保證了producer端每發(fā)送一條消息都要成功,如果不成功并將消息緩存起來,等異常恢復(fù)后再次發(fā)送。
缺點(diǎn):這樣保證了高可用,但是這會(huì)導(dǎo)致集群的吞吐量不是很高,因?yàn)閿?shù)據(jù)發(fā)送到broker之后,leader要將數(shù)據(jù)同步到fllower上,如果網(wǎng)絡(luò)帶寬、不穩(wěn)定等情況時(shí),ack響應(yīng)時(shí)間會(huì)更長(zhǎng)
(2)折中型
配置:acks = 1 ?retries > 0 retries 時(shí)間間隔設(shè)置 (并根據(jù)實(shí)際情況設(shè)置retries可能恢復(fù)的間隔時(shí)間)
優(yōu)點(diǎn):保證了消息的可靠性和吞吐量,是個(gè)折中的方案
缺點(diǎn):性能處于2者中間
(3)高吞吐型
配置:acks = 0
優(yōu)點(diǎn):可以相對(duì)容忍一些數(shù)據(jù)的丟失,吞吐量大,可以接收大量請(qǐng)求
缺點(diǎn):不知道發(fā)送的消息是 否成功
02
broker端是如何保證數(shù)據(jù)不丟失的
unclean.leader.election.enable=false
設(shè)置為 false(默認(rèn)參數(shù)為 true),意思是,當(dāng)存有你最新一條記錄的 replication 宕機(jī)的時(shí)候,Kafka 自己會(huì)選舉出一個(gè)主節(jié)點(diǎn),如果默認(rèn)允許還未同步你最新數(shù)據(jù)的 replication 所在的節(jié)點(diǎn)被選舉為主節(jié)點(diǎn)的話,你的數(shù)據(jù)將會(huì)丟失,因此這里應(yīng)該按需將參數(shù)調(diào)控為 false;
03
consumer端是如何保證數(shù)據(jù)不丟失的
在consumer消費(fèi)階段,對(duì)offset的處理,關(guān)系到是否丟失數(shù)據(jù),是否重復(fù)消費(fèi)數(shù)據(jù),因此,我們把處理好offset就可以做到exactly-once && at-least-once(只消費(fèi)一次)數(shù)據(jù)。
當(dāng)enable.auto.commit=true時(shí)
表示由kafka的consumer端自動(dòng)提交offset,當(dāng)你在pull(拉取)30條數(shù)據(jù),在處理到第20條時(shí)自動(dòng)提交了offset,但是在處理21條的時(shí)候出現(xiàn)了異常,當(dāng)你再次pull數(shù)據(jù)時(shí),由于之前是自動(dòng)提交的offset,所以是從30條之后開始拉取數(shù)據(jù),這也就意味著21-30條的數(shù)據(jù)發(fā)生了丟失。
當(dāng)enable.auto.commit=false時(shí)
由于上面的情況可知自動(dòng)提交offset時(shí),如果處理數(shù)據(jù)失敗就會(huì)發(fā)生數(shù)據(jù)丟失的情況。那我們?cè)O(shè)置成手動(dòng)提交。
當(dāng)設(shè)置成false時(shí),由于是手動(dòng)提交的,可以處理一條提交一條,也可以處理一批,提交一批,由于consumer在消費(fèi)數(shù)據(jù)時(shí)是按一個(gè)batch來的,當(dāng)pull了30條數(shù)據(jù)時(shí),如果我們處理一條,提交一個(gè)offset,這樣會(huì)嚴(yán)重影響消費(fèi)的能力,那就需要我們來按一批來處理,或者設(shè)置一個(gè)累加器,處理一條加1,如果在處理數(shù)據(jù)時(shí)發(fā)生了異常,那就把當(dāng)前處理失敗的offset進(jìn)行提交(放在finally代碼塊中)注意一定要確保offset的正確性,當(dāng)下次再次消費(fèi)的時(shí)候就可以從提交的offset處進(jìn)行再次消費(fèi)。
點(diǎn)一下在看再走吧
總結(jié)
以上是生活随笔為你收集整理的怎么保证读取最新数据_Kafka怎么保证数据不丢失?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python读取多个文件夹图片_pyth
- 下一篇: 怎么圆角变直角_衣柜设计个圆角有什么用?