Kafka面试题(总结26面试题)
1.kafka是什么?
kafka主要是一种高吞吐量的分布式消息系统,在技术上最初是由linkedin公司开发的,并采用scala语言编写而成。该系统现已成为apache组织下的一个开源项目
1.broker:kafka服务器,负责消息存储和转发
2.topic:消息类别,kafka按照topic来分类消息
3.partition:topic的分区即分片概念下被划分成多个partition对象
4.offset:记录在日志中的位置, 也可以理解为消息在其所在分区上的偏移量, 同样表示该消息的唯一标识符.
5.producer:消息生产者
6.consumer:消息消费者
7.consumer group:消息者分组,每个consumer必须属于一个group
zookeeper:存储着集群中的broker、topic、partition等元数据;此外,还负责broker故障处理、partition leader选举以及负载均衡控制等功能
2.partition的数据文件(offset,messagesize,data)
在某个partition中生成的消息包包含三条信息字段:偏移量(offset)、消息字节数(messagesize)以及实际的内容数据(data)。其中,
offset代表的是这条message在该partition中的逻辑位置标识,
它并不是该消息在分区数据文件中的物理存储起始点,
而是用来标识这条消息在整个分区中所处的位置的一个虚拟索引值,
可以说,
offset就是这个分区中某条特定 message 的唯一标识符。
而 messagesize 则用于指示这一条 message 的实际长度或占用的空间大小,
最后一条信息字段 data 则完整记录了这条 message 的具体内容信息。
3.数据文件分段segment(顺序读写、分段命令、二分查找)
kafka在每个分段后创建的数据目录下生成了一个索引目录,在其名称相同的基础上将其扩展为.index格式。该系统并未对每条消息单独建立一个记录以形成该目录中的信息;相反地,则采用了一种稀疏存储的方式,在每隔一定字节的数据之后会记录一次信息以节省空间,并使该结构能够在内存中高效运行

4.负载均衡(partition会均衡分布到不同broker上)
因为 topic 被划分为多个 partition,并且每个 partition 会均匀地分配至不同的 broker 上。因此采取随机算法或哈希机制将消息均匀分布至一个多节点集群中可有效提升每秒的消息处理数量。

5.批量发送
是主要提高消息吞吐量的关键方式,在producer端内存中整合了多条消息后通过一次批量请求的方式发送给broker从而减少了大量的IO操作频率这也牺牲了一定的消息实时性以一定延迟为代价换取更高的吞吐效率
6.压缩(GZIP或Snappy)
producer端可以选择使用CZIP或Snappy格式来进行消息集合的压缩;经过producer端的压缩后,在consumer端需要执行解压操作;通过压缩的好处是减少了数据传输量并缓解了网络压力;在大数据处理中发现瓶颈通常出现在网络环节而非中央处理器(虽然它们确实会占用一部分CPU资源)。
7.消费者设计

