Kafka 面试题及详细答案100道(11-22)-- 核心机制1

发布于:2025-08-17 ⋅ 阅读:(17) ⋅ 点赞:(0)

前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,SQL,Linux… 。

前后端面试题-专栏总目录

在这里插入图片描述

文章目录

  • 一、本文面试题目录
      • 11. 什么是Kafka的分区(Partition)?为什么要进行分区?
      • 12. 分区的数量对Kafka的性能有什么影响?如何确定分区数量?
      • 13. Kafka的分区副本(Replica)有什么作用?
      • 14. 什么是首领副本(Leader Replica)和追随者副本(Follower Replica)?它们的职责分别是什么?
      • 15. 简述Kafka的副本同步机制(ISR机制)。
      • 16. ISR(In-Sync Replicas)、OSR(Out-of-Sync Replicas)、AR(Assigned Replicas)的区别是什么?
      • 17. 当Leader副本故障时,Kafka如何进行故障转移?
      • 18. 什么是Kafka的消费者组(Consumer Group)?它的作用是什么?
      • 19. 消费者组内的消费者如何分配分区?有哪些分配策略?
      • 20. 消费者重平衡(Rebalance)是什么?触发重平衡的场景有哪些?
      • 21. 重平衡会带来什么问题?如何避免或减轻其影响?
      • 22. Kafka的消息是如何被持久化的?
  • 二、100道Kafka 面试题目录列表

一、本文面试题目录

11. 什么是Kafka的分区(Partition)?为什么要进行分区?

Kafka的分区(Partition) 是Topic的物理分片,是Kafka实现并行处理和水平扩展的核心机制。每个Topic可以被划分为多个Partition,每个Partition是一个有序的、不可变的消息序列,消息被追加到Partition的末尾并分配唯一的偏移量(Offset)。

进行分区的主要原因

  1. 提高吞吐量:多个Partition可以并行处理读写操作,大幅提升系统整体吞吐量
  2. 实现负载均衡:不同Partition可以分布在不同的Broker上,均衡集群负载
  3. 支持水平扩展:通过增加Partition数量或Broker节点扩展系统容量
  4. 保证局部有序性:每个Partition内部的消息是严格有序的,满足有序性需求
  5. 方便数据管理:可以针对不同Partition设置不同的存储和清理策略

示例:创建一个包含3个分区的Topic

# 使用kafka-topics.sh创建Topic
bin/kafka-topics.sh --create \
  --bootstrap-server localhost:9092 \
  --topic user-tracking \
  --partitions 3 \
  --replication-factor 2

12. 分区的数量对Kafka的性能有什么影响?如何确定分区数量?

分区数量对性能的影响

  • 正面影响
    • 更多分区可以提供更高的并行度,提高吞吐量
    • 可以分布到更多Broker上,充分利用集群资源
  • 负面影响
    • 过多分区会增加集群元数据管理开销
    • 增加ZooKeeper的负担(旧版本)
    • 增加消费者重平衡(Rebalance)的时间
    • 每个分区都有副本,过多分区会占用更多内存和磁盘资源

确定分区数量的方法

  1. 基于吞吐量需求

    • 先测试单个分区的吞吐量(如每秒1000条消息)
    • 根据总吞吐量需求计算大致分区数(如需要每秒5000条则至少5个分区)
  2. 考虑消费者数量

    • 分区数应大于等于消费者组中消费者的数量,否则部分消费者会空闲
    • 一般建议分区数是消费者数量的1-10倍
  3. 参考经验值

    • 对于一般业务场景,单个Topic的分区数建议在10-100之间
    • 对于高吞吐量场景,可增加到数百个,但需监控集群性能
  4. 考虑存储和副本因素

    • 分区数 × 副本数不应过多,避免超出集群存储能力

示例:通过kafka-configs.sh查看和修改分区相关配置

# 查看Topic的分区配置
bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic user-tracking

# 增加分区数量(注意:只能增加不能减少)
bin/kafka-topics.sh --alter \
  --bootstrap-server localhost:9092 \
  --topic user-tracking \
  --partitions 5

