瑞星 发表于 2024-12-20 09:19:40

Kafka 怎样保证数据不丢失?不重复?

2、retries的设置策略
   在kafka中错误分为2种,一种是可规复的,另一种是不可规复的。
    可规复性的错误:
    如碰到在leader的选举、网络的抖动等这些异常时,假如我们在这个时间设置的retries大于0的,也就是可以进行重试操作,那么等到leader选举完成后、网络稳定后,这些异常就会消息,错误也就可以规复,数据再次重发时就会正常发送到broker端。需要注意retries(重试)之间的时间间隔,以确保在重试时可规复性错误都已规复。
    不可规复性的错误:
    如:超过了发送消息的最大值(max.request.size)时,这种错误是不可规复的,假如不做处置处罚,那么数据就会丢失,因此我们需要注意在发生异常时把这些消息写入到DB、缓存本地文件中等等,把这些不乐成的数据记载下来,等错误修复后,再把这些数据发送到broker端。
我们上面讲了2个设置项的作用,下面联合现实场景怎样使用
3、怎样选取
   1.高可用型
    设置:acks = all,retries > 0 retry.backoff.ms=100(毫秒) (并根据现真相况设置retry大概规复的间隔时间)
    优点:这样保证了producer端每发送一条消息都要乐成,假如不乐成并将消息缓存起来,等异常规复后再次发送。
    缺点:这样保证了高可用,但是这会导致集群的吞吐量不是很高,由于数据发送到broker之后,leader要将数据同步到fllower上,假如网络带宽、不稳定等情况时,ack相应时间会更长
    2.折中型
    设置:acks = 1 retries > 0 retries 时间间隔设置 (并根据现真相况设置retries大概规复的间隔时间)
    优点:保证了消息的可靠性和吞吐量,是个折中的方案
    缺点:性能处于2者中间
   3.高吞吐型
    设置:acks = 0
    优点:可以相对容忍一些数据的丢失,吞吐量大,可以接收大量请求
    缺点:不知道发送的消息是 否乐成
二、consumer端是怎样保证数据不丢失的
1、consumer端的设置项
   group.id: consumer group 分组的一个id
    消费者隶属的消费组名称。在kafka中只允许消息只能被某个组内里的一个consumer端消费,假如为空,则会报异常。
    对于一个新的consumer参加到消费时,肯定会隶属于哪个组,只有这样才气消费数据
    auto.offset.reset = earliest(最早) /latest(最晚)
    从何处开始进行消费
    当一个新参加的consumer要进行消费数据,假如这个consumer是做数据分析工作的,是需要以前的历史数据那就需要从最早的位置消费数据,假如仅仅是查看消费情况,那可以从最晚位置开始消费数据
    enable.auto.commit = true/false(默认true)
    是否开启自动提交消费位移的功能,默认开启.
    当设置为true时,意味着由kafka的consumer端自己间隔一定的时间会自动提交offset,假如设置成了fasle,也就是由客户端(自己写代码)来提交,那就还得控制提交的时间间隔auto.commit.interval.ms
    auto.commit.interval.ms
    当enable.auto.commit设置为true时才生效,表示开启自动提交消费位移功能时自动提交消费位移的时间间隔。
   2、consumer端的设置策略
   在consumer消费阶段,对offset的处置处罚,关系到是否丢失数据,是否重复消费数据,因此,我们把处置处罚好offset就可以做到exactly-once && at-least-once(只消费一次)数据。
    当enable.auto.commit=true时
    表示由kafka的consumer端自动提交offset,当你在pull(拉取)30条数据,在处置处罚到第20条时自动提交了offset,但是在处置处罚21条的时间出现了异常,当你再次pull数据时,由于之前是自动提交的offset,所以是从30条之后开始拉取数据,这也就意味着21-30条的数据发生了丢失。
    当enable.auto.commit=false时
    由于上面的情况可知自动提交offset时,假如处置处罚数据失败就会发生数据丢失的情况。那我们设置成手动提交。
    当设置成false时,由于是手动提交的,可以处置处罚一条提交一条,也可以处置处罚一批,提交一批,由于consumer在消费数据时是按一个batch来的,当pull了30条数据时,假如我们处置处罚一条,提交一个offset,这样会严峻影响消费的能力,那就需要我们来按一批来处置处罚,或者设置一个累加器,处置处罚一条加1,假如在处置处罚数据时发生了异常,那就把当前处置处罚失败的offset进行提交(放在finally代码块中)注意一定要确保offset的正确性,当下次再次消费的时间就可以从提交的offset处进行再次消费。
