Kafka面试题

文章目录

    • 什么是kafka
    • kafka的设计是什么样的
    • kafka的应用场景
    • 使用kafka优缺点
    • kafka性能好体现在哪
    • 什么是传统的消息传递方法
    • kafka和传统技术有什么优势
    • kafka的zk是什么??我们可以在没有Zookeeper的情况下使用Kafka吗?
    • kafka如何消费消息
    • kafka如何提高远程用户吞吐量
    • 如何减少ISR扰动,broker什么时候离开ISR
    • kafka为什么需要复制
    • 请说明如果首选的副本不在ISR中会发生什么?
    • 数据传输的事务定义有哪三种级别
    • kafka判断一个节点是否还活着的两个条件
    • producer是否直接将数据发送到leader
    • consumer是否可消费指定分区消息
    • kafka消息是pull模式,还是push模式
    • kafka在硬盘上的消息格式是什么
    • kafka高效文件存储设计特点
    • kafka与传统消息系统的三个关键区别
    • kafka创建topic如何将分区放置到不同broker中
    • kafka新建的分区会在哪个目录中创建
    • 分区的目录如何保存到磁盘
    • kafka的ack机制
    • kafka的消费者如何消费数据
    • 消费者负载均衡策略
    • 数据有序
    • 项目用过消息队列么??为啥用消息队列呢??
    • 你在什么场景下用到了消息队列??
      • 异步
      • 解耦
      • 那流程走完了,你不管别人是否成功么?比如下单了,积分没加上,优惠券没扣减怎么办??
      • 肖峰
      • 使用消息队列遇到过什么问题没有??
      • 你是怎么做的技术选型呢??
    • 重复消费(幂等)、顺序消费、分布式事务
      • 消息队列重复消费在什么场景遇到呢
      • 消息队列重复消费是怎么保证的呢?
      • 消息队列顺序消费这样的场景,怎么保证
    • 分布式事务
      • 怎么保证分布式事务呢??

什么是kafka

Kafka是一种基于发布/订阅的分布式消息系统,它能够高效并实时的吞吐数据,以及通过副本冗余机制保证数据安全。

kafka的设计是什么样的

Kafka将消息以topic为单位进行归纳 将向Kafka topic发布消息的程序成为producers. 将预订topics并消费消息的程序成为consumer. Kafka以集群的方式运行,可以由一个或多个服务组成,每个服务叫做一个broker. producers通过网络将消息发送到Kafka集群,集群向消费者提供消息

kafka的应用场景

①异步处理
②应用解耦
③流量削峰
④日志处理
⑤消息通讯等。

使用kafka优缺点

优点:

  1. 吞吐量:kafka吞吐量非常高,达到十万级
  2. 响应时间:响应时间毫秒级
  3. 可用性:kafka是一个分布式系统,一个数据多副本,少数机器宕机,不会丢失数据
  4. 可靠性:经过参数优化配置,消息可以做到0丢失
  5. 功能支持:主要支持简单MQ功能,在大数据实时计算和日志采集中被大规模使用
    缺点:
  6. 吞吐量受主题影响很大,当主题达到几十个到几百个时,吞吐量大幅度下降
  7. 数据批量发送,并非真正实时
  8. 仅支持分区内消息有序,无法实现全局消息有序
  9. 依赖zk管理元数据

kafka性能好体现在哪

  1. 顺序读写
  2. 零拷贝
  3. 分区
  4. 批量发送
  5. 数据压缩

什么是传统的消息传递方法

排队:一组用户从队列中读取数据,每条消息发送给指定某个人
发布-订阅:消息广播给所有用户,

kafka和传统技术有什么优势

①快速:单一的Kafka代理可以处理成千上万的客户端,每秒处理数兆字节的读写操作。
②可伸缩:在一组机器上对数据进行分区
③和简化,以支持更大的数据
④持久:消息是持久性的,并在集群中进
⑤行复制,以防止数据丢失。
⑥设计:它提供了容错保证和持久性

