51CTO:也就这么回事,Kafka架构原理( 三 )


51CTO:也就这么回事,Kafka架构原理
文章图片
②ISR
采用第二种方案 , 所有Follower完成同步 , Producer才能继续发送数据 , 设想有一个Follower因为某种原因出现故障 , 那Leader就要一直等到它完成同步 。
这个问题怎么解决?Leader维护了一个动态的in-syncreplicaset(ISR):和Leader保持同步的Follower集合 。
当ISR集合中的Follower完成数据的同步之后 , Leader就会给Follower发送ACK 。
如果Follower长时间未向Leader同步数据 , 则该Follower将被踢出ISR集合 , 该时间阈值由replica.lag.time.max.ms参数设定 。 Leader发生故障后 , 就会从ISR中选举出新的Leader 。
③ACK应答机制
对于某些不太重要的数据 , 对数据的可靠性要求不是很高 , 能够容忍数据的少量丢失 , 所以没必要等ISR中的Follower全部接受成功 。
所以Kafka为用户提供了三种可靠性级别 , 用户根据可靠性和延迟的要求进行权衡 , 选择以下的配置 。
51CTO:也就这么回事,Kafka架构原理
文章图片
Ack参数配置:
0:Producer不等待Broker的ACK , 这提供了最低延迟 , Broker一收到数据还没有写入磁盘就已经返回 , 当Broker故障时有可能丢失数据 。 1:Producer等待Broker的ACK , Partition的Leader落盘成功后返回ACK , 如果在Follower同步成功之前Leader故障 , 那么将会丢失数据 。 -1(all):Producer等待Broker的ACK , Partition的Leader和Follower全部落盘成功后才返回ACK 。 但是在Broker发送ACK时 , Leader发生故障 , 则会造成数据重复 。④故障处理细节
51CTO:也就这么回事,Kafka架构原理
文章图片
LEO:每个副本最大的Offset 。 HW:消费者能见到的最大的Offset , ISR队列中最小的LEO 。
Follower故障:Follower发生故障后会被临时踢出ISR集合 , 待该Follower恢复后 , Follower会读取本地磁盘记录的上次的HW , 并将log文件高于HW的部分截取掉 , 从HW开始向Leader进行同步数据操作 。
等该Follower的LEO大于等于该Partition的HW , 即Follower追上Leader后 , 就可以重新加入ISR了 。
Leader故障:Leader发生故障后 , 会从ISR中选出一个新的Leader , 之后 , 为保证多个副本之间的数据一致性 , 其余的Follower会先将各自的log文件高于HW的部分截掉 , 然后从新的Leader同步数据 。
注意:这只能保证副本之间的数据一致性 , 并不能保证数据不丢失或者不重复 。
ExactlyOnce语义
将服务器的ACK级别设置为-1 , 可以保证Producer到Server之间不会丢失数据 , 即AtLeastOnce语义 。
相对的 , 将服务器ACK级别设置为0 , 可以保证生产者每条消息只会被发送一次 , 即AtMostOnce语义 。
AtLeastOnce可以保证数据不丢失 , 但是不能保证数据不重复;相对的 , AtMostOnce可以保证数据不重复 , 但是不能保证数据不丢失 。
但是 , 对于一些非常重要的信息 , 比如交易数据 , 下游数据消费者要求数据既不重复也不丢失 , 即ExactlyOnce语义 。
0.11版本的Kafka , 引入了幂等性:Producer不论向Server发送多少重复数据 , Server端都只会持久化一条 。
即:
AtLeastOnce+幂等性=ExactlyOnce要启用幂等性 , 只需要将Producer的参数中enable.idompotence设置为true即可 。
开启幂等性的Producer在初始化时会被分配一个PID , 发往同一Partition的消息会附带SequenceNumber 。
【51CTO:也就这么回事,Kafka架构原理】而Borker端会对
但是PID重启后就会变化 , 同时不同的Partition也具有不同主键 , 所以幂等性无法保证跨分区会话的ExactlyOnce 。