Kafka 面试问题

因为暂时只学了这两个,所以对比着记录一下。
来源于尚硅谷B站视频中的问题,因为没有找到官方答案,我将这些问题用自己的语言回答,并把另外看到的一些问题汇总在一起,欢迎指正。

面试问题

Kafka 篇

1. Kafka 中的 ISR(InSyncRepli)、OSR(OutSyncRepli)、AR(AllRepli)代表什么?

ISR 是 Leader 维护了一个动态的 in-sync replica set (同步副本集合),意为和 leader 保持同步的 follower 集合。当 ISR 中的 follower 完成数据的同步之后,就会给 leader 发送 ack (这个不是producer的ack)。如果 follower长时间未向leader发送同步数据请求,则该follower将被踢出ISR,加入OSR,即不同步的副本集合,该时间阈值由replica.lag.time.max.ms参数设定(最大请求时间间隔)。Leader 发生故障之后,就会从 ISR 中选举新的 leader。

0.9 版本之前还有一个机制是 比较 follower 和 leader 的数据,follower 落后太多也移除,但是这样可能会频繁操作 ISR 的进出,也会频繁操作 zk,后面版本就移除了。

OSR中的 follower 如果满足条件,追上了 leader 可以重新进入 ISR。AR 就是所有的 follower,即 AR = ISR + OSR。

2. Kafka中的HW、LEO等分别代表什么?

在这里插入图片描述
我们知道 Kafka 的主从机制,在部分情况下可能会出现不同副本,副本和leader数据不一致的问题

  • LEO:(Log End Offset)每个副本的最后一个offset
  • HW:(High Watermark)高水位,指的是消费者能见到的最大的 offset, ISR 队列中最小的 LEO

3. Kafka 中是怎么体现消息顺序性的?

Topic 中的每个 partition 都是由有序的不可变的记录序列组成,并且消息都是连续的被追加在尾部Kafka 不能保证全局有序性(全局生产顺序和消费顺序一致),只能保证每个 partition 内的有序性

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

对于发送的信息,我们可能需要定制化的处理逻辑。对于producer 而言, interceptor 使得用户在消息发送前onSend()方法,比如 修改消息,增加时间戳)以及 producer 回调逻辑前onAcknowledgement()方法,统计成功发送消息的数目)有机会对消息做一些定制化需求。同时, producer 允许用户指定多个 interceptor按序作用于同一条消息从而形成一个拦截链(interceptor chain)。

我们肯定不能先序列化再修改消息,所以处理顺序是,先拦截器,再序列化器,最后调用分区器对序列化后的消息进行定制化分区

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

Kafka 的 Producer 发送消息采用的是异步发送的方式。在消息发送的过程中,涉及到了两个线程—— main 线程和 Sender 线程,以及一个线程共享变量,或者说缓冲区——RecordAccumulator。 main 线程将消息发送给 RecordAccumulator,这时的数据是已经分好区的, Sender 线程不断从 RecordAccumulator 中拉取消息发送到 Kafka broker。

这个回答太空了,我还没来得及看源码,等看完之后再回过头整理一下。

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

对对对对对,但这种浪费资源的行为尽量避免。

相反当 topic 分区数大于 消费者数,那么一些消费者会承担更多的分区。

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

这个回想:当一个新的 topic 建立时,这个 offset 是 0,现在我们是从 0 开始存数据,而不是 1,所以说是 offset + 1

8. 有哪些情形会造成重复消费和漏消费?数据丢失和数据重复?

注意是 重复消费漏消费,而不是 数据丢失数据重复,前者是 consumer 的问题,后者是 ack 或者说是 producer 的问题。

先说 重复消费 和 漏消费:

  • 如果先处理数据,再提交 offset,处理完之后还没提交就挂掉了,就会重复消费。

  • 相反,如果先提交,再处理,提交完后挂掉了,就会漏掉此次消费。

至于数据丢失和数据重复和acks 参数配置有关:

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

10. topic 的分区数可不可以增加 / 减少?

可增,不可减。

可增的原因是,但是如果有一些分区逻辑的话,尽量在最开始设计好,不要增加,比如我根据key去分区,分区数变化后,相应的key的存储分区位置也会发生变化。

