2024年大数据最新大数据面试题 —— Kafka,2024年最新实战分析

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

(2)对于 Kafka 集群的好处是可以实现负载均衡

生产者分区策略

分区的原因

  • 方便在集群中扩展,每个 Partition 可以通过调整以适应它所在的机器,而一个 topic又可以有多个Partition组成,因此整个集群就可以适应任意大小的数据了;
  • 可以 提高并发,因为可以以 Partition 为单位读写了。(分区也是 Kafka 高效读写数据的主要原因)

(1)既没有 partition 值又没有 key 值的情况下, kafka 采用 Sticky Partition(黏性分区器),会随机选择一个分区,并 尽可能一直使用该分区,待该分区达到了batchsize大小或者默认发送的时间,kafka 再随机一个分区进行使用,只要与上一个分区不同即可。

(2)没有指明 partition 值但有 key 的情况下,将 keyhash 值与 topicpartition 数进行取余得到 partition 值;

(3)指明 partition 的情况下,直接将指明的值直接作为 partiton 值;

(4)自定义分区器:实现 Partitioner 接口,重写 partition 方法

Kafka分区分配的概念?

一个 consumer group 中有多个 consumer,一个 topic 有多个 partition,所以必然会涉及到 partition 的分配问题,即确定那个 partition 由哪个 consumer 来消费

消费者分区分配策略

Kafka 有三种分配策略,Range(范围分区) ,RoundRobin(轮询分区),Sticky(粘性分区)。

  • Range:(针对每个 topic 而言的)首先对同一个 topic 里面的分区按照序号进行排序,并对消费者按照字母顺序进行排序,然后用分区数除以消费者数,得到每个消费者消费几个 partition,然后按分区顺序连续分配若干 partition,除不尽的话前面几个消费者会多分配一个分区的数据。
    • 问题:如果只是针对 1个 topic,消费者 0 多消费一个分区影响不大;但是如果有 N个 topic,那么消费者 0 就会多消费 N 个分区,那么就容易发生数据倾斜。(该分配策略适用于topic少的情况)
    • 再平衡:挂掉了一个消费者之后,45 秒以内重新发送消息,此时剩余的消费者暂时不能消费到挂掉的消费者应该消费的分区,等到了45 秒以后,消费者就真正的挂掉了,此时会把它应该消费的分区数都分配给某个消费者
  • RoundRobin:(针对所有 topic) 首先将所有 partition 和 consumer 都列出来,然后按照 hashcode 排序,最后通过轮询算法来分配 partition 给到各个消费者。
    • 再平衡:进行轮询
  • Sticky:尽量均匀的分配分区给消费者(随机),黏性体现在在执行新的分配之前,考虑上一次的分配结果,尽量少的变动,这样就可以节省大量的开销。
    • 再平衡:均匀分配

Kafka 分区数可以增加或减少吗

我们可以使用 bin/kafka-topics.sh 命令对 Kafka 增加 Kafka 的分区数据,但是 Kafka 不支持减少分区数。

Kafka 分区数据不支持减少是由很多原因的,比如减少的分区其数据放到哪里去?是删除,还是保留?删除的话,那么这些没消费的消息不就丢了。如果保留这些消息如何放到其他分区里面?追加到其他分区后面的话那么就破坏了 Kafka 单个分区的有序性。如果要保证删除分区数据插入到其他分区保证有序性,那么实现起来逻辑就会非常复杂。

kafka 如果有台机器挂掉会发生什么

(1)follower故障

follower发生故障后会被临时踢出ISR,待该follower恢复后,follower会读取本地磁盘记录的上次的HW,并将log文件高于HW的部分截取掉,从HW开始向leader进行同步。等该follower的LEO大于等于该Partition的HW,即follower追上leader之后,就可以重新加入ISR了。

(2)leader故障

leader发生故障之后,会从ISR中选出一个新的leader,之后,为保证多个副本之间的数据一致性,其余的follower会先将各自的log文件高于HW的部分截掉,然后从新的leader同步数据。

Kafka在哪些地方会有选举过程,使用什么工具支持选举?

在这里插入图片描述

Kafka中Producer,Broker,Cousumer的关系

一条消息从生产到消费,可以划分三个阶段:

  • 生产阶段:Producer 创建消息,并通过网络发送给 Broker。
  • 存储阶段:Broker 收到消息并存储,如果是集群,还要同步副本给其他 Broker。
  • 消费阶段:Consumer 向 Broker 请求消息,Broker 通过网络传输给 Consumer。

