大数据面试(Kafka面试真题)
- 1、Kafka分区容错性?
- 2、Kafka的IOSR和ACK介绍,ACK分别有几种值?
- 3、Kafka的工作原理?
- 4、Kafka如何保证全局有序?
- 5、Kafka为什么同一个消费者组的消费者不能消费相同的分区?
- 6、Kafka支持什么语义,怎么实现ExactlyOnce?
- 7、为什么需要消费者组?
- [8、Kafka producer的写入数据过程?](#8、Kafka producer的写入数据过程?)
- 9、Kafka读取消息是推还是拉的模式?有什么好?
- 10、说下Kafka中的Partition?
1、Kafka分区容错性?
- 副本机制 :Kafka允许创建多个分区的副本,并将这些副本分布在不同的Broker上。每个分区都有一个领导副本和若干个追随者副本。领导副本负责处理读写请求,而追随者副本则被用于数据冗余和故障转移。如果领导副本宕机,Kafka会自动从追随者副本中选举出新的领导副本,从而保证数据的可用性和持久性。
- 数据复制 :Kafka适用异步复制机制来保证数据的可靠性。当消息被写入到领导副本时,Kafka会将其异步复制到追随者副本。只有当消息被成功复制到所有的副本后,写入操作才会被认为是完成的。这种机制可以避免数据丢失,并提高系统的吞吐量。
- ISR机制 :Kafka适用ISR(同步复制副本)机制来保证副本之间的一致性。只要处于ISR集合中的副本才被认为是处于同步状态,可以成为新的领导副本。如果某个副本无法及时复制消息或者落后于其它副本太多,它将被从ISR集合中移除,直到追赶上其它副本的进度。这种机制可以防止由于副本之间的不一致导致的数据丢失问题。
- 故障转移 :当某个Broker宕机或者分区的领导副本不可用时,Kafka会自动进行故障转移。它会从ISR集合中选择一个新的副本作为领导副本,并自动将客户端的消费者重定向到新的副本上。这种机制使得Kafka在面对故障时能够快速恢复,并保持高可用性。
2、Kafka的IOSR和ACK介绍,ACK分别有几种值?
OSR :是指Out-of-Sync Replicas,是指与leader副本失去同步的副本集合。当ISR中的副本失去与leader副本的同步,它们将被移动到OSR中,直到重新与leader副本同步。
ACK:是指Ackowledgement,用于控制生产者发送消息时的可靠性和性能。ACK有三个可选值:
- ACK=0 :生产者不等待任何确认,将消息发送到Kafka后即认为发送成功,适用于对可靠性要求不高的场景。
- ACK=1 :生产者等待leader副本成功写入消息后即认为发送成功,适用于对可靠性要求较高的场景。
- ACK=all :生产者等待ISR中所有副本成功写入消息后即认为发送成功,适用于对数据不可丢失的高可靠性要求场景。
3、Kafka的工作原理?
- 消息发布和订阅:Kafka通过主题(topic)来组织消息,生产者将消息发布到指定的主题,而消费者则订阅一个或多个主题来消费消息。
- 分区和复制:每个主题可以被划分为多个分区(partition),每个分区都是有序的消息日志。分区的目的是实现可伸缩性和并行处理。每个分区可以有多个副本(replica),用于提供数据的冗余和容错性。
- 持久化和顺序写:Kafka使用顺序写磁盘的方式来持久化消息,这样可以提高写入性能。消息被写入到分区的末尾,并根据其在分区的偏移量进行唯一标识。
- 消费者组:消费者可以以消费者组的形式进行协调消费。同一个消费者组中的消费者共同消费一个主题的所有分区,每个分区只能由一个消费者消费。这样可以实现负载均衡和容错性。
- 批量拉取和零拷贝 :Kafka的消费者可以批量拉取消息,减少网络传输开销。同时,Kafka还是用零拷贝技术,将消息从磁盘读取到内存,再通过网络发送给消费者,避免了数据的多次拷贝。
零拷贝技术:当消息从Kafka的日志文件发送到消费者时,Kafka利用零拷贝技术直接从文件系统缓存将数据传输到网络套接字,避免了将数据从内核空间拷贝到用户空间再拷贝回内核空间的过程。 - 消息保留和清理:Kafka可以根据时间或者大小来配置消息的保留策略。过期的消息会被自动清理,释放磁盘空间。
4、Kafka如何保证全局有序?
Kafka通过分区和分区内的顺序保证全局有序。
具体来说,Kafka将数据分为多个主题(topics),每个主题可以分为多个分区(partitions)。每个分区都有一个唯一的标识符,并且在Kafka集群中的多个节点上进行复制以提供高可用性。
在每个分区内,Kafka使用偏移量(offset)来标识消息的顺序。生产者将消息写入特定的分区时,Kafka会为每个消息分配一个递增的偏移量。消费者可以通过指定分区和偏移量来读取消息,从而保证消费者按照指定顺序处理消息。
如果某个主题只有一个分区,那么该主题的消息顺序是全局有序的。如果一个主题有多个分区,Kafka可以根据消息的键(key)来选择将消费写入哪个分区。这样,具有相同键的消息将被写入同一个分区, 并且同一个分区内的消息顺序是有序的。但是,不同分区之间的消息顺序是无法保证的。
5、Kafka为什么同一个消费者组的消费者不能消费相同的分区?
Kafka中同一个消费者组的消费者不能消费相同的分区,是因为Kafka采用了分布式的消息队列模型,通过将消息分散存储在多个分区中来提高消息的处理能力和可靠性。每个分区只能由同一个消费者组中的一个消费者进行消费,这样可以确保消息的有序性和不重复消费。
6、Kafka支持什么语义,怎么实现ExactlyOnce?
Kafka支持三种消息传递语义:At Most Once、At Least Once和Exactly Once。
要实现Exactly Once语义,Kafka使用了以下两个主要组件:
- 生产者端 :生产者在发送消息之前会生成一个唯一的消息ID,并将其与消息一起发送到Kafka。Kafka会根据消息ID来判断是否是重复的消息。生产者还需要将消息写入事务日志,并在确认写入事务日志后才将消息发送到Kafka。如果写入事务日志失败,则不会发送消息到Kafka。
- 消费者端 :消费者在接收到消息后,会将消息的偏移量和消费者组ID一起提交到Kafka。Kafka会将偏移量和消费者组ID存储在一个特殊的主题中,以便在发生故障时能够恢复消费的状态。消费者还需要将消费的结果写入事务日志,并在确认写入事务日志后才提交偏移量到Kafka。如果写入事务日志失败,则不会提交偏移量。
通过使用事务日志和唯一的消息ID,Kafka可以确保消息在发送和消费过程中的幂等性,并最终实现Exactly Once语义。
7、为什么需要消费者组?
Kafka的消费者是指使用Kafka消费消息的应用程序。消费者组是一组相同group.id的消费者的集合。每个消费者组中的消费者协同工作,以协调消息的消费。
消费者组的存在有以下几个原因:
- 并行处理 :通过将消费者组中的消费者分配到不同的分区上,可以实现消息的并行处理。每个分区只会被同一个消费者组中的一个消费者处理。这样可以提高消息处理的吞吐量。
- 容错性 :消费者组中的消费者可以相互备份,当其中一个消费者出现故障或不可用时,其它消费者可以接管其分区并继续消费。这种容错性能够确保消息的连续性和可靠性。
- 消费者动态扩展 :通过添加更多的消费者到消费者组中,可以实现消费能力的动态扩展。这样可以根据复制的变化动态调整消费者的数量。
8、Kafka producer的写入数据过程?
- 创建ProducerRecord :首先,开发者需要创建一个ProducerRecord对象,该对象包含了要发送的消息的主题、键和值等信息。
- 序列化消息 :ProducerRecord中的键和值需要被序列化为字节数组,以便能够在网络上传输。
- 分区选择 :根据配置的分区策略,Kafka producer会选择一个分区来发送消息。如果开发者没有指定分区,那么会根据键的哈希值选择一个分区。
- 消息发送 :Kafka produer将序列化后的消息发送给选定的分区的Leader副本。
- 消息写入磁盘 :Leader副本将消息写入磁盘,并向producer发送确认消息。
- 消息复制 :Leader副本将消息复制到其它的follower副本,以确保消息的可靠性。
- 消息提交 :当消息被所有的follower副本确认接收后,Leader副本会向producer发送确认消息。
- 异常处理:如果发送过程中发生了错误,比如网络错误或Leader副本失效,Kafka producer会根据配置重试策略进行重试,直到发送成功或达到最大重试次数。
9、Kafka读取消息是推还是拉的模式?有什么好?
Kafka的消息读取是拉模式(pull mode),即消费者主动从Kafka服务器拉取消息。这与推模式(push mode)相反,推模式是服务器将消息直接推送给消费者。
拉模式的好处有以下几点:
- 灵活性:消费者可以根据自身的处理能力和需求决定拉取消息的速率,可以根据实际情况动态调整。
- 节约资源:由于消费者主动拉取消息,可以避免服务器主动推送大量消息给消费者,减少网络带宽和服务资源的消耗。
- 容错性:消费者可以根据需要重新拉取消息,例如在处理过程中出现错误,可以重新拉取相同的消息进行重试。
- 消息积压控制:消费者可以根据自身的处理能力调整拉取消息的速率,避免由于消息过多而导致的消息积压问题。
10、说下Kafka中的Partition?
Kafka中的Partition(分区)是将主题(Topic)划分为多个独立的数据片段的过程。每个Partition是一个有序、不可变的消息序列,其中的消息按照Producer的发送顺序一次追加到Partition中。每个Partition在物理上对应一个独立的日志文件,这个文件被分成多个Segment(段)。
Partition的作用在于:
- 实现消息的水平扩展:Kafka可以在多个Broker上并行处理不同Partition的消息,提高了整个系统的吞吐量。
- 实现数据的持久化:每个Partition都会被复制到多个Broker上,确保数据的可靠性和冗余。
- 实现消息的顺序性:在同一个Partition中,消息的顺序是有序的,保证了消息的有序性处理。
每个Partition都有一个唯一的标识符(Partition ID),并且可以配置多个副本(Replica),其中一个为Leader副本,其它副本为Follower副本。Leader副本负责处理来自Producer和Consumer的请求,Follower副本用于备份和故障转移。
在生产者发送消息时,可以选择指定消息要发送到的Partition,如果没有指定,Kafka会根据某种策略(如Hash值)将消息平均分配到各个Partition中。而在消费者消费消息时,可以订阅一个或多个Partition,每个消费者只会消费其中一个Partition上的消息。