1.Kafka的设计时什么样的呢?

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

2.Producer是否直接将数据发送到broker的leader(主节点)?

是的,Producer 直接将数据发送到 broker leader(主节点),不需要在多个节点进行分发,为了帮助 producer 做到这点,所有的 Kafka 节点都可以及时的告知:哪些节点是活动的,目标 topic 目标分区的 leader 在哪。这样 Producer 就可以直接将消息发送到目的地了

3.Partition的数据如何保存到硬盘

Topic中的多个partition以文件夹的形式保存到 broker,每个分区序号从0递增,且消息有序.
Partition文件下有多个 segment(xxx.index,xxx.log)
segment文件里的大小和配置文件大小,可以根据要求修改默认为 1g。如果大小大于 1g 时,会滚动一个新的 segment 并且以上一个 segment 最后一条消息的偏移量命名

4.consumer是推还是拉?

采用pull拉取的模式
Pull 模式的另外一个好处是 consumer 可以自主决定是否批量的从 broker 拉取数据 。Push 模式必须在不知道下游consumer消费能力和消费策略的情况下决定是立即推送每条消息还是缓存之后批量推送。如果为了避免 consumer 崩溃而采用较低的推送速率,将可能导致一次只推送较少的消息而造成浪费。Pull 模式下,consumer 就可以根据自己的消费能力去决定这些策略。
Pull 有个缺点是,如果 broker 没有可供消费的消息,将导致 consumer 不断在循环中轮询,直到新消息到达。为了避免这点,Kafka 有个参数可以让 consumer阻塞知道新消息到达(当然也可以阻塞知道消息的数量达到某个特定的量这样就可以批量发送)。

5.讲一下主从同步

kafka允许topic的分区拥有若干个副本,这个数量是可以配置的。kafka会自动在每个副本上备份数据,所以当一个节点down掉的时候数据依然是可以使用的。kafka的副本功能不是必须的,可以只配置一个副本,这样其实就相当于只有一份数据。

6.Zookeeper对于Kafka的作用是什么?

zookeeper主要用在kafka集群中不同节点之间互相通信,在kafka中它被用于提交偏移量,因此如果节点在任何情况下都失败了,它都有可以从之前提交的偏移量中获取。除此之外还执行其他活动,比如:leader检测、分布式同步、配置管理、识别节点何时离开或链接集群、节点实时状态等。

7.kafka数据传输的事务定义有哪三种

(1)最多一次: 消息不会被重复发送,最多被传输一次,但也有可能一次不传输
(2)最少一次: 消息不会被漏发送,最少被传输一次,但也有可能被重复传输.
(3)精确的一次(Exactly once): 不会漏传输也不会重复传输,每个消息都传输被一次而且仅仅被传输一次,这是大家所期望的

8.Kafka判断一个节点是否还活着有那两个条件?

(1)节点必须可以维护和zookeeper的连接,zookeeper通过心跳机制检查每个节点的连接
(2)如果节点是个follower,它必须能及时同步leader的写操作,延时不能太久

9.Kafka与传统MQ消息系统之间有三个关键区别

(1)kafka持久化日志,这些日志可以被无限读取和无限期保留
(2)kafka是一个分布式系统,它以集群的方式运行,可以灵活伸缩,在内部通过复制数据提升容错能力和高可用性
(3)kafka支持实时的流式处理

10. Kafka新建的分区会在哪个目录下创建

在启动 Kafka 集群之前,我们需要配置好 log.dirs 参数,其值是 Kafka 数据的存放目录, 这个参数可以配置多个目录,目录之间使用逗号分隔,通常这些目录是分布在不同的磁盘上用于提高读写性能
当然我们也可以配置 log.dir 参数,含义一样。只需要设置其中一个即可。 如果 log.dirs 参数只配置了一个目录,那么分配到各个 Broker 上的分区肯定只能在这个目录下创建文件夹用于存放数据。
但是如果 log.dirs 参数配置了多个目录,那么 Kafka 会在哪个文件夹中创建分区目录呢? 答案是:Kafka 会在含有分区目录最少的文件夹中创建新的分区目录,分区目录名为 Topic 名+分区 ID。注意,是分区文件夹总数最少的目录,而不是磁盘使用量最少的目录!也就是说,如果你给 log.dirs 参数新增了一个新的磁盘,新的分区目录肯定是先在这个新的磁 盘上创建直到这个新的磁盘目录拥有的分区目录不是最少为止

11.kafka的ack(acknowledgement 确认收到)的三种机制[重点]

