Kafka可以说是必知必会的了,首先面试大数据岗位的时候必问kafka,甚至现在java开发岗位也会问到kafka一些消息队列相关的知识点。先来看看有哪些最新的Kafka相关面试点:
一、基础摸底
1.1、你们Kafka集群的硬盘一共多大?有多少台机器?日志保存多久?用什么监控的?
1.2、Kafka分区数、副本数和topic数量多少比较合适?
1.3、Kafka中的HW、LEO、ISR、AR分别是什么意思?
1.4、Kafka中的消息有序吗?怎么实现的?
1.5、topic的分区数可以增加或减少吗?为什么?
1.6、你知道kafka是怎么维护offset的吗?
1.7、你们是怎么对Kafka进行压测的?
二、感觉还不错,接着深入考察
2.1、创建或者删除topic时,Kafka底层执行了哪些逻辑?
2.2、你了解Kafka的日志目录结构吗?
2.3、Kafka中需要用到选举吗?对应选举策略是什么?
2.4、追问,聊聊你对ISR的了解?
2.5、聊聊Kafka分区分配策略?
2.6、当Kafka消息数据出现了积压,应该怎么处理?
2.7、Kafka是怎么实现Exactly Once的?
2.8、追问、谈谈你对Kafka幂等性的理解?
2.9、你对Kafka事务了解多少?
2.10、Kafka怎么实现如此高的读写效率?
三、侃侃而谈
3.1、说说你常用的broker参数优化?
3.2、那怎么进行producer优化呢?
总结最准确的答案如下:
一、基础摸底
1.1、你们Kafka集群的硬盘一共多大?有多少台机器?日志保存多久?用什么监控的?
这里考察应试者对kafka实际生产部署的能力,也是为了验证能力的真实程度,如果这个都答不好,那可能就不会再继续下去了。
一般企业判断这些指标有一个标准:
集群硬盘大小:每天的数据量/70%*日志保存天数;
机器数量:Kafka 机器数量=2*(峰值生产速度*副本数/100)+1;
日志保存时间:可以回答保存7天;
监控Kafka:一般公司有自己开发的监控器,或者cdh配套的监控器,另外还有一些开源的监控器:kafkaeagle、KafkaMonitor、KafkaManager。
1.2、Kafka分区数、副本数和topic数量多少比较合适?
首先要知道分区数并不是越多越好,一般分区数不要超过集群机器数量。分区数越多占用内存越大 (ISR 等),一个节点集中的分区也就越多,当它宕机的时候,对系统的影响也就越大。
分区数一般设置为:3-10 个。
副本数一般设置为:2-3个。
topic数量需要根据日志类型来定,一般有多少个日志类型就定多少个topic,不过也有对日志类型进行合并的。
1.3、Kafka中的HW、LEO、ISR、AR分别是什么意思?
LEO:每个副本的最后一条消息的offset
HW:一个分区中所有副本最小的offset
ISR:与leader保持同步的follower集合
AR:分区的所有副本
1.4、Kafka中的消息有序吗?怎么实现的?
kafka无法保证整个topic多个分区有序,但是由于每个分区(partition)内,每条消息都有一个offset,故可以保证分区内有序。
1.5、topic的分区数可以增加或减少吗?为什么?
topic的分区数只能增加不能减少,因为减少掉的分区也就是被删除的分区的数据难以处理。
增加topic命令如下:
bin/kafka-topics.sh --zookeeper localhost:2181/kafka --alter \
--topic topic-config --partitions 3
关于topic还有一个面试点要知道:消费者组中的消费者个数如果超过topic的分区,那么就会有消费者消费不到数据。
1.6、你知道kafka是怎么维护offset的吗?
1.维护offset的原因:由于consumer在消费过程中可能会出现断电宕机等故障,consumer恢复后,需要从故障前的位置的继续消费,所以consumer需要实时记录自己消费到了哪个offset,以便故障恢复后继续消费。
2. 维护offset的方式:Kafka 0.9版本之前,consumer默认将offset保存在Zookeeper中,从0.9版本开始,consumer默认将offset保存在Kafka一个内置的topic中,该topic为**__consumer_offsets**。
3.需要掌握的关于offset的常识:消费者提交消费位移时提交的是当前消费到的最新消息的offset+1而不是offset。
1.7、你们是怎么对Kafka进行压测的?
Kafka官方自带了压力测试脚本(kafka-consumer-perf-test.sh、kafka-producer-perf-test.sh), Kafka 压测时,可以查看到哪个地方出现了瓶颈(CPU,内存,网络 IO),一般都是网络 IO 达到瓶颈。
二、感觉还不错,接着深入考察
2.1、创建或者删除topic时,Kafka底层执行了哪些逻辑?
以创建topic为例,比如我们执行如下命令,创建了一个叫做csdn的分区数为1,副本数为3的topic。
bin/kafka-topics.sh --zookeeper node:2181 --create \
--replication-factor 3 --partitions 1 --topic csdn
这行命令,在kafka底层需要经过三个步骤来处理:
1. 在zookeeper中的/brokers/topics节点下创建一个新的topic节点,如:/brokers/topics/csdn;
2. 然后会触发Controller的监听程序;
3. 最后kafka Controller负责topic的创建工作,并更新metadata cache,到这里topic创建完成。
2.2、你了解Kafka的日志目录结构吗?
1. 每个 Topic 都可以分为一个或多个 Partition,Topic其实是比较抽象的概念,但是 Partition是比较具体的东西;
2. 其实Partition 在服务器上的表现形式就是一个一个的文件夹,由于生产者生产的消息会不断追加到log文件末尾,为防止log文件过大导致数据定位效率低下,Kafka采取了分片和索引机制,将每个partition分为多个segment;
3. 每组 Segment 文件又包含 .index 文件、.log 文件、.timeindex 文件(早期版本中没有)三个文件。.log和.index文件位于一个文件夹下,该文件夹的命名规则为:topic名称+分区序号。例如,csdn这个topic有2个分区,则其对应的文件夹为csdn-0,csdn-1;
4. log 文件就是实际存储 Message 的地方,而 index 和 timeindex 文件为索引文件,用于检索消息
2.3、Kafka中需要用到选举吗?对应选举策略是什么?
一共有两处需要用到选举,首先是partition的leader,用到的选举策略是ISR;然后是kafka Controller,用先到先得的选举策略。
2.4、追问,聊聊你对ISR的了解?
ISR就是kafka的副本同步队列,全称是In-Sync Replicas。ISR 中包括 Leader 和 Follower。如果 Leader 进程挂掉,会在 ISR 队列中选择一个服务作为新的 Leader。有 replica.lag.max.messages(延 迟条数)和replica.lag.time.max.ms(延迟时间)两个参数决定一台服务是否可以加入 ISR 副 本队列,在 0.10 版本移除了 replica.lag.max.messages 参数,防止服务频繁的进去队列。
任意一个维度超过阈值都会把 Follower 剔除出 ISR,存入 OSR(Outof-Sync Replicas) 列表,新加入的 Follower 也会先存放在 OSR 中。
2.5、聊聊Kafka分区分配策略?
在 Kafka 内部存在三种默认的分区分配策略:Range , RoundRobin以及0.11.x版本引入的Sticky。Range 是默认策略。Range 是对每个 Topic 而言的(即一个 Topic 一个 Topic 分),首先 对同一个 Topic 里面的分区按照序号进行排序,并对消费者按照字母顺序进行排序。然后用 Partitions 分区的个数除以消费者线程的总数来决定每个消费者线程消费几个分区。如果除不尽,那么前面几个消费者线程将会多消费一个分区。
三种分区分配策略详见文章:深入分析Kafka架构(三):消费者消费方式、分区分配策略(Range分配策略、RoundRobin分配策略、Sticky分配策略)、offset维护
文中对三种分区分配策略举例并进行了非常详细的对比,值得一看。
2.6、当Kafka消息数据出现了积压,应该怎么处理?
数据积压主要可以从两个角度去分析:
1. 如果是 Kafka 消费能力不足,则可以考虑增加 Topic 的分区数,并且同时提升消费 组的消费者数量,消费者数=分区数。(两者缺一不可)
2. 如果是下游的数据处理不及时:提高每批次拉取的数量。如果是因为批次拉取数据过少(拉取 数据/处理时间<生产速度),也会使处理的数据小于生产的数据,造成数据积压。
2.7、Kafka是怎么实现Exactly Once的?
在实际情况下,我们对于某些比较重要的消息,需要保证exactly once语义,也就是保证每条消息被发送且仅被发送一次,不能重复。在0.11版本之后,Kafka引入了幂等性机制(idempotent),配合acks = -1时的at least once语义,实现了producer到broker的exactly once语义。
idempotent + at least once = exactly once
使用时,只需将enable.idempotence属性设置为true,kafka自动将acks属性设为-1。
2.8、追问、谈谈你对Kafka幂等性的理解?
Producer的幂等性指的是当发送同一条消息时,数据在 Server 端只会被持久化一次,数据不丟不重,但是这里的幂等性是有条件的:
1. 只能保证 Producer 在单个会话内不丟不重,如果 Producer 出现意外挂掉再重启是 无法保证的。因为幂等性情况下,是无法获取之前的状态信息,因此是无法做到跨会话级别的不丢不重。
2. 幂等性不能跨多个 Topic-Partition,只能保证单个 Partition 内的幂等性,当涉及多个Topic-Partition 时,这中间的状态并没有同步。
2.9、你对Kafka事务了解多少?
Kafka是在0.11 版本开始引入了事务支持。事务可以保证 Kafka 在 Exactly Once 语义的基 础上,生产和消费可以跨分区和会话,要么全部成功,要么全部失败。
1. Producer 事务:
为了实现跨分区跨会话的事务,需要引入一个全局唯一的 Transaction ID,并将 Producer 获得的 PID 和 Transaction ID 绑定。这样当 Producer 重启后就可以通过正在进行的 Transaction ID 获得原来的 PID。
为了管理 Transaction,Kafka 引入了一个新的组件 Transaction Coordinator。Producer 就 是通过和 Transaction Coordinator 交互获得 Transaction ID 对应的任务状态。Transaction Coordinator 还负责将事务所有写入 Kafka 的一个内部 Topic,这样即使整个服务重启,由于 事务状态得到保存,进行中的事务状态可以得到恢复,从而继续进行。
2. Consumer 事务:
上述事务机制主要是从Producer方面考虑,对于 Consumer 而言,事务的保证就会相对较弱,尤其时无法保证 Commit 的信息被精确消费。这是由于 Consumer 可以通过offset访问任意信息,而且不同的 Segment File生命周期不同,同一事务的消息可能会出现重启后被删除的情况。
2.10、Kafka怎么实现如此高的读写效率?
1. 首先kafka本身是分布式集群,同时采用了分区技术,具有较高的并发度;
2. 顺序写入磁盘,Kafka 的 producer 生产数据,要写入到 log 文件中,写的过程是一直追加到文件末端,为顺序写。
官网有数据表明,同样的磁盘,顺序写能到 600M/s,而随机写只有 100K/s。这 与磁盘的机械机构有关,顺序写之所以快,是因为其省去了大量磁头寻址的时间。
3. 零拷贝技术
三、侃侃而谈
3.1、说说你常用的broker参数优化?
1. 网络和IO操作线程配置优化
# broker 处理消息的最大线程数(默认为 3)
num.network.threads=cpu 核数+1
# broker 处理磁盘 IO 的线程数
num.io.threads=cpu 核数*2
2. log数据文件策略
# 每间隔 1 秒钟时间,刷数据到磁盘
log.flush.interval.ms=1000
3. 日志保存策略
# 保留三天,也可以更短 (log.cleaner.delete.retention.ms)
log.retention.hours=72
4. replica相关配置
offsets.topic.replication.factor:3
# 这个参数指新创建一个 topic 时,默认的 Replica 数量,Replica 过少会影响数据的可用性,太多则会白白浪费存储资源,一般建议在 2~3 为宜
3.2、那怎么进行producer优化呢?
buffer.memory:33554432 (32m)
# 在 Producer 端用来存放尚未发送出去的 Message 的缓冲区大小。缓冲区满了之后可以选择阻塞发送或抛出异常,由 block.on.buffer.full 的配置来决定。
compression.type:none
#默认发送不进行压缩,这里其实可以配置一种适合的压缩算法,可以大幅度的减缓网络压力和Broker 的存储压力。
往期推荐 点击标题跳转