不可减的原因是 原有分区的数据没有合适的处理逻辑。首先肯定不能删除,也不能放到别的分区,因为会干扰单个分区的有序性,有序插入难度太大。

11. Kafka 有内部的 topic 吗?如果有是什么?有什么所用?

__consumer_offsets

kafka在0.10.x版本后默认将消费者组的位移提交到自带的topic __consumer_offsets里面

12. 什么是 Kafka 的分区分配,目的是什么,有什么策略?

Kafka 把一个 topic 分成不同的 partition,同一个 group 中的 consumer 可以消费同一个 topic 但是不能消费同一个 partition,分区分配策略即确定那个 partition 由哪个 consumer 来消费

对于 kafka 集群来说,分区可以做到负载均衡,对于消费者来说,可以提高并发度,提高读取效率

  • round-robin 轮询

    多个 topic时, 将每个Partition和对应的 topic 视为一个整体对象 TopicAndPartition,按照字典序排序,如 t0-0 就是 topic 0 的 第一个 partition。然后分配给 consumer,如果该consumer没有订阅该 topic,就给下一个 consumer。

  • range(默认)

    Range 分配策略,就是首先会计算各个consumer将会承载的分区数量,然后将指定数量的分区分配给该consumer。

13. 简述 Kafka 的日志目录结构,给定一个 offset 如何查到对应的消息?

  • Kafka 是按照 partition 存储数据的,文件夹命名方式是 topicName-partitionIndex,每个 broker 上有 0 或 多个partition。

  • Kafka 采取了分片和索引机制,来避免 log 文件过大导致数据定位效率低下。Kafka 将每个 partition 分为多个 segment

  • 每个 segment 对应两个文件——“.index”文件“.log”文件

  • 我们用 Offset 偏移量定位数据,每个 segment 的文件名是本文件存储的第一个数据对应的 Offset,我们用二分查找法,先定位到消息在哪个 index 文件中,再通过 index 文件找到数据在 log 文件中对应的起始位置和大小,再查找 log 文件可以获得对应的数据。

14. 聊一聊 Kafka Controller 的作用?

controller主要依靠ZK完成对集群broker和分区的管理如集群broker信息、分区选举ISR等。

15. Kafka 中有那些地方需要选举?这些地方的选举策略又有哪些?

  • 选 controller 先到先得

  • leader 挂掉后从 ISR(同步时间间隔,同步条数)中 选 leader

    考虑到集群整体的负载能力的平衡性,会尽量分配每一个 partition 的 leader 在不同的broker中,如果 leader 挂掉了,会按照当前 partition 的 AR 列表顺延到下一个 broker,当然需要这个 broker 在 ISR 中,然后根据设置可能会出发 自动leader自动平衡策略(由broker中server.propertiesauto.leader.rebalance.enable=true设置,默认为true,该策略会根据集群状态重新进行leader选举),但是这样势必会有业务阻塞、频繁超时之类的风险。可以针对此类问题设置相应的告警机制(例如邮件,短信,企业微信等通知方式),在合适的时机由运维进行手动执行的方式进行分区平衡。

    这个摘自 : https://blog.csdn.net/F_Hello_World/article/details/107469906?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-1&spm=1001.2101.3001.4242

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

OSR 中的副本就是失效副本,在同步时间间隔内没有进行同步或者落后太多的副本,等追上后会再加入 ISR

follower副本将leader副本的LEO(Log End Offset,每个分区最后一条消息的位置)之前的日志全部同步时,则认为该follower副本已经追赶上leader副本,此时更新该副本的 lastCaughtUpTimeMs标识。Kafka的副本管理器(ReplicaManager)启动时会启动一个副本过期检测的定时任务,而这个定时任务会定时检查当前时间与副本的lastCaughtUpTimeMs差值是否大于参数replica.lag.time.max.ms指定的值。
摘自:https://blog.csdn.net/u013256816/article/details/78851989