13. Kafka的分区副本(Replica)有什么作用?

Kafka的分区副本(Replica)是指为每个Partition创建的多个数据备份,分布在不同的Broker节点上。其主要作用如下:

  1. 提供数据冗余

    • 多个副本存储相同的数据,防止单点故障导致的数据丢失
    • 即使部分Broker宕机,数据仍可从其他副本中获取
  2. 保证高可用性

    • 当Leader副本所在的Broker故障时,可从Follower副本中选举新的Leader
    • 确保消息的生产和消费可以继续进行,不中断服务
  3. 提高读取性能

    • 允许消费者从Follower副本读取数据(可选配置)
    • 分担Leader副本的读取压力,提高整体读取吞吐量
  4. 支持灵活的可靠性配置

    • 可以根据业务需求配置不同的副本数量
    • 重要数据可配置更多副本,非重要数据可配置较少副本

示例:创建带有3个副本的Topic

bin/kafka-topics.sh --create \
  --bootstrap-server localhost:9092 \
  --topic payment-transactions \
  --partitions 4 \
  --replication-factor 3  # 每个分区有3个副本

14. 什么是首领副本(Leader Replica)和追随者副本(Follower Replica)?它们的职责分别是什么?

在Kafka中,每个Partition的多个副本中,有一个被指定为首领副本(Leader Replica),其余的则是追随者副本(Follower Replica)

首领副本(Leader Replica)的职责

  • 处理所有针对该Partition的读写请求
  • 维护消息的偏移量(Offset)信息
  • 负责将新消息同步给所有Follower副本
  • 决定哪些消息可以被消费者读取(已提交的消息)

追随者副本(Follower Replica)的职责

  • 从Leader副本同步消息,保持与Leader的数据一致性
  • 当Leader副本故障时,参与Leader选举,可能成为新的Leader
  • 不处理客户端的读写请求(默认配置下)
  • 监控Leader的状态,确保自己与Leader保持同步

示例:查看分区的Leader和Follower分布

# 查看Topic的详细信息,包括每个分区的Leader和Follower
bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic payment-transactions

# 输出示例(简化):
# Partition: 0  Leader: 1  Replicas: 1,2,0  Isr: 1,2,0
# Partition: 1  Leader: 2  Replicas: 2,0,1  Isr: 2,0,1

15. 简述Kafka的副本同步机制(ISR机制)。

Kafka的副本同步机制主要通过ISR(In-Sync Replicas,同步副本集合) 实现,确保消息在多个副本之间的一致性:

  1. ISR定义

    • ISR是指与Leader副本保持同步的Follower副本集合,包括Leader本身
    • 只有ISR中的副本才有资格被选举为新的Leader
  2. 同步过程

    • 生产者发送消息到Leader副本
    • Leader将消息写入本地日志,并向Follower发送同步请求
    • Follower从Leader拉取消息,写入本地日志,并向Leader发送确认
    • 当Leader收到足够多的ISR副本确认后,标记消息为"已提交"(Committed)
    • 只有已提交的消息才会被消费者读取
  3. 同步条件

    • Follower必须在规定时间内(replica.lag.time.max.ms,默认30秒)向Leader发送fetch请求
    • Follower的消息偏移量与Leader的差距不能超过规定阈值(replica.lag.max.messages,已过时)
  4. 动态调整

    • 当Follower落后太多或长时间未通信,会被移出ISR
    • 当Follower重新跟上Leader的进度,会被重新加入ISR

示例:修改ISR相关配置(server.properties)

# Follower多久未发送请求会被踢出ISR,默认30000ms
replica.lag.time.max.ms=30000

# 首领在认为消息已提交前需要收到的确认数
min.insync.replicas=2

16. ISR(In-Sync Replicas)、OSR(Out-of-Sync Replicas)、AR(Assigned Replicas)的区别是什么?