Kafka 怎么保证数据不丢失 / 可靠性 ***

一条消息从生产到消费,可以划分三个阶段:

  • 生产阶段:Producer 创建消息,并通过网络发送给 Broker。
  • 存储阶段:Broker 收到消息并存储,如果是集群,还要同步副本给其他 Broker。
  • 消费阶段:Consumer 向 Broker 请求消息,Broker 通过网络传输给 Consumer。

这三个阶段都可能丢失数据,所以要保证消息丢失,就需要任意一环都保证可靠。

生产阶段

  • ACK机制
    • ack=0、ack=1 都有丢失数据的风险。
    • ack=all/-1 意味着会等待所有同步副本都收到消息。再结合 min.insync.replicas ,就可以决定在得到确认响应前,至少有多少副本能够收到消息。

存储阶段

  • 每个 broker 中的 partition 我们一般都会设置有 replication (副本),的个数,生产者写入的时候首先根据分区分配策略(有 partition 按 partition,有 key 按 key,都没有轮询)写入到 leader 中,follower(副本) 再跟 leader 同步数据,这样有了备份,也可以保证消息数据的不丢失。

消费阶段

  • 消费者消费数据的时候会不断提交 ofset,就是消费数据的偏移量,以免挂了,下次可以从上次消费结束的位置继续消费。

Kafka解决两个客户端消费数据的问题

在Kafka中,同一个消费者组内的消费者可以共同消费一个或多个分区的数据。这种方式被称为分区分配。Kafka通过负载均衡来实现分区分配,确保一个分区只由一个消费者组内的消费者来消费。如果在同一个消费者组内有多个消费者,每个消费者可以独立地读取分区数据,并且每个分区只会被分配给一个消费者。这样就能够实现分布式消费数据的效果,同时也保证了消费者读取到的数据是有序的。如果一个消费者挂掉了,那么它所消费的分区将会重新分配给其他消费者,确保数据的高可靠性和可用性。

Kafka分区多副本机制?

Kafka为分区引入了多副本(Replica)机制,通过增加副本数量可以提升容灾能力。同一分区的不同副本中保存的是相同消息(在同一时刻,副本之前并非完全一样),副本之间是“一主多从”的关系,其中leader副本负责处理读写请求,follower副本只负责与leader副本的消息同步。副本处于不同的broker中,当leader副本出现故障时,从follower副本中重新选举新的leader副本对外提供服务。Kafka通过多副本机制实现了故障的自动转义,当Kafka集群中某个broker失效时扔然能够保证服务可用。

Kafka数据的一致性如何保证 ***

不论是旧的Leader还是新选举产生的Leader,Consumer都能读到一样的数据,Kafka是通过引入HW(High Water Mark)机制来保证数据一致性。

每个副本都有一个HW和一个LEO,LEO是每个副本最大的 offset,HW 则是所有副本中最小的LEO,即该Partition对外服务的最大 offset。

Kafka一个生产者可以把消息发到多个分区吗?

支持将不同消息发往多个分区,但是同一消息只能发往某一分区。

Kafka集群为什么挂掉一个broker后还能工作

Kafka使用了副本机制,每个分区的数据会被复制到多个broker上,即使某个broker挂掉,其他broker上的副本也能继续服务,确保了整个集群的可用性。

Kafka设置ack=-1时一定会保证消息不丢失吗

与ack=1或0相比,当其他环境相同的情况下,ack设置为-1/all可以达到最强的可靠性,但这并不意味这消息就一定可靠,因为ISR中可能只有Leader副本,这就成了ack=1的情况,所有此时是不安全。

Kafka的Broker端提供了一个参数min.insync.replicas,该参数控制的是消息至少被写入到多少个副本才算是"真正写入",该值默认值为1,生产环境设定为一个大于1的值可以提升消息的持久性,因为如果同步副本的数量低于该配置值,则生产者会收到错误响应,从而确保消息不丢失。

所以想要获得更高的可靠性,需要配合min.insync.replicas等参数的联动,才能尽量保证消息不丢失。

Kafka Follower如何与Leader同步数据

为保证producer发送的数据,能可靠的发送到指定的topic,topic的每个partition收到producer发送的数据后,都需要向producer发送ack,如果producer收到ack,就会进行下一轮的发送,否则重新发送数据。

Kafka日志保存时间

默认7天

Kafka单条日志的传输大小

