面试题答案
一键面试生产者发送环节
- acks机制:
acks=0
:生产者发送消息后,不需要等待任何来自Broker的确认,这种情况下速度最快,但数据可靠性最低,有可能因为网络问题等导致消息丢失。acks=1
:生产者发送消息后,只要Leader副本成功接收消息,就会给生产者发送确认。如果此时Follower副本还未同步完消息,而Leader副本所在的Broker发生故障,新选举的Leader可能没有这条消息,从而导致消息丢失。acks=all
(或acks=-1
):生产者发送消息后,需要等待ISR(In - Sync Replicas,与Leader保持同步的副本集合)中的所有副本都成功接收消息后,才会收到Broker的确认。这种方式数据可靠性最高,几乎不会丢失消息。
- 重试机制:当生产者发送消息失败时(比如网络瞬时故障等原因),可以配置重试次数和重试间隔时间。在一定次数内重试发送消息,提高消息成功发送的概率,减少消息丢失的可能性。
Broker存储环节
- 多副本机制:Kafka通过将每个分区的数据复制到多个Broker上形成多个副本,其中一个副本为Leader,其他为Follower。Leader负责处理读写请求,Follower从Leader同步数据。当Leader发生故障时,会从Follower中选举新的Leader,保证数据的可用性和持久性,减少数据丢失风险。
- ISR机制:ISR集合中的副本才被认为是与Leader保持同步的副本。只有ISR中的副本都成功写入消息,这条消息才被认为是已提交的。如果某个Follower副本落后Leader副本太多,会被移出ISR。当Leader发生故障时,只会从ISR中的Follower副本中选举新的Leader,保证新Leader的数据完整性,避免数据丢失。
- 日志刷盘策略:Kafka支持同步刷盘和异步刷盘。同步刷盘是指消息写入日志文件并刷盘成功后才向生产者发送确认,这样可以保证消息在Broker崩溃时不会丢失,但性能相对较低。异步刷盘是指消息先写入内存中的页缓存,然后由后台线程定期刷盘,这种方式性能较高,但在Broker崩溃时可能丢失部分未刷盘的消息。合理配置刷盘策略可以在性能和数据可靠性之间取得平衡。
消费者接收环节
- offset机制:消费者通过记录消费的offset(偏移量)来标记已经消费到的位置。当消费者重启或者发生再均衡时,可以根据之前记录的offset继续从上次消费的位置开始消费,避免重复消费和消息丢失。offset有自动提交和手动提交两种方式。
- 自动提交:消费者定期将offset提交到Kafka的内部主题
__consumer_offsets
中。这种方式简单,但可能会因为提交不及时,在消费者重启或再均衡时导致重复消费。 - 手动提交:消费者在处理完一批消息后,手动调用提交offset的方法。这样可以精确控制offset的提交时机,避免重复消费和消息丢失,但需要开发者小心处理提交逻辑,防止提交失败等问题。
- 自动提交:消费者定期将offset提交到Kafka的内部主题
- Exactly - Once语义:从Kafka 0.11版本开始引入了Exactly - Once语义。通过Producer ID(PID)、Sequence Number(序列号)等机制,保证生产者发送的消息在整个流处理过程中仅被处理一次,不会重复也不会丢失。在生产端,PID和Sequence Number保证消息幂等性;在消费端,结合offset机制和事务机制等实现Exactly - Once语义。