ISR、OSR和AR是Kafka中描述副本状态的三个重要概念,它们的区别如下:

  • AR(Assigned Replicas,已分配副本)

    • 定义:为某个Partition配置的所有副本的集合
    • 包含:Leader副本 + 所有Follower副本
    • 特点:数量等于副本因子(replication factor),一旦配置后不会轻易改变
    • 示例:如果一个Partition的副本因子是3,那么AR就包含3个副本
  • ISR(In-Sync Replicas,同步副本)

    • 定义:与Leader副本保持同步状态的副本集合
    • 包含:Leader副本 + 所有与Leader保持同步的Follower副本
    • 特点:是AR的子集,会动态变化;只有ISR中的副本可以被选举为新Leader
    • 同步标准:在规定时间内与Leader通信,且消息偏移量差距在允许范围内
  • OSR(Out-of-Sync Replicas,非同步副本)

    • 定义:与Leader副本不同步的Follower副本集合
    • 包含:AR中除去ISR的所有副本
    • 特点:因落后太多或长时间未通信而被移出ISR;不参与消息确认和Leader选举
    • 可能原因:网络问题、Follower负载过高、硬件性能不足等

三者关系:AR = ISR + OSR,其中ISR始终包含Leader副本。

示例:查看分区的AR、ISR状态

bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic order-events

# 输出示例解释:
# Partition: 0  Leader: 2  Replicas: 2,0,1  Isr: 2,0
# 说明:AR = [2,0,1],ISR = [2,0],OSR = [1]

17. 当Leader副本故障时,Kafka如何进行故障转移?

当Leader副本所在的Broker发生故障时,Kafka通过以下机制进行故障转移,确保服务连续性:

  1. 故障检测

    • ZooKeeper(或Kafka控制器)监控所有Broker的心跳状态
    • 当Leader所在Broker超过一定时间(默认6秒)未发送心跳,判定为故障
  2. 触发Leader选举

    • 控制器(Controller)负责检测到Leader故障后发起选举
    • 控制器是Kafka集群中的一个特殊Broker,负责管理分区Leader选举
  3. 选举新Leader

    • 从该Partition的ISR(同步副本集合)中选择新的Leader
    • 选举优先级:通常选择ISR中副本偏移量最大的Follower(最接近Leader的状态)
    • 如果ISR为空,可配置是否允许从OSR中选举(unclean.leader.election.enable)
  4. 更新元数据

    • 新Leader选举完成后,控制器更新集群元数据
    • 将新的Leader信息广播给所有Broker和消费者
  5. 恢复服务

    • 新Leader开始处理读写请求
    • 其他Follower开始从新Leader同步数据
    • 客户端(生产者和消费者)通过元数据更新知道新的Leader位置

示例:配置故障转移相关参数(server.properties)

# 控制器检测Broker故障的超时时间
controller.socket.timeout.ms=30000

# 是否允许从非同步副本中选举Leader(不推荐开启)
unclean.leader.election.enable=false

# 副本同步的超时时间
replica.lag.time.max.ms=30000

18. 什么是Kafka的消费者组(Consumer Group)?它的作用是什么?

Kafka的消费者组(Consumer Group) 是由多个消费者实例组成的群体,共同消费一个或多个Topic的消息。每个消费者组有一个唯一的ID,组内的消费者协同工作。

消费者组的主要作用

  1. 负载均衡

    • 多个消费者共同分担消费压力,提高消息处理能力
    • 每个Partition的消息只会被组内的一个消费者消费
  2. 高可用性

    • 当组内某个消费者故障时,其负责的Partition会被分配给其他消费者
    • 保证消费过程不中断,提高系统可用性
  3. 并行处理

    • 不同Partition的消息可以被不同消费者并行处理
    • 提高整体消息处理吞吐量
  4. 灵活的消费模式

    • 同一个Topic可以被多个消费者组同时消费(发布-订阅模式)
    • 每个消费者组独立维护自己的消费偏移量

示例:使用Java客户端创建消费者组

import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.Properties;
import java.util.Arrays;

