当前位置: 首页 > 后端技术 > Java

Java面试题汇总(消息队列)

时间:2023-04-02 09:20:08 Java

14.消息队列《深入理解Kafka 核心设计与实践原理》Kafka先说说KafkaKafka是一个高性能的消息中间件,包括Producer、Consumer、Broker、Zookeeper,负责集群元数据管理、controller选举等操作,Producer将消息发送给Broker,Broker负责将接收到的消息存储到磁盘,Consumer负责订阅和消费来自Broker的消息。Kafka中的消息基于主题。主题可以分布在不同的分区中。分区可以分布在不同的Broker中。分区有一个领导者和一个副本跟随者。follower负责从leader同步数据,leader负责读写请求消息的幂等性。处理思路主要是防止消息重复消费,通过业务端保证消息的幂等性。每条消息都设置了唯一ID,数据库使用唯一索引。消息队列如何保证高可用Kafka可以有多个Borkers,一个topic会把数据存放在不同的partiton上,有多个副本来同步数据,但是只会有一个leader,数据会存放在硬盘中Log的形式,记录消费的offset。如果leader挂了,ISR集合中的一个副本将被选为leader。Kafka的新分区会创建在哪个目录下?在启动Kafka集群之前,我们需要配置log.dirs参数,其值为Kafka数据的存放目录。该参数可以配置多个目录,以逗号分隔,通常这些目录分布在不同的磁盘上,以提高读写性能。也可以配置log.dir参数,意义相同,只需要设置其中一项即可。如果log.dirs参数只配置了一个目录,那么分配给每个Broker的分区只能在该目录下创建文件夹用于存放数据。但是如果log.dirs参数配置了多个目录,Kafka会在分区目录最少的文件夹中新建一个分区目录,分区目录名称为Topic名称+分区ID。注意是分区文件夹数最少的目录,不是磁盘占用最少的目录。Kafka的ack机制ack有3个值01-10:producer不会等待borker返回,延迟最低但存储保证最弱当server挂掉时会丢失数据1:等待leader确认消息返回,但是如果leader挂了,不保证复制是否完成-1:等待所有replicas确认消息返回如何保证消息可靠性Kafka保证消息可靠性,可以通过如下配置:Producer配置acks=all(-1)ISR中的所有副本都写入成功,即消息发送成功。min.insync.replicas默认为1,它指定了ISR集中的最小副本数。不满足条件会抛出NotEnoughReplicasException或NotEnoughReplicasAfterAppendException,即必须保证有replica同步数据跟得上leaderrunclean.leader.election.enable。默认为假。当leader下线时,可以从non-ISRset中选举出新的leader,这样可以提高可用性,但是会丢失数据。配置log.flush.interval.messages和log.flush.interval.ms同步刷新策略。对于重复消费和消息丢失的问题,如果客户端消费消息失败,应该将其放入死信队列,以便后期排查和回溯消费函数。消息看似消费成功,实际消费失败。我不知道是什么导致了错误。可以通过回溯消耗来补偿,或者“丢失”可以重现。如果seek()方法中消息积压过大无法消费,则需要检查是不是消费者有问题,或者服务器上的磁盘是不是快满了。如果消费者有问题,解决问题。但是由于数据积压太多,用原程序消费还是太慢了。需要扩容,创建一个临时topic,把分区改成原来的10倍大小,写一个程序把原来积压的消息发送到新创建的topic,启动10倍的机器来消费这些数据,然后服务器磁盘已满,只能扩容服务端磁盘,然后使用第一种方法解决问题。Kafka的分区策略消费者客户端参数partition.assignment.strategy配置消费分区策略RangeAssignor默认分配策略是通过分区数/消费者总数得到一个span进行分配RoundRobinAssignorrounds查询分配策略StickyAssignor可以进行分配partition尽量和上次一致,避免自定义分配过多reallocation,实现PartitionAssignor接口