8.consumer group
同一消费者群体中的多个消费者实例依次不消费同一个 partition, 这类似于队列模式。其中, partition内的消息是按顺序排列的, 消费者通过 pull 操作获取消息。Kafka系统不会删除已消耗的消息对于每个 partition, 并且会采用时间复杂度为 O(1) 的方式实现对 msg 的持久化。
9.如何获取topic主题的列表
bin/kafka-topics.sh --list --zookeeper localhost:2181
10.生产者和消费者的命令行是什么?
生产者在主题上发布消息:
请特别注意:此处的ip位于server.properties文件中,并属于listeners属性的一部分。随后每一行将对应一条新的消息输入。
消息者接收消息:
11.consumer是推还是拉?
kafka的核心问题是,在消费者(customer)是从 brokers 拉取消息还是由 brokers 将消息发送给消费者(producers)之间存在分歧?这个问题主要涉及 pull 和 push 两种方式。就这一问题而言,在生产者(producers)将数据发送到中间节点(brokers),而消费者(consumers)则从这些中间节点处获取数据这一传统设计思路下进行操作。
例如消息系统Scribe和Apache Flume采用了推送模式,并将消息传递给下游的消费者。然而,在这种情况下存在优点也有缺点:对于不同消费速率的消费者就难以协调。这些消息系统都致力于使消费者能够以最大速度尽可能快速地消耗消息;然而,在推送模式下当Broker发送的速度远高于Consumer消耗的速度时这可能会导致严重问题。最终,Kafka选择了经典的拉取模式作为解决方案。
pull模式的另一个优势在于消费者可以根据自身需求自主选择是否进行大批量的数据获取操作。然而,在不知道下游消费者的数据消耗能力及使用策略的情况下,默认选择逐条发送可能会导致性能压力增大。为了防止消费者出现崩溃现象,在降低消息发送频率的同时可能会造成单次消息数量减少而导致资源浪费的问题。
consumer就可以根据自己的消费能力去决定这些策略
消费者有一个特点:如果Broker没有可供消费的消息,则会使得Consumer一直持续地进行查询直到新消息到达。为了避免这种情况,Kafka提供了一个参数可以让Consumer阻塞等待直至新消息的到来(此外还可以设置一个特定的阈值,在消息数量达到该值时触发批量发送)
12.讲讲kafka维护消费状态跟踪的方法
大多数消息系统中,在broker端处理的消息被消费记录的情况较为常见。当一个消息发送给consumer时,在broker端会立即进行标识;如果后续收到customer的通知,则会再次标识该信息。这样一来,在完成消息处理后即可及时删除这些信息以节省存储空间。
但是这样做会不会有问题呢?如果一条消息发送出去后立即被标记为已消费过,在consumer处理消息时如果程序崩溃(比如出现错误),这条消息就会丢失了。为了应对这个问题,很多消息系统都提供了额外的功能:当一条消息被发送出去后仅标记为已发送状态,在consumer确认成功消费后才将其标记为已消费状态。这种方法虽然解决了消息丢失的问题但也带来了新的问题:如果在consumer处理成功但未及时向broker发送响应时这条消息会被消费两次;第二个问题是broker必须维护每条消息的状态每次都要先锁定消息更改状态后再解锁这增加了不必要的麻烦而且还要维护大量状态数据例如如果一条消息发送出去但没有收到成功消费的通知这条消息将一直保持锁定状态直到处理完毕Kafka采用了不同的策略:将Topic划分为多个分区每个分区在同一时间只能被一个consumer消费这意味着每个分区内的消费消息在日志中的位置只是一个简单的整数offset这样一来就很容易跟踪每个分区的消费状态只需要记录一个整数就可以了这种跟踪方法带来了另一个好处:consumer可以通过调整offset值重新消费较早的消息这对传统消息系统看起来似乎有些不合理但却是非常有用的因为并没有规定一条消息只能被消费一次
13.讲一下主从同步
深入探讨Kafka架构中的主从复制机制——个人博客园文章推荐:《Kafka架构设计与复制机制解析》
14.为什么需要消息系统,mysql不能满足需求嘛?
1.解耦:
支持你可以自行延伸两端的处理流程,只要确保它们遵循相同的接口规范
2.冗余:
消息队列将数据存储至彻底处理完成前进行持久化操作从而有效地规避了数据丢失的风险。在采用“插入-获取-删除”流程的消息系统中为了确保操作安全在执行删除动作前必须明确告知处理模块该条信息已送达以便保证后续的数据完整性与安全性。
3.扩展性:
由于消息队列与你的处理流程实现了解耦,则优化消入队列和提高处理效率变得非常容易。通过进一步优化资源利用率,则能够轻松实现这一目标。
4.灵活性 &峰值处理能力:
当网络流量激增时,在这种情况下系统仍需维持正常运转。然而 occasional high traffic situations are relatively rare. 如果将处理峰值流量作为投资资源的标准,则未免过于保守. 通过消息队列机制, 系统能够有效应对短暂的高负载压力而不崩溃.
5.可恢复性:
当某个部分组件失效时,并不会影响整个系统的运行。消息队列通过减少进程间的耦合度来提高系统的可靠性;一旦某个处理消息的进程故障停止服务,在系统恢复后仍可继续接收并处理这些来自队列的消息。
6.顺序保证:
在大多数使用场景中, 数据处理顺序的重要性不容忽视. 大多数消息队列本就具备排序功能, 并从而确保数据按照预先设定好的流程依次被处理. (Kafka通过机制确保每个partition内的消息严格按顺序排列)
7.缓存:
能够有效地管理与提升信息流的速度,在系统中协调生产与消费端的消息处理效率以解决消息处理速度不一致的问题
8.异步通信:
通常情况下,在线系统会设计一种机制来让用户提供灵活的操作空间。这种机制通过非阻塞式通信实现,并且支持将数据添加到队列中但不会立刻进行处理。根据需求批量添加数据到队列中,并且等到后续操作触发时才开始执行
15.zookeeper对于kafka的作用是什么?
Zookeeper是一个开放源代码、高效率的协调服务,并被用作Kafka分布式应用中的核心组件。
负责协调各节点之间的通信过程,并处理集群内部的数据同步问题。
其中kafka机制被用来记录偏移信息,并且一旦节点出现故障,在之前的日志记录中仍可恢复或重置
除了完成初始功能外,该系统还会执行一系列任务,包括但不限于:领导节点检测、分布式同步机制、配置管理模块、实时监控新节点的入网与离线行为,以及集群管理功能等。
16.数据传输的事务定义有哪三种?
和MQTT的事务定义一样都是三种
1.最多一次:消息不会被重复发送,最多被传输一次,但也有可能一次不传输
2.最少一次:消息不会被漏发送,最少被传输一次,但也有可能被重复传输
3.精确的一次(Exactly once):确保无遗漏且无冗余地传递信息,并使每个消息准确且唯一地发送出去以符合预期的结果。
17.kafka判断一个节点是否还活着有那俩个条件?
节点能够支持与Zookeeper建立连接,并且Zookeeper使用心跳计数器来验证各个节点是否保持连通。
如果一个节点是follower,则必须迅速地对接leader的写操作,并确保不会延迟过长的时间。
18.Kafka与传统MQ消息系统之间有三个关键区别
1.kafka持久化日志,这些日志可以被重复读取和无限制保留
2.kafka属于一种分布式系统:该系统采用集群架构运行,并且能够实现弹性扩展能力。通过复制数据来增强系统的容错能力,并提高其高可用性。
3.kafka支持实时的流式处理
19.讲一讲kafka的ack的三种机制
request.required.ack有三个值0 1 -1(all)
生产者不等到broker返回acks,在这个延迟是最小的情况下然而,在存储方面的保障是最差的;当服务器出现故障时会导致数据丢失
服务端会一直等待ack值并成功接收消息后响应成功;但如果leader失效且未验证复制完成情况,则可能导致数据丢失。
-1(all):服务端会等待所有follower的所有副本都接收到数据之后才会接收leader发来的ack, 从而确保数据不会丢失
20.消费者如何不自动提交偏移量,由应用提交?
请将auto.commit.offset配置为false,并在完成对一批消息的处理后调用commitSync()或进行异步提交操作commitAsync()。
即:
21.消费者故障,出现活锁问题如何解决?
当‘活锁’发生时,它是持续不断地发送心跳信号但未被处理,为了避免消费者长时间保持分区不变,我们采用了max.poll.interval.ms活跃检测机制。在此框架下,如果客户发起的请求频率超过最大检测间隔,客户端会主动退出当前组以便让其他客户接手该区域的所有操作,此时你会看到offset提交失败(如commitSync()引发 commitFailedException错误)。这种机制确保只有当前活跃成员才能进行offset操作,因此为了维持组内活动必须持续调用poll函数
消费者提供俩个配置设置来控制poll循环:
max.poll.interval.ms: 提高该间隔值可以使消费者有更多时间来处理返回的消息(当调用poll()方法时会返回消息时),通常一次会返回一批消息。需要注意的是较大的值可能导致组重平衡延迟。
该参数(max.poll.records)用于限制每次调用poll函数返回的消息数量。这有助于更方便地预估每个poll间隔内可能处理的最大消息数量。通过改变该参数的值,则可减小poll间隔。
对于消息处理时间难以估计的地方的情况而言,在这种情况下仅靠现有选项是无法满足要求的。解决这一问题的方法是在另一个线程中执行消息处理操作,并允许消费者继续调用poll函数以获取更新信息。特别需要注意的一点是,在执行完所有必要的操作后及时进行手动偏移量提交(根据你的具体需求)。此外,在启动新的分区分时必须暂停当前线程以防止从poll函数接收到新的消息;在线程完成所有处理工作之前,请返回最新的消息内容(如果当前系统在拉取消息的速度上超过了你的处理能力,则需要启动新的子线程来解决这个问题)
22.如何控制消费的位置
该方法允许通过指定TopicPartition以及long类型的偏移量来设定新的消费偏移量。其中可使用的特殊方法包括获取或定位到特定时间范围内的消息偏移量(如通过调用seekToBeginning(Collection)和seekToEnd(Collection)来分别获取起始偏移量与结束偏移量)。
23.kafka分布式(不是单机)的情况下,如何保证消息的顺序消费?
在kafka分布式系统中,每个单元被称为partition。每个partition会使用一个write-ahead log来进行组织管理。从而能够确保消息的读取顺序遵循FIFO原则。然而,在不同partition之间的消息读取则无法保证严格的FIFO顺序。不过,在实际应用中,默认情况下大多数用户都可以通过消息键来实现这一功能。因此,在相同的key下发送的消息只会被特定的partition接收处理。
在发送一条消息时,在kafka中可以指定三个参数:topic、partition和key。其中, partition和key是可选设置。如果选择了指定partition,则意味着所有消息都会发送到同一个partition,并且这种安排会实现有序传输;同时,在消费端,kafka保证一个特定的 partition 只能被一个 consumer 消费以确保数据的一致性和稳定性
24.kafka的高可用机制是什么?
这个问题比较系统地阐述 kafka 的系统特点、leader 与 follower 之间的关系以及消息读写顺序等。
扎心了啊大神们!终于到了第三个章节
https://yq.aliyun.com/articles/64703
25.kafka如何减少数据丢失
该文详细说明了如何避免Kafka系统出现消息丢失的情况,并提供了相应的配置参数设置方法。文章深入分析了可能导致消息丢失的原因及其解决方案的具体实施步骤,并通过实际案例展示了这些措施的有效性与可靠性。此外,在配置过程中需要注意的一些关键点也得到了充分的强调与说明
26.kafka如何不消费重复数据?比如扣款,我们不能重复扣
其实还是得结合业务来思考,我这里给几个思路:
比如你拿某个数据表要创建库的话,在检查主键是否存在之后发现这些数据已经存在的话就不再进行插入操作而更新一次数据库就可以了。
比如你是写 Redis,那没问题了,反正每次都是 set,天然幂等性。
例如你在上述两种情况之外
通过数据库的唯一键设置来确保重复数据不会被多次插入。由于有了独特的索引设置,在进行重复数据插入时会触发错误提示,并且无法将这些无效记录保留在数据库中。