17. Kafka 的哪些设计让它有如此高的性能?

  • Kafka 使用了分布式的技术,使用分区的设计,将一个 Topic(类比 RabbitMQ的 队列)分成了若干分区,提高了读写的并发度,所以效率是提高的

  • Kafka 具有高吞吐量和低延迟,

  • 单台的 Kafka 仍然具有较高的效率

    • 页缓存Page Cache Kafka在写入消息时是直接写入页缓存,然后由操作系统决定什么时候把页缓存里的数据刷入磁盘文件中。这样一来,消息写入性能就变成了写内存,不是在写磁盘。
    • 顺序写磁盘,在磁盘上开辟了一个空间连续写,比随机写减少了大量磁头寻址的时间
    • 零拷贝
      CPU不需要为数据在内存之间的拷贝消耗资源。而它通常是指计算机在网络上发送文件时,不需要将文件内容拷贝到用户空间(User Space)而直接在内核空间(Kernel Space)中传输到网络的方式。
    • 分片索引机制,提高了检索速度。
      https://zhuanlan.zhihu.com/p/258513662

18. Kafka的用途有哪些?使用场景如何?

Kafka 是一个分布式流式处理平台

流平台具有三个关键功能:

  1. 消息队列:发布和订阅消息流,这个功能类似于消息队列,这也是 Kafka 也被归类为消息队列的原因。
  2. 容错的持久方式存储记录消息流: Kafka 会把消息持久化到磁盘,有效避免了消息丢失的风险·。
  3. 流式处理平台: 在消息发布的时候进行处理,Kafka 提供了一个完整的流式处理类库。

Kafka 主要有两大应用场景:

  1. 消息队列 :建立实时流数据管道,以可靠地在系统或应用程序之间获取数据。
  2. 数据处理: 构建实时的流数据处理程序来转换或处理数据流。
  • 用户追踪: 根据用户在web或者app上的操作,将这些操作消息记录到各个topic中,然后消费者通过订阅这些消息做实时的分析,或者记录到HDFS,用于离线分析或数据挖掘
  • 日志收集: 通过 kafka 对各个服务的日志进行收集,再开放给各个consumer
  • 运营指标: 记录运营监控数据,收集操作应用数据的集中反馈,如报错和报告

19. Kafka 的高可靠性是怎么实现的?

主要就是 ISR机制 和 ack应答机制,详细见笔记

  • ISR 机制 将落后太多的从节点踢出,保证如果 leader 挂掉,follower 是可靠的,不会落后太多的。
  • ack 应答机制 通过调整可靠性级别,可以在数据可靠性和延迟上进行权衡
    • 0: producer 不等待 broker 的 ack,这一操作提供了一个最低的延迟, broker 一接收到还没有写入磁盘就已经返回,当 broker 故障时有可能丢失数据
    • 1: producer 等待 broker 的 ack, partition 的 leader 落盘成功后返回 ack,如果在 follower同步成功之前 leader 故障,那么将会丢失数据
    • -1(all) : producer 等待 broker 的 ack, partition 的 leader 和 ISR 的 follower 全部落盘成功后才返回 ack。但是如果在 follower 同步完成后, broker 发送 ack 之前, leader 发生故障,那么会造成数据重复,因为没有收到 ack,生产者会重复发送。

20. Kafka 的副本间数据一致性是怎么实现的?

副本间数据不一致一般发生在故障后,根据 HW(高水位), 我们把故障分为 follower 故障leader 故障 分别解决:

  • follower 故障:follower 发生故障后会被临时踢出 ISR,待该 follower 恢复后, follower 会读取本地磁盘记录的上次的 HW,并将 log 文件高于 HW 的部分截取掉,从 HW 开始向 leader 进行同步。等该 follower 的 LEO 大于等于该 Partition 的 HW,即 follower 追上 leader 之后,就可以重新加入 ISR 了。
  • leader 故障:leader 发生故障之后,会从 ISR 中选出一个新的 leader,之后,为保证多个副本之间的数据一致性, 其余的 follower 会先将各自的 log 文件高于 HW 的部分截掉,然后从新的 leader同步数据。

注意: 这只能保证副本之间的数据一致性,并不能保证数据不丢失或者不重复。

21. Kafka 的精准一次性是怎么实现的?

对于一些非常重要的信息,比如说交易数据,下游数据消费者要求数据既不重复也不丢失,即 Exactly Once 语义。