默认为单条消息最大值是 1M,但是在我们应用场景中,常常会出现一条消息大于 1M 的情况,如果不对 kafka 进行配置,则会出现生产者无法将消息推送到 kafka 中或消费者消费不到 kafka 里面的数据的情况。我们可以配置两个参数:一个是副本的最大值,一个是单条消息的最大值,来解决消息最大限制的问题。

  • message.max.bytes=1M:这个参数用来设置单条消息的最大大小
  • replica.fetch.max.bytes=1M:这个参数用来设置副本同步单条消息的最大大小

Kafka消息的消费方式?

Pull 模式。又针对该模式的缺点提出了 timeout 机制

(1)push模式:以消费者最低的消费速率来推送

  • 缺点:可能会造成资源的浪费
  • 优点:每次推送一定是有新消息的
    (2)pull模式:消费者主动拉取消息,拉取时是不知道有没有新消息的
  • 缺点:如果Kafka没有数据,消费者可能会陷入循环中,一直返回空数据
  • 优点:可以根据消费者的消费能力以适应当前的速率消费消息。

Kafka消息存储机制

kafka 中的消息就是 topic,topic 只是逻辑上的概念,而 partition 才是物理上的概念,每个 partition 对应一个 log 文件,它存储的就是 producer 生产的数据。生产者生产的数据会不断追加到 log 文件中,如果 log 文件很大了,就会导致定位数据变慢。因此 kafka 采取了分片和索引的·机制,将大的 log 文件分为多个 segment,每个 segment 会对应.log 文件和.index 文件和.timeindex 文件,.log 存储数据,.index 存储偏移量索引信息,.timeindex 存储时间戳索引信息。

  • .index 为稀疏索引,大约每往 log 文件写入 4kb 数据,会往 index 文件写入一条索引。
  • Index 文件中保存的 offset 为相对 offset,这样能确保 offset 的值所占空间不会过大

Kafka 的 ISR、OSR 和 AR

ISR(InSyncRepli):内部副本同步队列;
OSR(OutSyncRepli):外部副本同步队列;
AR(AllRepli):所有副本,AR = ISR + OSR;

任意一个超过延迟时间阈值的 follower 都会被剔除出 ISR,存入 OSR 列表,新加入的 follower 也会先存放在OSR中。

说下 Kafka 的 ISR 机制

为避免因某个副本的 follower 故障不能同步数据而造成 leader 一直等待,leader 维护了一个列表,为保持同 leader 同步的 follower 集合,该集合中副本和 leader 相差数据不超过一个阈值(可设置),超出一定时间数据未达到该阈值,则 follower 会被踢出 ISR。ISR 主要在 leader 出现故障后作为选举新 leader 的备用池。

Kafka 的 ack 有几种值 / ack 机制

Kafka为用户提供了三种可靠性级别,用户根据对可靠性和延迟的要求进行权衡,选择以下的 acks 参数配置:

  • 0:这一操作提供了一个最低的延迟,partition的 leader 接收到消息还没有写入磁盘就已经返回 ack,当 leader 故障时有可能丢失数据;
  • 1: partition的 leader 落盘成功后返回ack,如果在follower同步成功之前 leader 故障,那么将会丢失数据;
  • -1(all): partition 的 leader 和 follower 全部落盘成功后才返回 ack。但是如果broker发送 ack 之前,leader 发生故障,那么会造成数据重复。

Kafka的 offset 管理

Kafka 0.9 版本之前,consumer 默认将 offset 保存在 Zookeeper 中,从 0.9 版本开始,consumer 默认将 offset 保存在 Kafka 一个内置的 topic 中,该 topic 为__consumer_offsets

消费者提交消费位移时提交的是当前消费到的最新消息的offset还是offset+1?

offset+1

如果有一条offset对应的数据,消费完成之后,手动提交失败,如何处理?

可以给offset提交设置失败后重复提交,如果依旧提交失败,就要进行人工干预了

Kafka为什么同一个消费者组的消费者不能消费相同的分区?

因为这样可能会消费到重复的消息,因为 kafka 的 log 文件对应的数据都会存储自己的偏移量,而它是按照消费者组,主题,分区来进行区分的,那么同一个消费者组中的消费者使用的就是同一份偏移量,这样就很容易消费到重复的消息。

kafka的offset不是为单个消费者存的,是为消费者组存的。

正在消费一条数据,Kafka挂了,重启以后,消费的offset是哪一个

