面试题答案
一键面试生产者
- ACK机制:
acks = 0
:生产者发送消息后,不需要等待任何Broker的确认,直接认为消息发送成功。这种模式下,消息丢失的可能性较大,因为如果在发送过程中网络出现问题,生产者无法得知消息是否真正到达Broker。acks = 1
:生产者发送消息后,只要Leader副本成功接收消息并写入本地日志,就会向生产者发送确认。此时,如果Leader副本在向Follower副本同步数据之前崩溃,消息可能会丢失。acks = all
或acks = -1
:生产者发送消息后,需要等待所有同步中的副本(ISR中的副本)都成功接收消息后,才会收到确认。这种情况下,只要ISR中有一个副本存活,消息就不会丢失,大大提高了数据的可靠性。
- 重试机制:当生产者发送消息失败时(比如网络问题导致消息未被成功确认),会根据配置的重试次数和重试间隔进行重试。默认情况下,生产者会无限次重试,但可以通过
retries
参数设置最大重试次数。这样可以避免因临时网络故障等原因导致的消息丢失。
消费者
- 偏移量管理:
- 自动提交偏移量:消费者可以配置自动提交偏移量,Kafka会定期将消费者当前消费到的偏移量提交到Kafka内部的
__consumer_offsets
主题。这种方式简单,但可能会出现重复消费或消息丢失的情况。例如,在自动提交偏移量后但还未处理完当前批次的消息时,消费者崩溃重启,新的消费者实例会从已提交的偏移量开始消费,导致部分消息未被完全处理。 - 手动提交偏移量:消费者可以手动控制偏移量的提交时机。在处理完一批消息后,再手动提交偏移量。这样可以确保消息被成功处理后才更新偏移量,避免消息丢失。同时,手动提交又分为同步提交(
commitSync
)和异步提交(commitAsync
)。同步提交会阻塞当前线程直到提交成功,而异步提交不会阻塞线程,但可能会因为回调函数处理不当导致提交失败未被察觉。
- 自动提交偏移量:消费者可以配置自动提交偏移量,Kafka会定期将消费者当前消费到的偏移量提交到Kafka内部的
- 再均衡机制:当消费者组内成员发生变化(如新增消费者或消费者崩溃)时,Kafka会触发再均衡。在再均衡过程中,为了保证数据不丢失,消费者会暂停消费,等待分区重新分配完成后,从上次提交的偏移量继续消费。同时,Kafka通过
ConsumerRebalanceListener
接口提供了在再均衡前后执行自定义逻辑的能力,例如在再均衡前手动提交偏移量,以确保数据的可靠性。
Broker
- 副本机制:
- 多副本存储:Kafka的每个分区都可以配置多个副本,包括一个Leader副本和多个Follower副本。Leader副本负责处理生产者和消费者的读写请求,Follower副本会从Leader副本同步数据。当Leader副本出现故障时,Kafka会从Follower副本中选举出新的Leader副本,继续提供服务,保证数据的可用性和可靠性。
- ISR(In - Sync Replicas):ISR是与Leader副本保持同步的Follower副本集合。只有ISR中的副本才能参与Leader选举。Kafka通过动态维护ISR集合,确保只有与Leader副本同步程度在一定范围内的Follower副本才被认为是同步的。当Leader副本发生故障时,从ISR中的副本选举新Leader,这样可以最大程度地保证新Leader上的数据是完整的,避免数据丢失。
- 日志持久化:
- 刷盘策略:Kafka Broker将消息持久化到磁盘上,通过
log.flush.interval.messages
和log.flush.interval.ms
参数控制刷盘策略。前者表示每写入一定数量的消息后刷盘,后者表示每隔一定时间刷盘。这样即使Broker发生崩溃,也能保证大部分已写入的消息不会丢失。 - 日志段管理:Kafka的日志以日志段(Log Segment)为单位进行管理,每个日志段有一定的大小限制。当一个日志段写满后,会创建新的日志段。这种方式便于对日志进行清理和压缩,同时也提高了数据的读写性能和可靠性。例如,通过日志压缩(Log Compaction)机制,可以保留每个Key的最新值,在一定程度上节省存储空间并保证数据的一致性。
- 刷盘策略:Kafka Broker将消息持久化到磁盘上,通过