Kafka中Producer与Broker之间的交互

https://blog.csdn.net/Delicious_Life/article/details/106889968

目录

分区策略

高可用处理

Exactly Once解决消息重复发送的问题

分区策略
 

生产者放到broker中的数据为什么要分区存储?

1.方便在集群中扩展

2.更小的存储数据单元,可以提高并发

分区存储的原则

1.如果生产者指定放到broker的哪个partition中了,那就会按指定的分区存储

2.如果生产者没有指明partition但存储的内容含有key,则把key的hash值与broker的分区数进行取模,然后放到对应分区中

3.如果既没有指明partition也没有存储key,则第一次存储会随机生成一个整数,让这个整数和partition数取模,然后放到对应的分区中。第二次存储时再第一次随机生成的随机数上自增再取模执行同样的操作。

高可用处理
 

为什么生产者放到broker中这一环节需要进行高可用处理

为保证producer发送的数据,能可靠的进入到指定的broker分片中,broker的每一个分片收到producer发送的数据后都需要向producer发送ack(确认收到标志),如果producer收到ack,就会进行下一轮发送,否则重新发送数据。

发送ack产生的问题:何时发送?

kafka发送ack策略

kafka的默认设置为当所有的从节点都同步完主节点后再向producer发送ack确认标志。所有的从节点理想情况下同步后即发送ack,但要是有从节点网络延迟大,或者出现从节点宕机呢?这样就会增大了producer收到ack的时长。

为了解决这个问题,kafka提供了ISR队列

什么是ISR队列

leader维护了一个动态的in-sync replica set(ISR),意为和leader保持同步的follower集合。当ISR中的follower完成数据同步后,leader就会给follower发送ack,如果follower长期未向leader同步数据,则该follower将被踢出ISR,该事件阀值由replica.lag.time.max.ms参数设定,leader发生故障,就会从ISR中选举新的leader

ack的应答机制

为了提高ack的响应效率,对于某些不太重要的数据,对数据的可靠性要求不高,能够容忍数据的少量丢失,所以没必要等到ISR中的follower全部接收成功,因此kafka提供了三种可靠性级别,用户根据对可靠性和延迟的要求进行权衡,可以做以下参数的调整:

0:producer 不等待 broker 的 ack,这一操作提供了一个最低的延迟,broker在没接收完直接就返回ack,当 broker 故障时有可能会丢失数据;

1:producer 等待 broker 的 ack,partition 的 leader 落盘成功后返回 ack,但此时broker的主从同步尚未成功,如果在 follower同步成功之前 leader 故障,那么将会丢失数据;

-1(all):producer 等待 broker 的 ack,partition 的 leader 和 follower 全部落盘成功后才返回 ack。但是如果在 follower 同步完成后,broker向producer发送 ack 之前,leader 发生故障,broker集群会选出一个新leader,producer由于没有收到ack而重发给新leader,这样就会造成数据重复。

保证丢失的最小分片数

LEO :指的是每个副本最大的 offset ;
HW :指的是消费者能见到的最大的 offset ,ISR  队列中最小的 LEO 。
(1 )follower  故障
follower 发生故障后会被临时踢出 ISR,待该 follower 恢复后,follower 会读取本地磁盘记录的上次的 HW,并将 log 文件高于 HW 的部分截取掉,从 HW 开始向 leader 进行同步。等该 follower  的 LEO  大于等于该 Partition 的 的 HW,即 follower 追上 leader 之后,就可以重新加入 ISR 了。
(2 )leader  故障
leader 发生故障之后,会从 ISR 中选出一个新的 leader,之后,为保证多个副本之间的数据一致性,其余的 follower 会先将各自的 log 文件高于 HW 的部分截掉,然后从新的 leader同步数据。注意: 这只能保证副本之间的数据一致性,并不能保证数据不丢失或者不重复。

Exactly Once解决消息重复发送的问题
 

将ack设置为-1,可以保证producer到broker之间不会丢失数据,即At Least Once。相对的,将ack设置为0,可以保证生产者每条消息只会发送一次,即At Most Once。

At Least Once可以保证数据不丢失,但不能保证数据不重复;At Most Once可以保证数据不重复,但不能保证数据不丢失。如何保证数据既不丢失也不重复呢?Exactly Once

Kafka在0.11版本之后引入了“幂等性”的概念,幂等性指producer不论向broker发送多少次重复的数据,broker都会保存1条,幂等性结合了At Least Once构成了Exactly Once

启用幂等性需要将producer的参数enable.idompotence设置为true。开启幂等性的producer在初始化时会分配一个PID,发往同一个partition的消息会附带Sequence Number。而broker端会对<PID,Partition,SeqNumber>做缓存,当具有相同主键的消息提交时,broker只会持久化一条,但如果broker因宕机或重启导致PID变化就会重新生成PID,不同的partition也有不同主键,这种跨分区,跨会话的Exactly Once无法解决消息重复。
 

猜你喜欢

转载自blog.csdn.net/Maxiao1204/article/details/119991311