public class ConsumerGroupExample {
    public static void main(String[] args) {
        Properties props = new Properties();
        props.put("bootstrap.servers", "localhost:9092");
        // 消费者组ID,相同ID的消费者属于同一个组
        props.put("group.id", "order-processing-group");
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

        KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
        // 订阅主题
        consumer.subscribe(Arrays.asList("order-events"));
        
        // 消费消息的逻辑...
    }
}

19. 消费者组内的消费者如何分配分区?有哪些分配策略?

消费者组内的分区分配是指将订阅Topic的所有Partition分配给组内的消费者,确保每个Partition只被一个消费者消费。Kafka提供了多种分配策略:

分配过程

  1. 消费者加入组后,由组协调器(Coordinator)负责分配
  2. 协调器从组内选择一个消费者作为leader,负责执行分配逻辑
  3. 分配结果被广播给所有消费者
  4. 每个消费者只处理分配给自己的Partition

主要分配策略

  1. Range(范围分配,默认策略)

    • 按Topic分组,为每个Topic的Partition按顺序分配
    • 为每个消费者分配连续的Partition范围
    • 优点:简单直观;缺点:可能导致分配不均
  2. RoundRobin(轮询分配)

    • 将所有Topic的Partition排序后,按轮询方式分配给消费者
    • 优点:分配更均衡;缺点:当消费者订阅不同Topic时可能不够灵活
  3. Sticky(粘性分配)

    • 尽量保持现有分配不变,仅在必要时进行最小调整
    • 优点:减少重平衡时的分配变化,降低开销;缺点:实现复杂
  4. CooperativeSticky(协作粘性分配)

    • 是Sticky策略的改进版,支持增量重平衡
    • 不需要暂停所有消费者,提高重平衡效率

示例:配置消费者分配策略

Properties props = new Properties();
// 其他配置...

// 设置分配策略,可指定多个,按优先级尝试
props.put("partition.assignment.strategy", 
    "org.apache.kafka.clients.consumer.StickyAssignor");

// 或者使用轮询策略
// props.put("partition.assignment.strategy", 
//     "org.apache.kafka.clients.consumer.RoundRobinAssignor");

20. 消费者重平衡(Rebalance)是什么?触发重平衡的场景有哪些?

消费者重平衡(Rebalance) 是指消费者组内重新分配Partition与消费者之间映射关系的过程。当组内消费者数量或订阅的Topic分区数量发生变化时,会触发重平衡,以确保Partition被均匀分配。

触发重平衡的主要场景

  1. 消费者加入组

    • 新的消费者启动并加入已有的消费者组
    • 例如:为提高处理能力,增加新的消费者实例
  2. 消费者离开组

    • 消费者主动关闭(正常退出)
    • 消费者崩溃或网络故障导致与协调器失联(超过session.timeout.ms)
  3. 订阅的Topic发生变化

    • 消费者组订阅了新的Topic
    • 已订阅的Topic被删除
  4. Topic的分区数量发生变化

    • 管理员为已订阅的Topic增加了分区数量
    • 注意:Kafka不支持减少分区数量
  5. 消费者长时间未发送心跳

    • 消费者处理消息时间过长,超过max.poll.interval.ms
    • 协调器认为消费者已失效,将其移出组并触发重平衡

示例:重平衡相关配置

Properties props = new Properties();
// 其他配置...

// 消费者会话超时时间,默认10秒
props.put("session.timeout.ms", "10000");

// 两次poll之间的最大间隔,默认5分钟
props.put("max.poll.interval.ms", "300000");

// 每次poll请求获取的最大记录数
props.put("max.poll.records", "500");

21. 重平衡会带来什么问题?如何避免或减轻其影响?

重平衡带来的问题

  1. 消费暂停

    • 重平衡期间,所有消费者停止消费消息
    • 导致消息处理延迟增加,可能影响业务
  2. 重复消费

    • 重平衡后,消费者可能处理之前已处理过的消息
    • 尤其在未及时提交偏移量的情况下
  3. 负载不均

    • 重平衡后可能出现分区分配不均的情况
    • 导致部分消费者负载过重,部分空闲
  4. 系统开销增大

    • 重平衡过程需要协调多个组件通信
    • 频繁重平衡会消耗大量集群资源

