Kafka面试题2020版本

  1. Kafka同步(sync)、 异步(async)发送的区别:
    1. sync:这个生产者写一条消息的时候,它就立马发送到某个分区去。follower还需要从leader拉取消息到本地,follower再向leader发送确认,leader再向客户端发送确认。由于这一套流程之后,客户端才能得到确认,所以很慢。
    2. async:这个生产者写一条消息的时候,先是写到某个缓冲区,这个缓冲区里的数据还没写到broker集群里的某个分区的时候,它就返回到client去了。虽然效率快,但是不能保证消息一定被发送出去了
  2. Kafka中的ISR、AR又代表什么?ISR的伸缩又指什么
    1. ISR:In-Sync Replicas 副本同步队列
    2. AR:Assigned Replicas 所有副本
    3. OSR:Outof-Sync Replicas副本不同步队列
    4. AR=ISR+OSR
    5. ISR是由leader维护,follower从leader同步数据有一些延迟(包括延迟时间replica.lag.time.max.ms和延迟条数replica.lag.max.messages两个维度),任意一个超过阈值都会把follower剔除出ISR, 存入OSR(Outof-Sync Replicas)列表,新加入的follower也会先存放在OSR中
  3. 什么情况下一个 broker 会从 isr中踢出去
    1. leader会维护一个与其基本保持同步的Replica列表,该列表称为ISR(in-sync Replica),每个Partition都会有一个ISR,而且是由leader动态维护 ,如果一个follower比一个leader落后太多,或者超过一定时间未发起数据复制请求,则leader将其重ISR中移除 
  4. kafka节点之间如何复制备份的?(备份机制是Kafka0.8版本的新特性)
    1. kafka使用Zookeeper实现leader选举。如果leader失败,controller会从ISR选出一个新的leader
    2. Leader处理此分区的所有的读写请求,而follower被动的复制数据。(所有的写都发给leader, 然后leader将消息发给follower。)
    3. 一个Broker既可能是一个分区的leader,也可能是另一个分区的follower。kafka实际是保证在ISR写入成功的情况下就认为消息写入成功,而不是全部写入成功
    4. kafka使用ISR的方式很好的均衡了确保数据不丢失以及吞吐率
    5. ISR的副本保持和leader的同步,当然leader本身也在ISR中。初始状态所有的副本都处于ISR中,当一个消息发送给leader的时候,leader会等待ISR中所有的副本告诉它已经接收了这个消息,如果一个副本失败了,那么它会被移除ISR。下一条消息来的时候,leader就会将消息发送给当前的ISR中节点了
  5. Kafka在zookeeper保存的元数据有哪些?
    1. consumer、config、admin、broker、controller
  6. 如何保证数据的可靠性
    1. kafka 在 Producer 里面提供了消息确认机制来实现消息的可靠性(设置acks参数)
    2. Kafka 的分区多副本架构是 Kafka 可靠性保证的核心
  7. 如何保证数据的一致性
    1. 数据一致性主要是说不论是老的 Leader 还是新选举的 Leader,Consumer 都能读到一样的数据
    2. 只有 High Water Mark 以上的消息才支持 Consumer 读取,而 High Water Mark 取决于 ISR 列表里面偏移量最小的副本(也就是说消费只能读取leader和follower中都有的数据,leader中有但是follower中没有的数据消费着读取不到来实现的)
  8. Kafka中是怎么体现消息顺序性的
    1. kafka每个partition中的消息在写入时都是有序的,消费时,每个partition只能被每一个group中的一个消费者消费,保证了消费时也是有序的
    2. 整个topic不保证有序。如果为了保证topic整个有序,那么将partition调整为1
  9. partition 的数据如何保存到硬盘
    1. topic 中的多个 partition 以文件夹的形式保存到 broker,每个分区序号从 0 递增,且每个分区内部消息有序
    2. Partition 文件下有多个 segment文件(xxx.index,xxx.log)
    3. segment文件里的大小可以根据要求修改(默认为 1g)
    4. 如果大小大于 1g 时,会滚动一个新的segment,并且以上一个 segment最后一条消息的偏移量命名
  10. Kafka 与传统消息系统之间有三个关键区别
    1. Kafka 持久化日志系统:这些日志可以被重复读取和无限期保留
    2. Kafka 是一个分布式系统:它以集群的方式运行,可以灵活伸缩,在内部通过复制数据,提升容错能力和高可用性
    3. Kafka 支持实时的流式处理
  11. Kafka 创建 Topic 时如何将分区放置到不同的 Broker 中
    1. 副本因子不能大于 Broker 的个数
    2. 第一个分区的第一个副本放置位置是随机从 brokerList 选择的
    3. 其他分区的第一个副本放置位置相对于第1个分区依次往后移
  12. kafka中消息传递的过程
    1. 生产者发送消息阶段:
      1. 将消息存入Kafka中时,生产者根据配置的分片算法,分配到一个partition 中(在发送一条消息时,可以指定这条消息的 key,Producer 根据这个 key 和 Partition 机制来判断应该将这条消息发送到哪个 Parition)
      2. Paritition 机制可以通过指定 Producer 的 paritition.class 这一参数来指定,该 class 必须实现 kafka.producer.Partitioner 接口
      3. 随后生产者与该 Partition Leader 建立联系,之后将消息发送至该 partition leader。之后生产者会根据设置的 request.required.acks 参数不同,选择等待或或直接发送下一条消息
    2. Kafka存储消息阶段:
      1. 当 Kafka 接收到消息后,其并不直接将消息写入磁盘,而是先写入内存中。之后根据生产者设置参数的不同,选择是否回复 ack 给生产者
      2. 之后有一个线程会定期将内存中的数据刷入磁盘,这里有两个参数控制着这个过程:log.flush.interval.messages=1,那么每次来一条消息,就会刷一次磁盘。通过这种方式,就可以达到消息绝对不丢失的目的,这种情况我们称之为同步刷盘。反之,我们称之为异步刷盘
      3. Kafka 服务器也会进行副本的复制,该 Partition 的 Follower 会从 Leader 节点拉取数据进行保存。然后将数据存储到 Partition 的 Follower 节点中。
    3. 消费者拉取消息阶段:
      1. 在消费者启动时,其会连接到 zk 注册节点,之后根据所连接 topic 的 partition 个数和消费者个数,进行 partition 分配
      2. 接着消费者连接对应分区的 Kafka Server,并从该分区服务器拉取数据
  13. acks参数(acks参数,是在KafkaProducer端的参数)
    1. request.required.acks = 0 表示 Producer 不等待来自 Leader 的 ACK 确认,直接发送下一条消息。在这种情况下,如果 Leader 分片所在服务器发生宕机,那么这些已经发送的数据会丢失
    2. request.required.acks = 1 表示 Producer 等待来自 Leader 的 ACK 确认,当收到确认后才发送下一条消息。在这种情况下,消息一定会被写入到 Leader 服务器,但并不保证 Follow 节点已经同步完成。所以如果在消息已经被写入 Leader 分片,但是还未同步到 Follower 节点,此时Leader 分片所在服务器宕机了,那么这条消息也就丢失了,无法被消费到
    3. request.required.acks = -1 表示 Producer 等待来自 Leader 和所有 Follower 的 ACK 确认之后,才发送下一条消息。在这种情况下,除非 Leader 节点和所有 Follower 节点都宕机了,否则不会发生消息的丢失
  14. kafka的producer为什么会丢消息?如何防止数据丢失?
    1. Kafka消息发送分同步(sync)、异步(async)两种方式;Kafka保证消息被安全发送,acks有三个选项分别是0,1,-1;所以消息有六种发送场景
    2. 网络异常:acks设置为0时,不和Kafka集群进行消息接受确认,当网络发生异常等情况时,存在消息丢失的可能;
    3. Leader异常:acks设置为1时,Leader副本接收成功,Kafka集群就返回成功确认信息,而Follower副本可能还在同步。这时Leader副本突然出现异常,新Leader副本(原Follower副本)未能和其保持一致,就会出现消息丢失的情况;
    4. 客户端异常:异步发送时,消息并没有直接发送至Kafka集群,而是在Client端按一定规则缓存并批量发送。在这期间,如果客户端发生死机等情况,都会导致消息的丢失
    5. 缓冲区满了:异步发送时,Client端缓存的消息超出了缓冲池的大小,也存在消息丢失的可能;
    6. 总结:想要更高的吞吐量就设置:异步、ack=0;想要不丢失消息数据就选:同步、ack=-1
  15. Kafka消息的发送语义(消息传递保证)
    1. 至少一次:consumer可以先读取消息,处理消息,最后记录offset,当然如果在记录offset之前就crash了,新的consumer会重复的消费一些消息
    2. 最多一次:consumer可以先读取消息,然后将offset写入日志文件中,然后再处理消息。这存在一种可能就是在存储offset后还没处理消息就crash了,新的consumer继续从这个offset处理,那么就会有些消息永远不会被处理
    3. 恰好一次:在处理消息的时同时保存住每个消息的offset。以原子事务的方式保存offset和处理的消息结果。传统数据库实现原子事务比较简单。但对于非传统数据库,比如hdfs或者nosql,为了实现这个目标,只能将offset与消息保存在同一行
  16. 消费者提交offset方式:
    1. 在consumer消费阶段,对offset的处理,关系到是否丢失数据,是否重复消费数据,是否恰好只处理一次数据
    2. 自动提交:enable.auto.commit=true
      1. auto.commit.interval.ms:自动提交的间隔时间;默认是5秒钟提交一次,可以通过查看 kafka config目录下的配置文件,查询配置的默认值
      2. 导致重复消费:自动提交时,假设 1s 提交一次 offset 的更新,设当前 offset = 10,当消费者消费了 0.5s 的数据,offset 移动了 15,由于提交间隔为 1s,因此这一offset 的更新并不会被提交,这时候我们写的消费者挂掉,重启后,消费者会去 ZooKeeper 上获取读取位置,获取到的 offset 仍为10,它就会重复消费
      3. 导致数据丢失的隐患:开启了自动提交,那么系统会自动进行提交offset。可能会引起,并未消费掉,就提交了offset.引起数据的丢失(如:当你在pull(拉取)30条数据,在处理到第20条时自动提交了offset,但是在处理21条的时候出现了异常,当你再次pull数据时,由于之前是自动提交的offset,所以是从30条之后开始拉取数据,这也就意味着21-30条的数据发生了丢失)
    3. 手动提交:enable.auto.commit=false
      1. 当设置成false时,由于是手动提交的,可以处理一条提交一条,也可以处理一批,提交一批
      2. 由于consumer在消费数据时是按一个batch来的,当pull了30条数据时,如果我们处理一条,提交一个offset,这样会严重影响消费的能力
      3. 那就需要我们来按一批来处理,或者设置一个累加器,处理一条加1,如果在处理数据时发生了异常,那就把当前处理失败的offset进行提交(放在finally代码块中)注意一定要确保offset的正确性,当下次再次消费的时候就可以从提交的offset处进行再次消费
  17. 消费者的两种API:
    1. 高级API:在高阶消费者中,offset 采用自动提交的方式
    2. 低级API:在低级消费者中,offset 采用手动提交的方式
  18. kafka consumer如何防止数据丢失?
  19. kafka consumer如何确保只数据恰好消费一次?

猜你喜欢

转载自www.cnblogs.com/WeiKing/p/12926991.html