Kafka面试题
在大数据领域,Kafka 作为一个高吞吐量的分布式发布订阅消息系统,被广泛应用于各种场景。以下是一些常见的 Kafka 面试题及解析。
一、如何发送超过 1MB 的文件
在 Kafka 中,默认情况下单个消息的大小被限制在 1MB 以内。如果要发送超过 1MB 的文件,可以通过以下几种方式:
-
调整
message.max.bytes、replica.fetch.max.bytes和fetch.message.max.bytes等参数来增大允许的消息大小。但需要注意的是,过大的消息可能会影响性能和网络传输。 -
将大文件分割成多个较小的消息进行发送,在接收端再进行合并处理。
-
文件压缩,推荐使用
snappy压缩算法进行压缩
二、怎么保证数据的可靠性
-
副本机制:Kafka 通过副本机制来保证数据的可靠性。每个分区可以有多个副本,其中一个为主副本,其他为从副本。当主副本出现故障时,从副本可以被选举为主副本继续提供服务。
-
生产者配置:
- 设置
acks参数为all或-1,表示生产者需要等待所有副本都接收到消息后才认为发送成功。 - 设置
retries参数为一个较大的值,当发送失败时自动重试。
- 设置
-
消费者配置:
-
正确处理消费过程中的异常,避免意外退出导致数据丢失。
-
定期提交偏移量,确保在故障恢复后能够从正确的位置继续消费。
-
三、如何保证幂等性
- 开启生产者的幂等性:在生产者配置中设置
enable.idempotence=true。开启幂等性后,生产者在发送消息时会为每个消息分配一个唯一的序列号,Kafka 会确保相同序列号的消息只被持久化一次。默认3.0之后自动开启幂等机制 - 注意事项:开启幂等性可能会对性能产生一定的影响,并且需要确保生产者的重试机制不会导致重复发送相同序列号的消息。
四、如何保证消息的顺序性
- 单分区:如果要保证消息的严格顺序性,可以将相关的消息发送到同一个分区。在一个分区内,Kafka 保证消息的顺序性。
建议设置KEY,使用按key投递的方式,相同类型的消息发到同一个分区
-
消费者单线程消费:在消费者端,使用单线程进行消费,确保按照消息的顺序进行处理。
-
使用事务消息,可以保证跨分区的顺序性
五、参数优化
-
网络相关参数:
batch.size:控制生产者批量发送消息的大小,适当增大可以提高吞吐量,但也会增加延迟。linger.ms:生产者在发送消息前等待的时间,当等待时间达到该值或者消息数量达到batch.size时,生产者会发送消息。receiver.buffer.bytes和sender.buffer.bytes:分别设置消费者和生产者的网络缓冲区大小。
-
存储相关参数:
log.retention.hours:控制日志的保留时间,可以根据实际需求进行调整。log.segment.bytes:日志分段的大小,影响日志的滚动和清理策略。
-
副本相关参数:
min.insync.replicas:控制写入消息到分区时需要同步的最少副本数量。
-
消息压缩 snappy
compression.type:
- 这个参数用于设置消息的压缩类型。
- 可选值有:
none(不压缩)、gzip、snappy、lz4、zstd。 - 默认值为
producer(即由生产者端的默认配置决定,通常为gzip、snappy或lz4中的一个,具体取决于 Kafka 的版本和配置)。
六、发送消息阻塞的场景
- 网络问题:如果网络出现故障或者拥堵,可能导致发送消息阻塞。
- 服务器负载过高:当 Kafka 服务器负载过高时,可能无法及时处理生产者的请求,导致发送消息阻塞。
- 参数设置不合理:例如
batch.size设置过大,导致生产者长时间等待消息数量达到批量发送的条件。 - pagecache污染,不停从磁盘读到内存中进行交换,可以使用raid
七、kafka 的顺序写是什么
Kafka 的顺序写是指将消息顺序地写入磁盘。与随机写相比,顺序写可以大大提高磁盘的写入性能。Kafka 将消息追加到日志文件的末尾,这种方式可以充分利用磁盘的顺序写入特性,减少磁盘寻道时间,提高写入速度。
八、为什么会出现消息丢失
-
生产者方面:
- 如果
acks设置为0或1,生产者在发送消息后不等待服务器的确认,可能会出现消息丢失的情况。 - 网络故障或服务器故障导致消息发送失败,但生产者没有进行重试。
- 如果
-
消费者方面:
-
消费者在处理消息过程中出现异常,没有正确提交偏移量,导致在故障恢复后重复消费已经处理过的消息,而未处理的消息可能被遗漏。
-
消费者在处理消息前自动提交偏移量,如果在处理消息过程中出现故障,可能会导致消息丢失。
-
九、为什么异步提交不支持重试?
异步提交是指生产者在发送消息后不等待服务器的确认,而是继续发送下一条消息。由于异步提交不等待服务器的确认,所以无法确定消息是否发送成功。如果出现发送失败的情况,无法进行重试,因为生产者不知道哪些消息发送失败了。
十、如何合理地提交 offsets
-
自动提交:可以设置消费者自动提交偏移量,但需要注意自动提交的频率,避免在处理消息过程中出现故障导致重复消费或消息丢失。
-
手动提交:在消费者处理完一批消息后,手动提交偏移量。这样可以确保在处理消息过程中出现故障时,能够从正确的位置继续消费。
-
同步提交和异步提交:手动提交可以选择同步提交或异步提交。同步提交会等待服务器的确认,确保偏移量提交成功,但会影响性能。异步提交不等待服务器的确认,性能较高,但可能会出现提交失败的情况。
十一、rebalance 的优化方式有哪些
-
减少消费者组的变化:尽量避免在运行过程中频繁地添加或删除消费者,因为这会触发 rebalance。
-
合理设置
session.timeout.ms和heartbeat.interval.ms:这两个参数控制消费者与服务器之间的心跳和会话超时时间。设置合理的值可以减少不必要的 rebalance。默认3秒,超时45秒(3.0前是10秒)。调整成心跳15秒。 -
优化消费者的处理逻辑:提高消费者的处理速度,减少处理时间,避免因为消费者处理过慢而触发 rebalance。
-
kafka 2.4之后包含了增量rebalance协议,3.0已经是默认了。只让撤销的分区挂载到新的消费者上,老的不动,可以继续消费 。
十二、如何做到精准一次消费?
-
开启幂等性:确保生产者发送的消息不会被重复处理。
-
手动提交偏移量:在消费者处理完消息后,手动提交偏移量,确保不会重复消费已经处理过的消息。
-
处理消费过程中的异常:正确处理消费过程中的异常,避免因为异常导致消息丢失或重复消费。
十三、消费者消费性能提升方式有哪些?
-
增加消费者数量:可以根据服务器的性能和负载情况,适当增加消费者数量,提高消费速度。
-
调整参数:
- 增大
fetch.min.bytes和fetch.max.wait.ms,让消费者在一次拉取中获取更多的数据,减少拉取次数。 - 调整
max.poll.records,控制每次拉取的消息数量。
- 增大
-
优化消费者的处理逻辑:提高消费者的处理速度,例如使用多线程处理消息。
十四、kafka 能多线程获取数据吗?
可以。可以使用多个消费者线程来同时从 Kafka 中获取数据。但需要注意的是,需要正确处理线程之间的协调和同步问题,避免出现数据重复消费或丢失的情况。
使用Parallel Consumer ,Confulent公司的产品,可以实现多线程消费。
十五、kafka 中 zk 的作用?
-
存储元数据:存储 Kafka 集群的元数据信息,如主题、分区、副本等的分配情况。
-
选举控制器:在 Kafka 集群中,通过 Zookeeper 选举出一个控制器来管理集群的状态变化。
-
监控节点状态:Zookeeper 可以监控 Kafka 节点的状态,当节点出现故障时,触发相应的处理机制。
十六、kraft 算法的原理,以及与 raft 算法的区别
Kafka 的 kraft 算法和通用的 raft 算法有以下一些不同点:
一、设计目的
-
kraft 算法:
- 专门为 Kafka 集群设计,主要用于管理 Kafka 集群的元数据和控制器选举等与 Kafka 特定功能紧密相关的任务。
- 目标是在保证 Kafka 集群高可用和可靠的元数据管理的同时,尽可能与 Kafka 的架构和工作方式无缝集成。
-
raft 算法:
-
是一种通用的分布式一致性算法,旨在为各种分布式系统提供一种可靠的共识机制,保证数据的一致性和高可用性。
-
可以应用于多种不同类型的分布式系统,不限于消息队列领域。
-
二、应用场景
-
kraft 算法:
- 仅在 Kafka 集群环境中使用,重点关注 Kafka 主题、分区、副本等元数据的管理以及控制器的选举和故障转移。
- 与 Kafka 的存储架构和消息传递机制紧密结合,例如在处理分区副本的同步、领导者选举等方面,会考虑 Kafka 特有的数据存储和传输需求。
-
raft 算法:
-
可应用于更广泛的分布式系统场景,如分布式数据库、分布式文件系统等。
-
在不同场景下,需要根据具体系统的需求进行定制和调整,但基本的一致性保证和领导者选举机制是通用的。
-
三、实现细节
-
领导者选举:
- kraft 算法:在 Kafka 中,控制器负责管理整个集群的状态,包括分区的领导者选举。kraft 算法在选举控制器时,会考虑节点的负载、网络延迟等因素,以确保选出的控制器能够高效地管理集群。例如,可能会优先选择负载较低、网络连接较好的节点作为控制器。
- raft 算法:通常基于日志的连续性和节点的可用性进行领导者选举。候选节点通过向其他节点发送请求,获得大多数节点的支持后成为领导者。在选举过程中,主要关注日志的完整性和一致性,以保证新的领导者能够继续推进系统的状态更新。
-
日志复制:
- kraft 算法:Kafka 的日志复制是基于分区的,每个分区都有一个领导者副本和多个追随者副本。kraft 算法会确保领导者副本将消息顺序地写入日志,并将日志同步到追随者副本。在复制过程中,会考虑网络延迟、副本的可用性等因素,以保证消息的可靠传递。
- raft 算法:日志复制通常是基于领导者向追随者发送日志条目,并等待追随者的确认。Raft 算法会确保日志的一致性和顺序性,通过严格的日志复制机制来保证系统的状态更新在各个节点上的一致性。
-
成员变更:
-
kraft 算法:在 Kafka 中,成员变更通常需要通过控制器进行协调。当有新的节点加入或现有节点退出时,控制器会重新分配分区的副本,以保证数据的均衡分布和高可用性。kraft 算法会尽量减少成员变更对集群性能的影响,例如通过逐步的副本重新分配策略,避免一次性大规模的副本迁移。
-
raft 算法:成员变更需要遵循一定的协议,以确保在变更过程中系统的一致性和可用性不受影响。例如,在增加新成员时,需要进行一系列的日志复制和确认操作,以保证新成员能够同步到最新的系统状态。
-
四、性能特点
-
kraft 算法:
- 由于是专门为 Kafka 设计的,可能会针对 Kafka 的工作负载进行优化,例如在处理大规模的消息流和高吞吐量的场景下,可能会有更好的性能表现。
- 与 Kafka 的存储和网络架构紧密结合,能够充分利用 Kafka 的特性,如顺序写入磁盘、零拷贝技术等,提高系统的整体性能。
-
raft 算法:
- 作为通用算法,需要在不同的场景下进行性能调优。在某些特定的场景下,可能需要根据具体的系统需求进行定制化开发,以提高性能。
- 其性能可能会受到通用实现的限制,不一定能完全适应 Kafka 这种高吞吐量的消息队列系统的需求。
以上是对 Kafka 常见面试题的解析,希望对大家有所帮助。在实际应用中,需要根据具体的场景和需求,合理地配置和使用 Kafka,以充分发挥其优势。