来源于网络
1.基础摸底
你们Kafka集群的硬盘一共多大?有多少台机器?日志保存多久?用什么监控的
集群硬盘大小:每天的数据量/70%日志保存天数
机器数量:Kafka 机器数量=2(峰值生产速度*副本数/100)+1
日志保存时间:可以回答保存7天
监控Kafka:一般公司有自己开发的监控器,或者cdh配套的监控器,另外还有一些开源的监控器
Kafka分区数、副本数和topic数量多少比较合适?
分区数一般设置为:3-10 个
副本数一般设置为:2-3个
topic数量需要根据日志类型来定,一般有多少个日志类型就定多少个topic,不过也有对日志类型进行合并的
Kafka中的HW、LEO、ISR、AR分别是什么意思
LEO:每个副本的最后一条消息的offset
HW:一个分区中所有副本最小的offset
ISR:与leader保持同步的follower集合
AR:分区的所有副本
Kafka中的消息有序吗?怎么实现的?
kafka无法保证整个topic多个分区有序,但是由于每个分区(partition)内,每条消息都有一个offset,故可以保证分区内有序
topic的分区数可以增加或减少吗?为什么?
topic的分区数只能增加不能减少,因为减少掉的分区也就是被删除的分区的数据难以处理
消费者组中的消费者个数如果超过topic的分区,那么就会有消费者消费不到数据
你知道kafka是怎么维护offset的吗?
1.维护offset的原因:由于consumer在消费过程中可能会出现断电宕机等故障,consumer恢复后,需要从故障前的位置的继续消费,所以consumer需要实时记录自己消费到了哪个offset,以便故障恢复后继续消费
- 维护offset的方式:Kafka 0.9版本之前,consumer默认将offset保存在Zookeeper中,从0.9版本开始,consumer默认将offset保存在Kafka一个内置的topic中,该topic为__consumer_offsets
消费者提交消费位移时提交的是当前消费到的最新消息的offset+1而不是offset。
你们是怎么对Kafka进行压测的?
Kafka官方自带了压力测试脚本(kafka-consumer-perf-test.sh、kafka-producer-perf-test.sh), Kafka 压测时,可以查看到哪个地方出现了瓶颈(CPU,内存,网络 IO),一般都是网络 IO 达到瓶颈
是什么确保了Kafka中服务器的负载平衡?
由于领导者的主要角色是执行分区的所有读写请求的任务,而追随者被动地复制领导者。因此,在领导者失败时,其中一个追随者接管了领导者的角色。基本上,整个过程可确保服务器的负载平衡。
什么是broker?作用是什么?
一个单独的kafka server就是一个broker,broker主要工作就是接收生产者发过来的消息,分配offset,之后保存到磁盘中。同时,接收消费者、其他broker的请求,根据请求类型进行相应的处理并返回响应,在一般的生产环境中,一个broker独占一台物理服务器
接收Producer发过来的数据,并且将它持久化,同时提供给Consumer去订阅
组成Kafka集群节点,之间没有主从关系,依赖ZooKeeper来协调,broker负责消息的读取和存储,一个broker可以管理多个partition
2.深入考察
创建或者删除topic时,Kafka底层执行了哪些逻辑?
在zookeeper中的/brokers/topics节点下创建一个新的topic节点,如:/brokers/topics/csdn;
然后会触发Controller的监听程序;
最后kafka Controller负责topic的创建工作,并更新metadata cache,到这里topic创建完成。
你了解Kafka的日志目录结构吗?
每个 Topic 都可以分为一个或多个 Partition,Topic其实是比较抽象的概念,但是 Partition是比较具体的东西;
其实Partition 在服务器上的表现形式就是一个一个的文件夹,由于生产者生产的消息会不断追加到log文件末尾,为防止log文件过大导致数据定位效率低下,Kafka采取了分片和索引机制,将每个partition分为多个segment;
每组 Segment 文件又包含 .index 文件、.log 文件、.timeindex 文件(早期版本中没有)三个文件。.log和.index文件位于一个文件夹下,该文件夹的命名规则为:topic名称+分区序号。例如,csdn这个topic有2个分区,则其对应的文件夹为csdn-0,csdn-1;
log 文件就是实际存储 Message 的地方,而 index 和 timeindex 文件为索引文件,用于检索消息
Message
一个Kafka的Message由一个固定长度的header和一个变长的消息体body组成。
header部分由一个字节的magic(文件格式)和四个字节的CRC32(用于判断body消息体是否正常)构成。当magic的值为1的时候,会在magic和crc32之间多一个字节的数据:attributes(保存一些相关属性,比如是否压缩、压缩格式等等);如果magic的值为0,那么不存在attributes属性。
body是由N个字节构成的一个消息体,包含了具体的key/value消息。
聊聊你对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 中。
聊聊Kafka分区分配策略?
重点
消费者的分区分配
每个主题一般会有很多个分区。为了使得我们能够及时消费消息,我们也可能会启动多个消费者去消费,而每个消费者又会启动一个或多个溪流去分别消费Topic里面的数据。我们又知道,Kafka存在Consumer Group的概念,也就是group.id一样的Consumer,这些Consumer属于同一个Consumer Group,组内的所有消费者协调在一起来消费订阅主题(订阅主题)的所有分区(分区)。当然,每个分区只能由同一个消费组内的一个消费者来消费
在Kafka内部存在两种默认的分区分配策略:Range和RoundRobin。当以下事件发生时,Kafka将会进行一次分区分配:
同一个Consumer Group内新增消费者
消费者离开当前所属的Consumer Group,包括关闭或崩溃
订阅的主题新增分区
将分区的所有权从一个消费者移到另一个消费者称为重新平衡(再平衡),如何再平衡就涉及到本文提到的分区分配策略。下面我们将详细介绍Kafka内置的两种分区分配策略。本文假设我们有个名为T1的主题,其包含了10个分区,然后我们有两个消费者(C1,C2)来消费这10个分区里面的数据,而且C1的num.streams = 1,C2的num.streams = 2。
范围策略
一系列策略是对每个主题而言的,首先对同一个主题里面的分区按照序号进行排序,并对消费者按照字母顺序进行排序。在我们的例子里面,排完序的分区将会是0,1,2,3,4,5,6,7,8,9;消费者线程排序将会是C1-0,C2-0,C2-1。然后将partitions的个数除于消费者线程的总数来决定每个消费者线程消费几个分区。如果除不尽,那么前面几个消费者线程将会多消费一个分区。在我们的例子里面,我们有10个分区,3个消费者线程,10/3 = 3,而且除除不尽,那么消费者线程C1-0将会多消费一个分区,所以最后分区分配的结果看起来是这样的:
C1-0 将消费 0, 1, 2, 3 分区
C2-0 将消费 4, 5, 6 分区
C2-1 将消费 7, 8, 9 分区
假如我们有11个分区,那么最后分区分配的结果看起来是这样的:
C1-0 将消费 0, 1, 2, 3 分区
C2-0 将消费 4, 5, 6, 7 分区
C2-1 将消费 8, 9, 10 分区
假如我们有2个主题(T1和T2),分别有10个分区,那么最后分区分配的结果看起来是这样的:
C1-0 将消费 T1主题的 0, 1, 2, 3 分区以及 T2主题的 0, 1, 2, 3分区
C2-0 将消费 T1主题的 4, 5, 6 分区以及 T2主题的 4, 5, 6分区
C2-1 将消费 T1主题的 7, 8, 9 分区以及 T2主题的 7, 8, 9分区
可以看出,C1-0消费者线程比其他消费者线程多消费了2个分区,这就是范围策略的一个很明显的弊端。
RoundRobin战略
必须满足如下条件
同一个Consumer Group里面的所有消费者的num.streams必须相等;
每个消费者订阅的主题必须相同
在我们的例子里面,加入按照hashCode排序完的主题 - 分区组依次为T1-5,T1-3,T1-0,T1-8,T1-2,T1-1,T1-4,T1-7, T1-6,T1-9,我们的消费者线程排序为C1-0,C1-1,C2-0,C2-1,最后分区分配的结果为:
C1-0 将消费 T1-5, T1-2, T1-6 分区;
C1-1 将消费 T1-3, T1-1, T1-9 分区;
C2-0 将消费 T1-0, T1-4 分区;
C2-1 将消费 T1-8, T1-7 分区;
Sticky
分区的分配要尽可能的均匀
分区的分配尽可能的与上次分配的保持相同
当两者发生冲突时,第一个目标优先于第二个目标
当Kafka消息数据出现了积压,应该怎么处理?
数据积压主要可以从两个角度去分析:
如果是 Kafka 消费能力不足,则可以考虑增加 Topic 的分区数,并且同时提升消费 组的消费者数量,消费者数=分区数。(两者缺一不可)
如果是下游的数据处理不及时:提高每批次拉取的数量。如果是因为批次拉取数据过少(拉取 数据/处理时间<生产速度),也会使处理的数据小于生产的数据,造成数据积压。
Kafka是怎么实现Exactly Once的?
idempotent + at least once = exactly once
谈谈你对Kafka幂等性的理解?
Producer的幂等性指的是当发送同一条消息时,数据在 Server 端只会被持久化一次,数据不丟不重,但是这里的幂等性是有条件的:
只能保证 Producer 在单个会话内不丟不重,如果 Producer 出现意外挂掉再重启是 无法保证的。因为幂等性情况下,是无法获取之前的状态信息,因此是无法做到跨会话级别的不丢不重。
幂等性不能跨多个 Topic-Partition,只能保证单个 Partition 内的幂等性,当涉及多个Topic-Partition 时,这中间的状态并没有同步。
你对Kafka事务了解多少?
Kafka是在0.11 版本开始引入了事务支持。事务可以保证 Kafka 在 Exactly Once 语义的基础上,生产和消费可以跨分区和会话,要么全部成功,要么全部失败。
- Producer 事务:
为了实现跨分区跨会话的事务,需要引入一个全局唯一的 Transaction ID,并将 Producer 获得的 PID 和 Transaction ID 绑定。这样当 Producer 重启后就可以通过正在进行的 Transaction ID 获得原来的 PID。
为了管理 Transaction,Kafka 引入了一个新的组件 Transaction Coordinator。Producer 就 是通过和 Transaction Coordinator 交互获得 Transaction ID 对应的任务状态。Transaction Coordinator 还负责将事务所有写入 Kafka 的一个内部 Topic,这样即使整个服务重启,由于 事务状态得到保存,进行中的事务状态可以得到恢复,从而继续进行。
- Consumer 事务:
上述事务机制主要是从Producer方面考虑,对于 Consumer 而言,事务的保证就会相对较弱,尤其时无法保证 Commit 的信息被精确消费。这是由于 Consumer 可以通过offset访问任意信息,而且不同的 Segment File生命周期不同,同一事务的消息可能会出现重启后被删除的情况。
Kafka怎么实现如此高的读写效率?
首先kafka本身是分布式集群,同时采用了分区技术,具有较高的并发度;
顺序写入磁盘,Kafka 的 producer 生产数据,要写入到 log 文件中,写的过程是一直追加到文件末端,为顺序写。
官网有数据表明,同样的磁盘,顺序写能到 600M/s,而随机写只有 100K/s。这 与磁盘的机械机构有关,顺序写之所以快,是因为其省去了大量磁头寻址的时间。零拷贝技术