kafka的zk是什么??我们可以在没有Zookeeper的情况下使用Kafka吗?

一旦Zookeeper停止工作,它就不能服务客户端请求。
zookeeper用于在集群中不同节点之间进行通信

在kafka中,zk用于提交偏移量,当任意节点失败,都可以从之前提交的偏移量出继续执行
除了提交偏移量,还进行leader检测,新节点状态检测,配置管理,分布式同步

kafka如何消费消息

它支持将字节从套接口转移到磁盘,通过内核空间保存副本,并在内核用户之间调用内核。

kafka如何提高远程用户吞吐量

若用户位置与broker不同数据中心,则可能需要优化套接字缓冲区大小,以对应对长网络延迟

如何减少ISR扰动,broker什么时候离开ISR

ISR是一组与leader完全同步的消息副本,也就是说ISR包含了所有提交的消息。
当一个副本从leader中脱离出来,就会从ISR中删除

kafka为什么需要复制

确保任何已发布的消息不会丢失,在机器错误,程序错误时任然可用。

请说明如果首选的副本不在ISR中会发生什么?

如果首选的副本不在ISR中,控制器将无法将leadership转移到首选的副本。

数据传输的事务定义有哪三种级别

  1. 最多一次:消息不会重复发送,最多传输一次,但有可能不传输
  2. 最少一次:消息不会漏传,最少传输一次,但有可能重复传输
  3. 精确一次:消息不会重复也不会漏传,消息传输一次且仅传输一次

kafka判断一个节点是否还活着的两个条件

  1. 节点任然在维护和zk的心跳,zk通过心跳机制检查每个节点的连接
  2. 如果节点是flower,他必须能及时同步leader的写操作

producer是否直接将数据发送到leader

所有的kafka节点都不许告知:哪些节点是活动的,目标主题分区的leader在哪

consumer是否可消费指定分区消息

consumer消费消息时,向broker发出fetch请求去消费特定分区消息,consumer指定消息在日志中的offset,就可以消费这个位置开始的消息

kafka消息是pull模式,还是push模式

producer将消息推送到broker,consumer从broker拉取消息。
其他消息系统Flume就采用push模式,将消息推送到consumer,这样做可以由broker决定消息推送的速率,但对于不同消费速度的consumer就不好处理了,当推送速度远远大于consumer消费速度时,可能导致消费者奔溃

pull模式另一个好处就是 consumer可以根据自己的消费能力去决定是否批量拉取数据

pull缺点是,当broker没有消息时,consumer将不断进行轮询。为了避免这点,可通过参数让consumer阻塞直到新数据到达

kafka在硬盘上的消息格式是什么

消息由一个固定长度的头部 和 可变长度的字节数组组成
消息长度:4byte(1+4+n)
版本号:1byte
CRC效验码:4bytes
具体消息:nbytes

kafka高效文件存储设计特点

  1. 将主题中一个partition大文件分为多个大小相等的段文件,更加容易定期删除已消费文件,减少磁盘
  2. 通过索引信息快速定位message的位置
  3. 通过索引元数据全部映射到内存,避免磁盘io
  4. 索引文件稀疏存储,大幅度降低索引原文件占用空间大小

kafka与传统消息系统的三个关键区别

  1. kafka持久化日志,这些日志可以重复读取,而且无限期保留
  2. kafka是一个分布式系统,通过增加分区线性提高主题的吞吐量,内部通过复制机制实现高可用和容错能力
  3. kafka支持实时流式处理

kafka创建topic如何将分区放置到不同broker中

  1. 副本因子不能大于broker的个数
  2. 第一个分区第一个副本随机放到brokerList中,其他分区的第一个副本则循环向 后移动
  3. 剩余副本则随机放

kafka新建的分区会在哪个目录中创建

在启动kafka集群之前,我们通过配置log.dirs参数指定数据存放目录,这个参数可配置多个目录,用逗号分割开。通常这些目录分布在同步磁盘上用于提高读写性能。
当我们配置多个目录,kafka创建的分区会在哪个目录创建分区目录呢??kafka会在含有分区目录最少的文件夹中创建新得分区目录分区目录名为topic名+分区ID

