如何保证消息不丢
为了保证producer发送的数据能可靠的到达指定的topic, topic的每个分区收到消息后,都要向producer发送ack, 如果producer收到ack就会进行下一轮的发送,否则重新发送数据。
ACK响应机制:
1.何时发送ack?
确保有follower与leader同步完成,leader才发送ack,这样才能保证在leader挂掉之后在follower中选出新的leader
2.多个follower同步之后完成之后发送ack?
方案:
2.1 半数以上的follower完成同步即可发送ack
延迟低,但选举leader时,容忍n台节点的故障,需要2n+1个副本
2.2全部follower完成同步才发送ack
选举leader时,容忍n台节点的故障,需要n+1个副本, 延迟高
Kafka选择了第二种方案:
1、同样为了容忍n台节点故障,第一种方案需要2n+1个副本,第二种只需要n+1个,而kafka每个分区都有大量数据,第一种方案会造成数据大量冗余
2、网络延迟对kafka影响较小
https://blog.youkuaiyun.com/lukabruce/article/details/101012815
ISR机制:
采用第二种方案时,leader受到数据,所有follower都开始同步数据,但是有部分follower由于故障迟迟不能与leader同步,那leader需要一直等下去,直到同步完成才能发送ack???
Leader维护了一个动态的in-sync-replica set (ISR). 意为和leader保持同步的follower集合(包括leader自己)。当ISR中的follower完成同步之后,leader会给follower发送ack, 如果follower长时间未向leader同步数据,则该follower将会被剔除ISR,该时间阈值由replica.lag.time.max.ms参数设定。Leader发生故障后就会从这些ISR中选举新的leader
ACK应答机制:
对于某些不太重要的数据,对某些数据的可靠性要求不是很高,能够容忍数据的少量丢失,所以没必要等待ISR中的follower全部接受成功;
kafka为用户设置了三种可靠性级别,通过acks参数设定:
0: producer不等broker的ack, 提供了最低的延迟, broker一接收到还没有写入磁盘就返回, broker故障时会丢失数据
1:producer等待broker的ack,partition的leader落盘成功后返回ack, 如果在follower同步成功之前leader故障,会丢失数据
-1(all):producer等待broker的ack、partition的leader和follower全部落盘成功过后才返回ack,但是如果在follower同步完成后, broker发送ack之前,leader发生故障,那么会造成数据重复;
同时极端情况下,ISR的follower为0, broker故障时也会丢失数据
AR/ISR/OSR:
分区中的所有副本统称为AR(Assigned Repllicas)。所有与leader副本保持一定程度同步的副本(包括Leader)组成ISR(In-Sync Replicas),ISR集合是AR集合中的一个子集。消息会先发送到leader副本,然后follower副本才能从leader副本中拉取消息进行同步,同步期间内follower副本相对于leader副本而言会有一定程度的滞后。前面所说的“一定程度”是指可以忍受的滞后范围,这个范围可以通过参数进行配置。与leader副本同步滞后过多的副本(不包括leader)副本,组成OSR(Out-Sync Relipcas),由此可见:AR=ISR+OSR。在正常情况下,所有的follower副本都应该与leader副本保持一定程度的同步,即AR=ISR,OSR集合为空。