3、comsumer 的应用场景
   1.一直commit offset的处置处罚
    假如poll了100条数据,每处置处罚1条,commit offset一次,这样会严峻影响性能,在处置处罚的时间设置1个计数器(或累加器),按一批来提交,但要确保提交offset的准确性
   
    2.rebalance的影响
    在处置处罚数据时,有2种情况会发生,一种情况是处置处罚了一半的时间,发生了rebalance,但是offset还没有来得及提交,另一种情况是rebalance发生后,重新分配了offset,在这种情况时会发生错误。
   
    3.消息处置处罚错误时的处置处罚
    假如consumer在处置处罚数据的时间失败了,那么可以把这条数据给缓存起来,可以是redis、DB、file等,也可以把这条消息存入专门用于存储失败消息的topic中,让别的的consumer专门处置处罚失败的消息。
    4.处置处罚消息的时间过长
    假如poll一批100条消息的时间是1秒钟,但是在每处置处罚1条需要花费1秒钟,这样来说极其影响消费能力,那我们可以把100条消息放到1个线程池中处置处罚。这里特别特别注意,由于线程池的处置处罚举动是并行的,所以要做对offset的判断。这里先说正常情况,假如消息都能被正常处置处罚,那么会提交1个offset,并把这个offset存起来,假如此时又提交了1个offset,把2个offset相对比,哪个大把哪个存起来并做提交。假如消息处置处罚发生了错误,我们在前面讲过,把这个错误消息发送到专门处置处罚错误的topic中,让专门的consumer来处置处罚。
4、consumer 保证确保消息只被处置处罚一次处置处罚,同时确保幂等性
   exactly-once & at-least-once
    如何保证消息只获取一次并且确定被处理呢?这就需要我们在处理消息的时候要添加一个unique key
    假如pull 一个batch 100条的消息,在处置处罚到第80条的时间,由于网络延迟、或者crash的原因没有来得及提交offset,被处置处罚的80条数据都添加了unique key, 可以存到到DB中或者redis中(推荐,由于这样更快),当consumer端会再次poll消费数据时,由于没有提交offset,所以会从0开始消费数据,假如对之前已经消息过的数据没有做unique key的处置处罚,那么会造成重复消息之前的80条数据,但是假如把每条对应的消息都添加了unique key,那就只需要对被处置处罚的消息进行判断,有没有unique key 就可以做到不重复消费数据的题目,这样也同时保证了幂等性。
三、broker端是怎样保证数据不丢失的
1、broker端的设置项
以下参数都是在创建topic时进行设置
   1.replication-factor 3
    在创建topic时会通过replication-factor来创建副本的个数,它提高了kafka的高可用性,同时,它允许n-1台broker挂掉,设置好公道的副本因子对kafka团体性能是非常有资助的,通常是3个,极限是5个,假如多了也会影响开销。
   2.min.insync.replicas = 2
    分区ISR队列集合中最少有多少个副本,默认值是1
   
    3.unclean.leander.election.enable = false
    是否允许从ISR队列中选举leader副本,默认值是false,假如设置成true,则大概会造成数据丢失。
2、leader选举造成的数据丢失

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Kafka 怎样保证数据不丢失?不重复?