当Kafka服务器挂掉时,消费者正在消费的offset会保存在消费者所在的客户端内存中,并且会定期定时地将消费的offset提交到Kafka集群中。如果此时Kafka服务器挂掉,那么消费者无法将消费的offset提交到Kafka集群中,此时消费者的offset并没有被记录到Kafka集群中,也就是说,在Kafka服务器重启后,消费者的offset会被重置到上一次提交的offset位置,而不是当前正在消费的offset位置。

为什么需要消费者组

消费者组的好处:

  • 消费效率更高
  • 消费模式灵活
  • 便于故障容灾

有哪些情形会造成重复消费

消费者消费后没有提交offset(程序崩溃/强行kill/消费耗时/自动提交偏移情况下unsubscrible)。

有哪些情形会造成消息漏消费

消费者没有处理完消息就提交offset(自动提交偏移 未处理情况下程序异常结束)。

当你使用kafka-topics.sh创建(删除)了一个topic之后,Kafka背后会执行什么逻辑?

创建

(1)会在zookeeper中的/brokers/topics节点下创建一个新的topic节点,如:/brokers/topics/first
(2)触发Controller的监听程序
(3)kafka Controller 负责topic的创建工作,并更新metadata cache

删除

调用脚本删除topic会在zk上将topic设置待删除标志,kafka后台有定时的线程会扫描所有需要删除的topic进行删除,也可以设置一个配置server.properties的delete.topic.enable=true直接删除

Kafka读取消息 Pull 模式的优缺点

优点:灵活控制消费速率;批量拉取提高效率。

缺点:需要消费者不断进行主动拉取,会增加网络负担;消费者长时间不拉取或拉取速度过慢情况下,可能导致信息阻塞;如果kafka没有数据,消费者可能会陷入循环中,一直返回空数据。

Kafka的消费者组是如何消费数据的

(1)一个消费者组有n个消费者
(2)一个消费者组内,一个分区只能由一个消费者消费
(3)一个消费者组,所有消费者组合起来消费一个Topic下所有分区
(4)一个消费者组内,一个消费者可消费多个分区
(5)分区通过分配算法分配给一个组内的消费者,消费者消费时会有一个offset来保存自己的消费位置

Kafka 消费者是否可以消费指定分区消息

Kafa consumer消费消息时,向broker发出fetch请求去消费特定分区的消息,consumer指定消息在日志中的偏移量(offset),就可以消费从这个位置开始的消息,customer拥有了offset的控制权,可以向后回滚去重新消费之前的消息。

Kafka 零拷贝技术

传统数据文件拷贝过程传统的数据文件拷贝过程如下图所示,大概可以分成四个过程:

  • 操作系统将数据从磁盘中加载到内核空间的Read Buffer(页缓存区)中。
  • 应用程序将Read Buffer中的数据拷贝到应用空间的应用缓冲区中。
  • 应用程序将应用缓冲区的数据拷贝到内核的Socket Buffer中。
  • 操作系统将数据从Socket Buffer中发送到网卡,通过网卡发送给数据接收方。

在这里插入图片描述

通过上图可以发现,传统的数据文件传输需要多次在用户态和核心态之间进行切换,并且需要把数据在用户太和和核心态之间拷贝多次,最终才打到网卡,传输给接收方。

所谓的零拷贝是指将数据在内核空间直接从磁盘文件复制到网卡中,而不需要经由用户态的应用程序之手。这样既可以提高数据读取的性能,也能减少核心态和用户态之间的上下文切换,提高数据传输效率。

  • 操作系统将数据从磁盘中加载到内核空间的Read Buffer(页缓存区)中。
  • 操作系统直接将数据从内核空间的Read Buffer(页缓存区)传输到网卡中,并通过网卡将数据发送给接收方。
  • 操作系统将数据的描述符拷贝到Socket Buffer中。Socket 缓存中仅仅会拷贝一个描述符过去,不会拷贝数据到 Socket 缓存。

Kafka数据零拷贝的过程如下图所示:

在这里插入图片描述

通过零拷贝技术,就不需要把内核空间页缓存里的数据拷贝到应用层缓存,再从应用层缓存拷贝到 Socket 缓存了,两次拷贝都省略了,所以叫做零拷贝。这个过程大大的提升了数据消费时读取文件数据的性能。Kafka 从磁盘读数据的时候,会先看看内核空间的页缓存中是否有,如果有的话,直接通过网关发送出去。

