一、基础概念类
问题:请简述 Kafka 是什么,以及它的主要应用场景有哪些?
答案:Kafka 是一个分布式流处理平台,它以高吞吐量、可持久化、可水平扩展等特性而闻名。其主要应用场景包括:
日志收集:可以收集和聚合来自不同来源的日志数据,方便进行集中存储和分析。
消息队列:作为异步消息传递系统,解耦生产者和消费者,提高系统的可扩展性和响应性能。
实时流处理:实时处理如金融交易数据、物联网设备产生的数据等,进行实时分析和决策。
问题:Kafka 中的主题(Topic)、分区(Partition)和副本(Replica)分别是什么含义,它们之间有什么关系?
答案:
主题(Topic):是消息的逻辑分类,生产者发送消息到特定主题,消费者从主题中订阅消息。
分区(Partition):每个主题可以被划分为多个分区,分区是物理存储单元,消息以追加的方式存储在分区中。分区可以分布在不同的 Broker 上,实现并行处理和水平扩展。
副本(Replica):为了保证数据的可靠性,每个分区可以有多个副本。其中一个副本是领导者(Leader)副本,负责处理读写请求,其他副本是追随者(Follower)副本,它们从领导者副本同步数据。当领导者副本出现故障时,追随者副本中的一个会被选举为新的领导者副本。
关系:一个主题包含一个或多个分区,每个分区有零个或多个副本。
生产者与消费者类
问题:Kafka 生产者如何保证消息的可靠性发送?
答案:
设置合适的 acks 参数:acks = 0 时,生产者发送消息后不等待任何确认,速度快但可能丢失消息;acks = 1 时,生产者等待领导者副本确认,若领导者副本确认前崩溃,消息可能丢失;acks = all 时,生产者等待所有同步副本确认,确保消息不会丢失,但性能相对较低。
重试机制:生产者发送消息失败时,通过配置 retries 参数设置重试次数,避免因网络等瞬时故障导致消息发送失败。
幂等性:从 Kafka 0.11.0.0 版本开始,生产者支持幂等性,通过设置 enable.idempotence 为 true,保证即使在重试的情况下,相同消息也只会被成功写入 Kafka 一次,避免重复消息。
问题:Kafka 消费者如何实现精准一次消费(Exactly Once)?
答案:
从生产者角度:利用生产者的幂等性和事务特性。生产者开启幂等性(enable.idempotence = true),对于跨分区的事务,通过事务 API(如 initTransactions、beginTransaction、sendOffsetsToTransaction 等方法)确保一批消息要么全部成功写入 Kafka,要么全部失败。
从消费者角度:通过设置 enable.auto.commit = false,关闭自动提交消费偏移量。消费者在处理完消息后,手动提交偏移量,并且将偏移量提交操作包含在事务中,确保消息处理和偏移量提交的原子性。这样当消费者重启后,不会重复消费已经处理过的消息,从而实现精准一次消费。
集群与架构类
问题:Kafka 集群中 Zookeeper 的作用是什么?
答案:
集群管理:存储 Kafka 集群的元数据信息,如主题、分区、Broker 等信息,帮助 Kafka 集群中的节点了解整个集群的状态。
领导者选举:在 Kafka 集群中,当某个分区的领导者副本出现故障时,Zookeeper 协助选举出新的领导者副本。它通过临时节点和 Watch 机制来监测 Broker 和分区的状态变化,触发选举流程。
Broker 注册:Kafka Broker 在启动时会在 Zookeeper 中注册自己,并且定期发送心跳信息保持连接,Zookeeper 根据这些信息来判断 Broker 的存活状态。
问题:Kafka 集群是如何实现水平扩展的?
答案:
添加 Broker:在已有的 Kafka 集群中,通过增加新的 Broker 节点来扩展集群的处理能力。新的 Broker 启动后会向 Zookeeper 注册自己,集群中的其他节点会感知到新节点的加入。
重新分配分区:使用 Kafka 提供的工具(如 kafka-reassign-partitions.sh),可以将现有主题的分区重新分配到新加入的 Broker 上。通过合理地分配分区,使得集群的负载更加均衡,提高整体的处理能力。例如,对于一个有大量读写操作的主题,可以将部分分区迁移到新的 Broker 上,减轻原有 Broker 的压力。
生产者和消费者的自动感知:生产者和消费者在与 Kafka 集群交互时,能够自动感知到集群的变化。当新的 Broker 加入或分区重新分配后,生产者可以将消息发送到新的分区,消费者也能从新的分区拉取消息,无需手动修改配置,从而实现无缝的水平扩展。