首页 > 技术文章 > kafka面试题

JoshWill 2020-06-08 14:41 原文

1.Kafka的作用

1)数据缓冲:将上游数据接收到消息队列中,暂时存放,下游服务可以按照自己的节奏进行处理。上游数据一旦有大量的突发流量,保证了下游服务不会受到影响。
2)解耦以及扩展:将上游服务和下游服务通过消息队列进行通信。消息队列可以作为一个接口层,只要上游服务以及下游服务遵守接口的规范,便可以随意添加新的服务器。
3)冗余及健壮性:一个消息被保存为多个副本,多个下游服务可以消息同一个消息。
4)异步通信:数据暂时存放在消息队列中,下游服务可以在需要的时候再去处理它。

2.Kafka消息发送机制

异步、批量、消息重试

Producer将消息经过KeySerializer、valueSerializer序列化后,经过Partition分区器处理,决定消息落到topic具体哪个分区中,最后将消息发送到客户端的消息缓冲池accumulator中,这个缓冲池的最大值默认为32M(buffer.memory)并交由一个Sender线程进行发送。消息在缓存池中会被分为一个个batch,每个batch默认大小为16KB(batch.size),消息一旦攒够该大小或超过最大空闲时间(linger.ms)将会被发送到broker。Producer通过参数(retries)控制消息发送的重试次数,由于网络抖动等原因,消息将会重新进行发送。

3.kafka中ack为0,1,-1代表啥

1)0代表生产者发送的消息一旦发送出去,不需要等待消息的确认,传输效率最高,但是可靠性无法保证
2)1代表生产者将消息发送出去,需要等待leader接收成功的消息确认,kafka默认为该值。
3)-1代表生产者将消息发送出去,需要等待ISR中所有的副本都接收成功。

4.kafka的unclean是啥

kafka中的一个配置unclean.leader.election.enable,新版本该值默认为false。一旦开启该配置,意味着在leader宕掉的情况下,非ISR中的follower也可以参与leader选举,这样就会造成数据的不一致情况的发生,消费者拿到的消息会重复。

5.kafka为什么不支持读写分离

kafka中消息的读写都会直接与leader进行交互,不会与follower进行交互,follower只是为了保证消息的可用性。kafka不支持读写分离主要因为:数据的延时问题以及因此导致的数据不一致性,follower在向leader进行数据拉取时,需要一定的时间,在这段时间内,follower内的数据与leader中的数据时不一致的。

6.kafka是否可以保证消息的顺序性

kafka不能保证整个topic中的消息是有序的,只能保证每个partition中的消息是有序的。

7.kafka中的consumer group是什么意思

consumer group是一个逻辑上的概念,多个消费者可以构成一个消费组,一个partition只能被消费组中的一个消费者所消费。但是多个消费组可以消费同一个partition。

8.什么情况下broker会从ISR中被踢出

leader负责维护ISR列表,每个Partition都会有一个ISR,如果其中一个follower超过10s(replica.lag.time.max.ms)没有向leader发起数据复制请求,则会被leader将其从ISR中移除。

9.如何避免消费端Rebalance

消费端的Rebalance就是让一个消费组内的所有消费者就如何消费topic的所有分区达成共识的过程,在Rebalance过程中,所有的Consumer实例都会停止消费,等待Rebalance的完成,严重影响消费端的TPS,所以应当尽量避免。
Rebalance发生的条件有三种:
1)消费组内的消费者成员数量发生变化
2)消费主题的数量发生变化
3)消费主题的分区数量发生变化
后面两种情况是不可避免的,所以我们能做的就是尽量避免第一种情况的发生
组内成员数量发生变化无非就两种情况,一种是为了提高消费速度增加了消费者组内的消费者数量,这种情况是正常的。另外一种情况是有消费者退出,这种情况需要避免。正常情况下,每个消费者都会定期向组协调器发送心跳,表明自己还存活,如果消费者不能及时的发送心跳,组协调器会被认为该消费者已经“死”了,就会导致消费者离组引发Rebalance问题。这里涉及到两个参数:session.timeout.ms和heartbeat.interval.ms分别为组协调器认为消费组存活的期限和消费者发送心跳的时间间隔。max.poll.interval.ms为consumer两次拉取数据的最大时间间隔,超过这个时间,也会导致消费者离组。另外,如果Consumer端频繁进行FullGC也会导致消费端长时间停顿,引发Rebalance。为了解决这个问题,主要从以下方面入手:
1)合理配置session.timeout.ms和heartbeat.interval.ms,避免因心跳发送超时导致的Rebalance。
2)调整max.poll.interval.ms的大小
3)监控消费这的GC情况

10.kafka是否有消息丢失以及消息重复的情况,如何解决

消息丢失:
1)request.required.acks属性设置为0,当网络异常,缓冲区满等情况,消息可能丢失
2)属性设置为1,leader确认接收,但是在副本进行同步之前挂掉了,数据可能丢失
解决方法:同步模式下,将属性设置为-1;异步模式下,不设置阻塞超时时间,当缓冲区满时让生产者一直处于阻塞状态

消息重复:主要针对的是消费者可能会重复读取相同消息的情况,消费者如果在处理了消息但是没有更新offset的情况下宕掉了,那么在它重启之后就会读取到之前已经处理过的数据。
解决方法:想要解决这种情况,就要保证消费端的幂等性,综合实际的情况来考虑。比如,将数据插入到数据库中可以先判断是否已经存在,如果存在,就不做插入处理等。

推荐阅读