分区的目录如何保存到磁盘

Kafka面试题_第1张图片
主题中的多个分区文件以文件夹的形式保存到broker中,每个分区序号从0递增,且消息有序
partition文件夹下有多个segment文件(xxx.index,xxx.log)
segment文件默认为1G,如果segment文件大于1G时,会生成一个新得segment文件,文件名为上一个segment最后一条消息的偏移量命名

索引文件(n,length):表示第n个message
a) 通过offset二分查找文件列表定位到segment文件
b) 通过index元数据指针,查找log文件对象对应的message

kafka的ack机制

request.required.acks有三个值 0 1 -1
0:生产者不会等待broker的ack,延迟最低,但存储保证最弱
1:服务端等待分区leader确认接收消息后发送ack,但当leader挂掉其他flower每复制数据也会丢失数据
-1:服务端等待分区所有副本确认接受消息后发送ack,保证不会丢失数据,但延迟最大

kafka的消费者如何消费数据

消费者每次消费消费数据时,都会记录消费的offset偏移量位置,等待下次消费时,接着上次位置继续消费

消费者负载均衡策略

主题中的一个分区对应一个消费者成员,增加消费者组的消费者可以增加消费能力,但当超出了分区数目时,消费者会出现空闲情况

数据有序

一个消费者组内的消息是有序的,消费者组之间是无需的

项目用过消息队列么??为啥用消息队列呢??

我们的项目本身的业务体量很小,所以直接单机一把都能都能搞定了,但是后面业务体量不断扩大,采用微服务的设计思想,分布式的部署方式,所以拆分了很多的服务,随着体量的增加以及业务场景越来越复杂了,很多场景单机的技术栈和中间件以及不够用了,而且对系统的友好性也下降了,最后做了很多技术选型的工作,我们决定引入消息队列中间件。

你在什么场景下用到了消息队列??

一说到消息队列你脑子就要想到异步、削峰、解耦,条件反射那种。

异步

我们之前的场景很多步骤都是在一个流程里面做完的,就比如我们的订单系统吧,本来我们的业务很简单下了单,付了钱,扣减了库存流程就走完了。
但是后面联通那边来了需求,说要融合抢鲜购和沃门店两套系统,将沃门店的优惠券系统和积分系统加到抢鲜购中,好么,加了个优惠券系统,流程里多了100ms去扣减优惠券,加了个积分系统,流程里多了200ms去增减积分,最后联通那边还要求,我们下单成功后要给用户发短信,然后又多了100ms。
Kafka面试题_第2张图片
Kafka面试题_第3张图片
老东家要求所有接口的Rt(response time)在200ms内,超出的全部优化。
敖丙负责的系统QPS9w+,Rt要求在50ms内。
通过异步来实现,用户支付完成后,立马给用户返回下单成功。
为啥不用多线程去做:

解耦

联通那边提需求是一会一个变,难道每次新调用一个接口都要重新发布系统,重新在原系统做修改么,这就违反了开闭原则,这就是很典型的系统耦合问题了
当用户发起下单请求时,主流程只经过订单系统,支付系统流程就结束了,然后将支付成功消息发送出去,而后面不管接入什么系统,只要订阅相应的支付成功消息完成相应的逻辑就好了。

那流程走完了,你不管别人是否成功么?比如下单了,积分没加上,优惠券没扣减怎么办??

这其实是用了消息队列的一个缺点,涉及到分布式事务的知识点

肖峰

当遇到秒杀活动时,如果流量直接到数据库时,会将数据库打挂的
那怎么办,将下单请求放到队列里面,每秒钟消费多少请求就看自己的消费能力了

使用消息队列遇到过什么问题没有??

技术是把双刃剑,虽然带来了很多好处,但使用之后的问题也是接踵而至。

  1. 数据一致性:不仅仅时消息队列的问题,分布式服务普遍存在的问题。只有所有服务都成功才能算这一次下单是成功的。
    分布式事务:把下单,优惠券,积分。。。都放在一个事务里面一样,要成功一起成功,要失败一起失败。
  2. 可用性:中间件如果挂了,那么会导致优惠券不扣了,积分不加了的情况