request.required.acks 有三个值 0 1 -1(all)
0:producer 不会等待brokerack,该操作提供了最低的延迟,当server节点挂掉的时候就会丢失数据
1:producer会等待ack值,leader副本确认接收到消息后发送ack,但是如果leader挂掉后,他不确保是否复制完成,新leader也会导致数据丢失
-1(all):服务端会等待所有follower的副本收到数据才会收到leader发出的ack,这样数据不会丢失.但是如果在 follower 同步完成后,broker 发送 ack 之前,leader 发生故障,那么会造成数据重复

12.消费者负载均衡策略

一个消费者组中的一个分片对应一个消费者成员,他能保证每个消费者成员都能访问。
如果组中成员太多,会有空闲的成员

13.kafaka生产数据时数据的分组策略

生产者决定数据产生到集群的哪个 partition
每一条消息都是以(keyvalue)格式
Key 是由生产者发送数据传入
所以生产者(key)决定了数据产生到集群的哪个 partition

14.数据有序

一个消费者组里它的内部是有序的
消费者组与消费者组之间是无序的

15.kafka 分布式(不是单机)的情况下,如何保证消息的顺序消费?

kafka分布式的单位是partition,同一个partition用一个write ahead log,所以可以保证fifo的顺序。不同partition之间不能保证顺序。但是绝大多数用户可以通过message key来定义,因为同一个keymessage可以保证只发送到同一个partition.
Kafka 中发送 1 条消息的时候,可以指定(topic, partition, key) 3 个参数。partiton key 是可选的。如果你指定了 partition,那就是所有消息发往同 1个 partition,就是有序的。并且在消费端,Kafka 保证,1 个 partition 只能被1 个 consumer 消费。或者你指定 key( 比如 order id),具有同 1 个 key 的所有消息,会发往同 1 个 partition

16.kafka 的高可用机制是什么?

17.kafka 如何减少数据丢失

Kafka到底会不会丢数据(data loss)? 通常不会,但有些情况下的确有可能会发生。下面的参数配置及Best practice列表可以较好地保证数据的持久性(当然是trade-off,牺牲了吞吐量)。

  • block.on.buffer.full = true
  • acks = all
  • retries = MAX_VALUE
  • max.in.flight.requests.per.connection = 1
  • 使用KafkaProducer.send(record, callback)
  • callback逻辑中显式关闭producer:close(0)
  • unclean.leader.election.enable=false
  • replication.factor = 3
  • min.insync.replicas = 2
  • replication.factor > min.insync.replicas
  • enable.auto.commit=false
  • 消息处理完成之后再提交位移

18.kafka 如何不消费重复数据?比如扣款,我们不能重复的扣

其实还是得结合业务来思考,我这里给几个思路:
比如你拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了,update 一下好吧。
比如你是写 Redis,那没问题了,反正每次都是 set,天然幂等性。
比如你不是上面两个场景,那做的稍微复杂一点,你需要让生产者发送每条数据的时候,里面加一个全局唯一的 id,类似订单 id 之类的东西,然后你这里消费到了之后,先根据这个 id 去比如 Redis 里查一下,之前消费过吗?如果没有消费过,你就处理,然后这个 id 写 Redis。如果消费过了,那你就别处理了,保证别重复处理相同的消息即可。
比如基于数据库的唯一键来保证重复数据不会重复插入多条。因为有唯一键约束了,重复数据插入只会报错,不会导致数据库中出现脏数据。

19.kafka follower如何与leader同步数据

Kafka的复制机制既不是完全的同步复制,也不是单纯的异步复制。完全同步复制要求All Alive Follower都复制完,这条消息才会被认为commit,这种复制方式极大的影响了吞吐率。而异步复制方式下,Follower异步的从Leader复制数据,数据只要被Leader写入log就被认为已经commit,这种情况下,如果leader挂掉,会丢失数据,kafka使用ISR的方式很好的均衡了确保数据不丢失以及吞吐率。Follower可以批量的从Leader复制数据,而且Leader充分利用磁盘顺序读以及send file(zero copy)机制,这样极大的提高复制性能,内部批量写磁盘,大幅减少了Follower与Leader的消息量差。

20.什么情况下一个 broker 会从 isr中踢出去

leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-sync Replica),每个Partition都会有一个ISR,而且是由leader动态维护 ,如果一个follower比一个leader落后太多,或者超过一定时间未发起数据复制请求,则leader将其重ISR中移除 ,详细参考 kafka的高可用机制

21.在 Kafka 3.0.0 中,Kafka 项目中的所有组件都已弃用对 Java 8、Scala 2.12 的支持,宣布弃用,但 3.0.0 还能用,这次宣布只是给用户一个调整的时间,到了 Kafka 4.0,Java 8、Scala 2.12 将将正式取消支持。