本文为复习期间面试总结
从以下方面对kafka面试进行总结:基本原理架构/项目实践/生产者/消费者/协调者/存储层/控制器
常见概念
- Partition: kafka分区模型 每个分区都是一个有序的独立的不可变的记录序列,新的消息会不断-的追加到序列末尾,分区的offset都是从0开始。kafka只能保证消息在单个分区的有序
- Segment:partition物理上由多个segment组成
- Offset:偏移量 通过offset+partition+topic可以定位到唯一一条消息
- broke:消息代理服务器 可以认为是一台独立的机器
- Topic:消息主题
- ConsumerGroup:消费者组
- ISR:副本冗余[正在和主副本保持同步的备份副本 只要ISR中还有一个节点是存活的就能保证消息不丢失 主副本和备份副本都有消息,主挂可切换副]
- AR: 所有副本[包含主副本和正在同步的副本]
- OSR:被踢出ISR的叫OSR,当同步进度追上 会重新加入ISR
ZK作用
注册中心[作为共享存储保存了kafka集群和客户端的相关信息]
一般生产环境三台起部署 且部署基数台。
分区副本如何分配
只有一个节点:
所有的分区副本都会在文件存储根目录下:命名规则为 TopicName+分区序号 序号从0开始
有多节点:
每个节点有相等的机会分配分区的主副本。
副本分配算法:将所有节点和分区排序
主副本分配规则:将第i个分区分配到 第i%n个 节点上。
从副本分配规则:将第i个分区的第k个从副本分配到第(i+k)%n 个节点上。
partiton中文件存储方式
kafka高可用的
一般多机分布式部署 Kafka每个topic的partition有N个副本,其中N是topic的复制因子。Kafka通过多副本机制实现故障自动转移,当Kafka集群中一个Broker失效情况下仍然保证服务可用。
kafka消息模型
队列模型和发布订阅 kafka使用消费者组统一了上面2种消息模型。[队列1对1/订阅1对多]
kafka为什么这么快
写message
- 消息并不是直接写入磁盘,而是写入Page Chache[页缓存]。
- 由异步线程刷盘,消息从页缓存输入磁盘。
读message
- 先找页缓存区域 如果可以找到消息,直接socket返回消息。
- 找不到消息此时会在磁盘上读取,并加载到page cache。
其他:
- 零拷贝:指计算机操作的过程中,CPU不需要为数据在内存之间的拷贝消耗资源。而它通常是指计算机在网络上发送文件时,不需要将文件内容拷贝到用户空间(User Space)而直接在内核空间(Kernel Space)中传输到网络的方式。
- page cache: 放弃使用JVM管理内存,转而使用页缓存。
- 使用JVM内存会受到GC影响。且过大的堆空间容易降低吞吐量。
- JVM内的对象都需要保存object overhead[实例的type信息和内置monitor信息等]
kafka follower如何与leader同步数据/kafka节点之间消息如何备份的
leader也称为主副本 follower 也称为备份副本
Producer在push消息到kafka时,先通过ZK找到对应Topic下Partition的主副本[leader],Producer和leader建立联系发送消息,N个replicas中。其中一个replica为leader,其他都为follower,leader处理partition的所有读写请求,与此同时,follower会被动定期地去复制leader上的数据。
这种消息机制不能算完全的同步也不能算完全的异步
ISR HW LEO 之间的关系/流转过程
- ISR 正在主副本保持备份的副本
- HW high wather高水位 一般指的是ISR中同步主副本的进度最慢的副本当前正在同步的消息的offset,在HW之前的消息都可以被消费者拉取到
- LEO log end offset 当前主副本中正在写入的消息 一般是当前分区中最后一条消息的offset+1
当主副本有消息写入的时候,follower会主动向leader获取消息,每次读消息都会更新HW当HW大于等于LEO时候可以认为是同步完成,副本管理者会想producer报告ack确认消息保存成功。
项目实践
ACK 0 -1 1分别代表什么
- [-1] 也就all 需要等待ISR中所有都同步完成
- 1 默认的只需要等待主副本同步完成即可
- 0 不确认就开始发送下一条消息
kafka事务
kafka在较高版本上支持事务,但是我们使用的版本较低,且目前业务上无硬性需求。
消息队列丢失数据如何处理
这个问题可以分为三个方面 生产者 消费者 消息队列
- 生产者方面我们使用的异步回调的方式,在收到回调的时候若消息没有发送成功,我们会记录再次发送。
- 消费者 消费者的数据丢失可以认为是提交了offset但是数据处理失败了,我们使用的手动提交在处理成功后在提交offset 不会遇到这个问题。但是要注意消息处理时间不能过长,如果处理过长还没提交offset管理者可能会认为当前消费者下线从而触发reblance
- 消息队列数据丢失 我们在kafka配置了
ack = -1
要求所有ISR都确认同步了消息才给producer发送ack 所以可以保证消息不会丢失。
生产者
生产者消息发送的几种方式
同步阻塞 异步非阻塞 [都是通过send方法实现的]
生产者如何为消息选取分区的
若消息没有设置key loadblance写入partition。如设置了key murmur2(key) mod PartitionNum
简单讲下生产者的工作流程
- 主线程将消息封装到ProducerRecord[partition/key/value/key/时间戳]
- client对ProducerRecord进行序列化
- 根据分区策略确定分区[无key轮询有key murmur2(key) mod PartitionNum]
- 将消息放入缓存区[每一个分区对应一个双端队列] 由sender线程将一个批次的消息batch的消息发送到对应的broker
生产者如何批量的发送消息
sender的作用:归类消息为每个目标节点建立一个请求
sender线程并不真正发送客户端请求 sender线程会去遍历记录收集器中根据分区分好组的消息batches,将相同目标节点[NodeId]的batches的消息归类,为相同目标节点的[NodeId]创建一个请求发送消息。
-
消息放入记录收集器时会按分区进行分组,存放到对应的batches,分区队列保存了即将发送消息的批记录。
-
sender线程可以使用单线程迭代
消费者
什么是管理者
管理者是消费者组中的概念,用于对同一个消费者组中的所有消费者进行协调。
什么是reblance
简单来说就是消费者消费消息出现不均衡,会通过reblance达到动态平衡的过程。通常有如下几个方面
- 消费者组订阅的主题发生变化
- 消费者消费的分区数量出现变化
- 消费者组中的消费者数量发生变化
消费者什么时候会再次加入消费者组
消费者只有在出现reblance的时候会出现再次加入消费者,分为如下步骤1.消费者准备好自身状态2.和协调者发送加入消费者组的请求3.成功加入消费者组,分配分区开始消费消息。
2种消费模式
消费模式可分为订阅模式和分配模式
- 订阅模式 消费者订阅指定主题,由协调者协调消费的分区
- 分配模式 由消费者指定消费的分区。此时协调者不参与
我们项目中有4个分区,使用的订阅模式 设置了4个消费者。每个消费者独立消费一个分区[由协调者安排]
交付语义
- 精准一次
- 至多一次
- 至少一次
参考资料
- kafka实战
- kafka技术内幕
- kafka在公司项目实践