当前位置:   article > 正文

Kafka常见面试题

Kafka常见面试题

1、说说kafka中的⼀些基本概念【必须】

Borker:

消息中间件处理节点,⼀个Kafka节点就是⼀个broker,⼀个或者多个Broker可以组成⼀个Kafka集群

Topic:

Kafka根据topic对消息进⾏归类,发布到Kafka集群的每条消息都需要指定⼀个topic

Producer:

消息⽣产者,向Broker发送消息的客户端

Consumer:

消息消费者,从Broker读取消息的客户端

ConsumerGroup:

每个Consumer属于⼀个特定的Consumer Group,⼀条消息可以被多个不同的Consumer Group消费,但是⼀个Consumer Group中只能有⼀个Consumer能够消费该消息

Partition:

物理上的概念,⼀个topic可以分为多个partition,每个partition内部消息是有序的

2、Kafka的使用场景【必须】

日志收集:

⼀个公司可以⽤Kafka收集各种服务的log,通过kafka以统⼀接⼝服务的⽅式开放给各种consumer,例如hadoop、Hbase、Solr等。

消息系统:

解耦和⽣产者和消费者、缓存消息等。

用户活动跟踪:

Kafka经常被⽤来记录web⽤户或者app⽤户的各种活动,如浏览⽹⻚、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘

运营指标:

Kafka也经常⽤来记录运营监控数据。包括收集各种分布式应⽤的数据,⽣产各种操作的集中反馈,⽐如报警和报告。

3、说说消息队列的流派

rabbitMQ:内部的可玩性(功能性)是⾮常强的

rocketMQ: 阿⾥内部⼀个⼤神,根据kafka的内部执⾏原理,⼿写的⼀个消息队列中间件。性能是与Kafka相⽐肩,除此之外,在功能上封装了更多的功能。

kafka:全球消息处理性能最快的⼀款MQ

zeroMQ

有broke:

重topic:Kafka、RocketMQ、ActiveMQ

整个broker,依据topic来进⾏消息的中转。在重topic的消息队列⾥必然需要topic的存在

轻topic:RabbitMQ

topic只是⼀种中转模式

⽆broker:

在⽣产者和消费者之间没有使⽤broker,例如zeroMQ,直接使⽤socket进⾏通信

4、说说你对发送消息和消费消息的理解

发送消息:

把消息发送给broker中的某个topic,打开⼀个kafka发送消息的客户端,然后开始⽤客户端向kafka服务器发送消息

消费消息:

打开⼀个消费消息的客户端,向kafka服务器的某个主题消费消息

⽅式⼀:从当前主题中的最后⼀条消息的offset(偏移量位置)+1开始消费

⽅式⼆:从当前主题中的第⼀条消息开始消费

关于消息的细节:

1、⽣产者将消息发送给broker,broker会将消息保存在本地的⽇志⽂件中

2、消息的保存是有序的,通过offset偏移量来描述消息的有序性

3、消费者消费消息时也是通过offset来描述当前要消费的那条消息的位置

5、单播消息和多播消息的区别

单播消息:

在⼀个kafka的topic中,启动两个消费者,⼀个⽣产者,问:⽣产者发送消息,这条消息是否
同时会被两个消费者消费?

如果多个消费者在同⼀个消费组,那么只有⼀个消费者可以收到订阅的topic中的消息。换⾔
之,同⼀个消费组中只能有⼀个消费者收到⼀个topic中的消息。

多播消息:

不同的消费组订阅同⼀个topic,那么不同的消费组中只有⼀个消费者能收到消息。实际上也
是多个消费组中的多个消费者收到了同⼀个消息。

6、消费组相关的参数

current-offset:

最后被消费的消息的偏移量

Log-end-offset:

消息总量(最后⼀条消息的偏移量)

Lag:

积压了多少条消息

7、kafka中主题和分区的概念【重点】

主题:

topic在kafka中是⼀个逻辑的概念,kafka通过topic将消息进⾏分类。不同的topic会被订阅该topic的消费者消费。

但是有⼀个问题,如果说这个topic中的消息⾮常⾮常多,多到需要⼏T来存,因为消息是会被
保存到log⽇志⽂件中的。为了解决这个⽂件过⼤的问题,kafka提出了Partition分区的概念。

分区:

通过partition将⼀个topic中的消息分区来存储。这样的好处有多个:

1、分区存储,可以解决统⼀存储⽂件过⼤的问题

2、提供了读写的吞吐量:读和写可以同时在多个分区中进行