重复消费,消息丢失,顺序消费,分布式事务等问题。。。

你是怎么做的技术选型呢??

目前在市面上比较主流的消息队列中间件主要有,Kafka、ActiveMQ、RabbitMQ、RocketMQ 等这几种
ActiveMQ和RabbitMQ这两着因为吞吐量还有GitHub的社区活跃度的原因,在各大互联网公司都已经基本上绝迹了
越来越多的公司更青睐RocketMQ这样的消息中间件了
Kafka和RocketMQ一直在各自擅长的领域发光发亮,吞吐量都在10万级。

重复消费(幂等)、顺序消费、分布式事务

https://blog.csdn.net/qq_35190492/article/details/103232854?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

消息队列重复消费在什么场景遇到呢

Kafka面试题_第4张图片
Kafka面试题_第5张图片
重复消费是个比较严重和常见的问题,但凡用到消息队列,我第一时间就考虑是否重复消费。
在公司做活动模块时,遇到需要给一个活动页面加GMV(销售总额),最后根据它的GMV在什么区间去给他发奖励,这是电商活动常见玩法。

首先电商活动100%都是异步去加的,不然你想,一个用户下一单就操作表加一下金额,在高并发的场景下,数据库根本顶不住。而且用户在下单看一些活动页面,有时候马上就有了,有时候延迟很久,这个速度就取决于消息队列的消费速度。
下个单支付成功就将这个消息发出去,活动开发人员就监听你的支付成功消息,然后再活动GMV表里给你加上去,最终发生重复消费问题。一般消息队列都会有重试机制,就是说如果业务发生异常则会抛出异常要求你重新发一次,当然网络抖动啊,程序bug啊,数据问题啊都可能进行重试。但监听这个订单支付成功消息除了活动模块之外,还有库存模块,优惠券模块,积分模块。如果积分模块处理失败请求重试但此时活动GMV已经将销售额加上了,就会导致重复累加销售额的问题。

消息队列重复消费是怎么保证的呢?

我们是通过接口幂进行处理的,接口幂的意思就是说无论调用这个接口多少次,返回的结果都是一样的。
一般幂等接口的实现,我会分场景去考虑,看是强效验还是弱效验。如果和钱相关的场景就做强效盐,否则做弱效验。

key=订单号+场景

  1. 用流水表做强效验,是因为涉及到金钱这样的活动,有啥问题可以很方便的通过流水表进行对账,而且还可以帮助开发人员定位问题。
    大致处理流程是:下单发支付成功消息,活动模块判断这个订单我处理过没,如果处理过就return返回,如果没处理过,则累加销售额和流水,这两个操作在同一个事务中,要成功都成功。

  2. 通过redis保存做弱效验,将key放到redis中,在一定时间内在redis中进行判断 发短信之类

消息队列顺序消费这样的场景,怎么保证

  1. 场景
    a) 当数据量大的时候,数据从主数据库同步到备用数据库压力会很大
    比如我们增、删、改消费的时候变成了改、删、增
    b) 订单的创建、支付、发货、收货必须是顺序的
  2. 保证
    通过hash取模的方法,让同一个订单发送到同一个分区/队列,然后再使用同步发送,保证了消息发送的有序性。
    消费者的顺序消费,由消费者业务保证!!!————待定

分布式事务

什么是事务呢??事务的4个属性就是ACID
什么是分布式事务呢??比如下单流程可能涉及到10多个环节,下单支付成功了,但优惠券扣减失败了,积分新增失败了,分布式事务就是保证这些在不同服务的操作具有ACID

怎么保证分布式事务呢??

没有最完美的系统,只有最适合的系统。
2pc提交,Zab协议,最终一致性
分布式事务有很多弊端:长时间锁定数据库资源,并发上不去

你可能感兴趣的:(面试)