在 0.11 版本以前的 Kafka,对此是无能为力的,只能保证数据不丢失,再在下游消费者对数据做全局去重。对于多个下游应用的情况,每个都需要单独做全局去重,这就对性能造成了很大影响。

0.11 版本的 Kafka,引入了一项重大特性:幂等性所谓的幂等性就是指 Producer 不论向 Server 发送多少次重复数据, Server 端都只会持久化一条。幂等性结合 At Least Once 语义,就构成了 Kafka 的 Exactly Once 语义。即:

At Least Once + 幂等性 = Exactly Once

要启用幂等性,只需要将 Producer 的参数中 enable.idempotence 设置为 true 即可。 Kafka的幂等性实现其实就是将原来下游需要做的去重放在了数据上游。开启幂等性的 Producer 在初始化的时候会被分配一个 PID,发往同一 Partition 的消息会附带 Sequence Number而 Broker 端会对<PID, Partition, SeqNumber>做缓存,当具有相同主键的消息提交时, Broker 只会持久化一条。

但是 PID 重启就会变化,同时不同的 Partition 也具有不同主键,所以幂等性无法保证跨分区跨会话的 Exactly Once。

但是单个分区,没有挂掉的情况下,可以完成 精准一次性写入

22. 如何解决消费者速率低的问题?

增加分区数和消费者数

23. Kafka 消费者是以 poll / pull 方式获取数据?

用Pull模式。在Pull模式下,consumer可以根据自身速率选择如何拉取数据,避免了低速率的consumer发生崩溃的问题。
但缺点是,consumer要时不时的去询问broker是否有新数据,容易发生死循环,内存溢出

24 Kafka创建Topic时如何将分区放置到不同的Broker中?

随机一个 broker 作为起点,依次往下分配,分区数可以大于 broker 数,但是副本数不能。

25. Kafka中的事务管理

  • Producer 事务(保证数据精准一次写入 结合幂等性)

    为了实现跨分区跨会话的事务,需要引入一个全局唯一的 Transaction ID,并将 Producer 获得的 PID 和Transaction ID 绑定。这样当Producer 重启后(重启后 PID 会改变)就可以通过正在进行的 TransactionID 获得原来的 PID,这也是精准一次性实现的基础。

    为了管理 Transaction, Kafka 引入了一个新的组件 Transaction Coordinator。 Producer 就是通过和 Transaction Coordinator 交互获得 Transaction ID 对应的任务状态。 Transaction Coordinator 还负责将事务所有写入 Kafka 的一个内部 Topic __transaction_state,这样即使整个服务重启,由于事务状态得到保存,进行中的事务状态可以得到恢复,从而继续进行。

  • Consumer 事务(较弱)

    上述事务机制主要是从 Producer 方面考虑,对于 Consumer 而言,事务的保证就会相对较弱,尤其时无法保证 Commit 的信息被精确消费。这是由于 Consumer 可以通过 offset 访问任意信息,而且不同的 Segment 生命周期不同,同一事务的消息可能会出现重启后被删除的情况

26. Kafka 作为消息队列使用的优点?

  • 与周边生态系统兼容性较好,如大数据和流计算领域
  • 性能较好,基于 Scala 和 Java 语言开发,设计中大量使用了批量处理和异步的思想,最高可以每秒处理千万级别的消息。

27. 比较 Kafka 和 RabbitMQ

部分摘自:https://blog.csdn.net/chenyh_csdn/article/details/83858291

  • 应用场景
    RabbitMQ:用于实时的,对可靠性要求较高的消息传递上。
    kafka:用于处于活跃的流式数据,大数据量的数据处理上。
  • 吞吐量
    RabbitMQ:支持消息的可靠的传递,支持事务,不支持批量操作,基于存储的可靠性的要求存储可以采用内存或硬盘,吞吐量小。
    kafka:内部采用消息的批量处理,数据的存储和获取是本地磁盘顺序批量操作,消息处理的效率高,吞吐量高。
  • 集群负载均衡
    RabbitMQ:本身不支持负载均衡,需要 loadbalancer 的支持
    kafka:采用zookeeper对集群中的broker,consumer进行管理,把topic分成若干partition给broker时默认遵循负载均衡策略,以及部分broker挂掉之后也有可以开启的默认的自动平衡策略。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值