避免或减轻影响的方法

  1. 减少重平衡频率

    • 合理设置session.timeout.ms和heartbeat.interval.ms
    • 确保消费者能及时发送心跳,避免被误判为失效
  2. 优化重平衡性能

    • 使用Sticky或CooperativeSticky分配策略
    • 控制消费者组大小,避免过大的消费者组
  3. 处理重复消费

    • 实现消息处理的幂等性
    • 及时提交消费偏移量
  4. 平滑扩展

    • 避免频繁增减消费者实例
    • 扩展时一次增加足够数量的消费者

示例:优化重平衡配置

Properties props = new Properties();
// 其他配置...

// 心跳间隔,应小于session.timeout.ms的1/3
props.put("heartbeat.interval.ms", "3000");

// 会话超时时间,根据业务处理时间设置
props.put("session.timeout.ms", "10000");

// 使用协作粘性分配策略,支持增量重平衡
props.put("partition.assignment.strategy", 
    "org.apache.kafka.clients.consumer.CooperativeStickyAssignor");

// 自动提交偏移量的间隔
props.put("auto.commit.interval.ms", "5000");

22. Kafka的消息是如何被持久化的?

Kafka采用磁盘存储的方式持久化消息,通过一系列优化机制实现了高性能的持久化操作:

  1. 日志文件结构

    • 每个Partition对应一个日志目录,包含多个日志片段(Segment)
    • 每个Segment由一个数据文件(.log)和一个索引文件(.index)组成
    • 数据文件存储实际消息,索引文件存储消息偏移量与物理位置的映射
  2. 写入机制

    • 消息被追加到当前活跃Segment的末尾(顺序写)
    • 先写入操作系统的页缓存(Page Cache),再异步刷盘
    • 支持配置刷盘策略(如按时间或消息数量)
  3. 刷盘策略

    • 可配置log.flush.interval.messages(按消息数)
    • 可配置log.flush.interval.ms(按时间)
    • 默认依赖操作系统的刷盘机制,平衡性能和可靠性
  4. 日志保留策略

    • 按时间保留:log.retention.hours(默认168小时/7天)
    • 按大小保留:log.retention.bytes
    • 超过保留期限的Segment会被后台线程删除或压缩
  5. 零拷贝技术

    • 读取消息时使用零拷贝(mmap + sendfile)技术
    • 避免用户态和内核态之间的数据拷贝,提高读取性能

示例:配置消息持久化相关参数(server.properties)

# 消息保留时间,默认7天
log.retention.hours=168

# 每个分区的最大保留字节数,默认-1(无限制)
log.retention.bytes=-1

# 每个Segment文件的最大大小,默认1GB
log.segment.bytes=1073741824

# 检查日志是否需要清理的间隔时间
log.retention.check.interval.ms=300000

# 刷盘策略:每500条消息刷盘
log.flush.interval.messages=500

# 刷盘策略:每5秒刷盘
log.flush.interval.ms=5000

Kafka的持久化设计兼顾了性能和可靠性,通过顺序写入、页缓存、零拷贝等技术,即使使用磁盘存储也能实现高性能的消息处理。

二、100道Kafka 面试题目录列表

文章序号 Kafka 100道
1 Kafka面试题及详细答案100道(01-10)
2 Kafka面试题及详细答案100道(11-22)
3 Kafka面试题及详细答案100道(23-35)
4 Kafka面试题及详细答案100道(36-50)
5 Kafka面试题及详细答案100道(51-65)
6 Kafka面试题及详细答案100道(66-80)
7 Kafka面试题及详细答案100道(81-90)
8 Kafka面试题及详细答案100道(91-95)
9 Kafka面试题及详细答案100道(96-100)

网站公告

今日签到

点亮在社区的每一天
去签到