Kafka在生产者和消费者两个阶段都使用了零拷贝技术。

kafka服务器默认能接收的最大消息是多少

1M

在这里插入图片描述

Kafka新建的分区会在哪个目录下创建

在启动 Kafka 集群之前,我们需要配置好 log.dirs 参数,其值是 Kafka 数据的存放目录,这个参数可以配置多个目录,目录之间使用逗号分隔,通常这些目录是分布在不同的磁盘上用于提高读写性能。

如果 log.dirs 参数只配置了一个目录,那么分配到各个 Broker 上的分区肯定只能在这个目录下创建文件夹用于存放数据。

如果 log.dirs 参数配置了多个目录,Kafka 会在含有分区目录最少的文件夹中创建新的分区目录,分区目录名为 Topic名+分区ID。

数据传输的事务有几种

数据传输的事务定义通常有以下三种级别:

  • 最多一次(At Most Once):消息不会被重复发送,最多被传输一次,但也有可能一次不传输
  • 最少一次(At Least Once ):消息不会被漏发送,最少被传输一次,但也有可能被重复传输
  • 精确的一次(Exactly once):不会漏传输也不会重复传输,每个消息都传输被接收

Kafka中的分区器、序列化器、拦截器是否了解?它们之间的处理顺序是什么?

  • 拦截器:用来在消息发送前做一些准备工作,如过滤,修改,定制化。
  • 序列化器:将key和value序列化成字节数组,以便进行网络传输。
  • 分区器:如果制定了partition字段,就不需要分区器作用;默认调用两个方法,partition(~)方法,参数分别表示主题、键、序列化后的键、值、序列化后的值以及集群的元数据信息,返回值为分区号;close()方法,关闭分区器并回收一些资源。

拦截器 —> 序列化器 —> 分区器

Kafka生产者客户端的整体结构是什么样子的?使用了几个线程来处理?分别是什么?

在消息发送的过程中,涉及到了两个线程—— main线程Sender线程,以及一个线程共享变量——RecordAccumulator。main线程将消息发送给RecordAccumulator,Sender线程不断从RecordAccumulator中拉取消息发送到Kafka broker。

“消费组中的消费者个数如果超过topic的分区,那么就会有消费者消费不到数据”这句话是否正确?

正确。

失效副本是指什么?有那些应对措施?

不能及时与leader同步,暂时踢出ISR,等其追上leader之后再重新加入

kafka 有几种数据保留的策略?

kafka 有两种数据保存策略:基于过期时间和基于存储的消息大小。

聊一聊Kafka Controller的作用?

Kafka 集群中有一个 broker 会被选举为 Controller,负责管理集群 broker 的上下线,所有 topic 的分区副本分配leader 选举等工作。

Controller的信息同步工作是依赖于Zookeeper的。

如果我指定了一个offset,Kafka Controller 怎么查找到对应的消息?

简述Kafka的日志目录结构?

每个分区对应一个文件夹,该文件夹的命名规则为:topic名称+分区序号。Kafka 采取了 分片索引 机制,将每个 partition 分为多个 segment。每个segment 对应两个文件——.index文件和.log文件。

kafka中的 zookeeper 起到什么作用,可以不用zookeeper么

(1)记录有哪些 broker 服务器

(2)记录谁是 leader 以及哪些服务器可用

(3)选举 controller,Kafka 集群中有一个 broker 会被选举为 Controller,负责管
理集群 broker 的上下线,所有 topic 的分区副本分配和 leader 选举等工作

(4)记录消费数据的 offset,在消费者消费数据的时候,需要定时的将分区消息
的消费进度 offset 记录到 zookeeper 中(kafka0.9 版本之前)

kafka 不能脱离 zookeeper 单独使用,因为 kafka 使用 zookeeper 管理和协调 kafka 的节点服务器。

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

(3)选举 controller,Kafka 集群中有一个 broker 会被选举为 Controller,负责管
理集群 broker 的上下线,所有 topic 的分区副本分配和 leader 选举等工作

(4)记录消费数据的 offset,在消费者消费数据的时候,需要定时的将分区消息
的消费进度 offset 记录到 zookeeper 中(kafka0.9 版本之前)

kafka 不能脱离 zookeeper 单独使用,因为 kafka 使用 zookeeper 管理和协调 kafka 的节点服务器。

[外链图片转存中…(img-fGpVFl2v-1714886730902)]
[外链图片转存中…(img-YvnO7tGG-1714886730902)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 30
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值