8、kafka副本的概念【重点】

在创建主题时,除了指明了主题的分区数以外,还指明了副本数,那么副本是⼀个什么概念呢?

副本:

为了为主题中的分区创建多个备份,多个副本在kafka集群的多个broker中,会有⼀个副本作为leader,其他是follower。

leader:

kafka的写和读的操作,都发⽣在leader上。leader负责把数据同步给follower。当leader挂了,经过主从选举,从多个follower中选举产⽣⼀个新的leader

follower:

接收leader的同步的数据

isr:

可以同步和已同步的节点会被存⼊到isr集合中。

这⾥有⼀个细节:如果isr中的节点性能较差,会被提出isr集合。

9、生产者的同步发送消息和异步发送消息

同步发送消息:

如果⽣产者发送消息没有收到ack,⽣产者会阻塞,阻塞到3s的时间,如果还没有收到消息,会进⾏重试。重试的次数3次。

异步发送消息:

异步发送,⽣产者发送完消息后就可以执⾏之后的业务,broker在收到消息后异步调⽤⽣产者提供的callback回调⽅法。

10、生产者中的ack的配置【必须】

在同步发送的前提下,⽣产者在获得集群返回的ack之前会⼀直阻塞。那么集群什么时候返回ack呢?此时ack有3个配置:

ack = 0:

kafka-cluster不需要任何的broker收到消息,就⽴即返回ack给⽣产者,最容易丢消息的,效率是最⾼的

ack=1(默认):

多副本之间的leader已经收到消息,并把消息写⼊到本地的log中,才会返回ack给⽣产者,性能和安全性是最均衡的

ack=-1/all:

⾥⾯有默认的配置min.insync.replicas=2(默认为1,推荐配置⼤于等于2),此时就需要leader和⼀个follower同步完后,才会返回ack给⽣产者(此时集群中有2个broker已完成数据的接收),这种⽅式最安全,但性能最差。

11、关于消息发送的缓冲区

kafka默认会创建⼀个消息缓冲区,⽤来存放要发送的消息,缓冲区是32m

kafka本地线程会去缓冲区中⼀次拉16k的数据,发送到broker

如果线程拉不到16k的数据,间隔10ms也会将已拉到的数据发到broker

12、消费者自动提交和手动提交offset

提交的内容:

消费者⽆论是⾃动提交还是⼿动提交,都需要把所属的消费组+消费的某个主题+消费的某个分区及消费的偏移量,这样的信息提交到集群的_consumer_offsets主题⾥⾯。

自动提交:

消费者poll消息下来以后就会⾃动提交offset

注意:⾃动提交会丢消息。因为消费者在消费前提交offset,有可能提交完后还没消费时消费者挂了。

手动提交:

需要把⾃动提交的配置改成false

⼿动提交⼜分成了两种:

⼿动同步提交:

在消费完消息后调⽤同步提交的⽅法,当集群返回ack前⼀直阻塞,返回ack后表示提交成功,执⾏之后的逻辑

⼿动异步提交:

在消息消费完后提交,不需要等到集群ack,直接执⾏之后的逻辑,可以设置⼀个回调⽅法,供集群调⽤

13、关于长轮询poll消息

默认情况下,消费者⼀次会poll500条消息。

代码中设置了⻓轮询的时间是1000毫秒。

意味着:

如果⼀次poll到500条,就直接执⾏for循环

如果这⼀次没有poll到500条。且时间在1秒内,那么⻓轮询继续poll,要么到500条,要么到1s

如果多次poll都没达到500条,且1秒时间到了,那么直接执⾏for循环

如果两次poll的间隔超过30s,集群会认为该消费者的消费能⼒过弱,该消费者被踢出消费组,触发rebalance机制,rebalance机制会造成性能开销。可以通过设置这个参数,让⼀次poll的消息条数少⼀点

14、新消费组的消费offset规则

新消费组中的消费者在启动以后,默认会从当前分区的最后⼀条消息的offset+1开始消费(消费新消息)。可以通过以下的设置,让新的消费者第⼀次从头开始消费。之后开始消费新消息(最后消费的位置的偏移量+1)

Latest:

默认的,消费新消息

earliest:

第⼀次从头开始消费。之后开始消费新消息(最后消费的位置的偏移量+1)

15、kafka集群中的controller、rebalance、HW、LEO【重点】

controller:

集群中谁来充当controller

每个broker启动时会向zk创建⼀个临时序号节点,获得的序号最⼩的那个broker将会作为集群中的controller,负责这么⼏件事:

当集群中有⼀个副本的leader挂掉,需要在集群中选举出⼀个新的leader,选举的规则是从isr集合中最左边获得。

当集群中有broker新增或减少,controller会同步信息给其他broker

当集群中有分区新增或减少,controller会同步信息给其他broker

rebalance机制:

前提:消费组中的消费者没有指明分区来消费

触发的条件:当消费组中的消费者和分区的关系发⽣变化的时候

分区分配的策略:在rebalance之前,分区怎么分配会有这么三种策略

range:根据公示计算得到每个消费消费哪⼏个分区:前⾯的消费者是分区总数/消费者数量+1,之后的消费者是分区总数/消费者数量

轮询:大家轮着来

sticky:粘合策略,如果需要rebalance,会在之前已分配的基础上调整,不会改变之前的分配情况。如果这个策略没有开,那么就要进⾏全部的重新分配。建议开启。

HW和LEO:

LEO是某个副本最后消息的消息位置(log-end-offset)

HW是已完成同步的位置。消息在写⼊broker时,且每个broker完成这条消息的同步后,hw才会变化。在这之前消费者是消费不到这条消息的。在同步完成之后,HW更新之后,消费者才能消费到这条消息,这样的⽬的是防⽌消息的丢失。

16、如何防止消息丢失【必须】

⽣产者:

1、使⽤同步发送

2、把ack设成1或者all,并且设置同步的分区数>=2

消费者:

把⾃动提交改成⼿动提交

17、如何防止重复消费【必须】

在防⽌消息丢失的⽅案中,如果⽣产者发送完消息后,因为⽹络抖动,没有收到ack,但实际上broker已经收到了。

此时⽣产者会进⾏重试,于是broker就会收到多条相同的消息,⽽造成消费者的重复消费。

怎么解决:

⽣产者关闭重试:会造成丢消息(不建议)

消费者解决⾮幂等性消费问题:

所谓的幂等性:多次访问的结果是⼀样的。对于rest的请求(get(幂等)、post(⾮幂等)、put(幂等)、delete(幂等))

解决⽅案:

在数据库中创建联合主键,防⽌相同的主键,创建出多条记录

使⽤分布式锁,以业务id为锁。保证只有⼀条记录能够创建成功

18、如何做到消息的顺序消费【必须】

⽣产者:

保证消息按顺序消费,且消息不丢失——使⽤同步的发送,ack设置成⾮0的值

消费者:

主题只能设置⼀个分区,消费组中只能有⼀个消费者

kafka的顺序消费使⽤场景不多,因为牺牲掉了性能,但是⽐如rocketmq在这⼀块有专⻔的功能已设计好。

19、如何解决消息积压问题【必须】

消息积压问题的出现:

消息的消费者的消费速度远赶不上⽣产者的⽣产消息的速度,导致kafka中有⼤量的数据没有被消费。随着没有被消费的数据堆积越多,消费者寻址的性能会越来越差,最后导致整个kafka对外提供的服务的性能很差,从⽽造成其他服务也访问速度变慢,造成服务雪崩。

消息积压的解决方案:

在这个消费者中,使⽤多线程,充分利⽤机器的性能进⾏消费消息。

通过业务的架构设计,提升业务层⾯消费的性能。

创建多个消费组,多个消费者,部署到其他机器上,⼀起消费,提⾼消费者的消费速度

创建⼀个消费者,该消费者在kafka另建⼀个主题,配上多个分区,多个分区再配上多个消费者。该消费者将poll下来的消息,不进⾏消费,直接转发到新建的主题上。此时,新的主题的多个分区的多个消费者就开始⼀起消费了。此方案不常用。

20、实现延时队列的效果【重点】

应用场景:

订单创建后,超过30分钟没有⽀付,则需要取消订单,这种场景可以通过延时队列来实现

具体方案:

kafka中创建创建相应的主题

消费者消费该主题的消息(轮询)

消费者消费消息时判断消息的创建时间和当前时间是否超过30分钟(前提是订单没⽀付)

如果是:去数据库中修改订单状态为已取消

如果否:记录当前消息的offset,并不再继续消费之后的消息。等待1分钟后,再次向kafka拉取该offset及之后的消息,继续进⾏判断,以此反复。

Kafka学习视频:

千锋教育最新kafka入门到精通教程|kafka原理解析从安装到实战,阿里P7架构师讲解Java必备(附源码)_哔哩哔哩_bilibili

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/759287
推荐阅读
相关标签
  

闽ICP备14008679号