消息队列Kafka
基础应用:
“你们在哪些场景下使用了Kafka?(例如:异步点赞通知、更新Feed流)”
“如何保证消息不被重复消费?(幂等性)”
“如果消息积压了怎么办?”
深入原理:
“Kafka为什么能支持高吞吐量?”
“谈谈你对Kafka副本机制的理解。”
一、基础应用
1.“你们在哪些场景下使用了Kafka?(例如:异步点赞通知、更新Feed流)”
1.视频发布后的Feed流推送:
当用户上传视频并完成转码后,系统会通过Kafka发送消息到“feed-push”主题,触发后续的Feed流推送操作。这样可以实现异步处理,提高系统的响应速度。
2.大规模粉丝Feed推送分片处理:
对于拥有大量粉丝的用户,当他们发布新视频时,系统会将粉丝列表分片,并通过“feed-push-shard”主题发送分片消息。这样做是为了避免一次性推送大量数据导致性能问题,通过分片并行处理来提升推送效率。
3.解耦服务间通信:
使用Kafka作为消息中间件,实现了服务间的解耦。比如视频服务不需要直接调用Feed服务的接口,只需要发送消息到Kafka,Feed服务监听相应的主题即可处理相关业务逻辑。
2.“如何保证消息不被重复消费?(幂等性)”
1.利用Redis的幂等性操作:
在Feed推送服务中,我们使用Redis的ZSet数据结构来存储用户的Feed流。Redis的ZSet添加操作具有天然的幂等性,即使同一条消息被多次处理,也不会重复添加到用户的Feed流中。
2.幂等性设计原则:
我们在设计时就要确保这个操作是幂等的。例如,在处理关注事件时,如果用户已经关注了某个用户,再次处理关注事件不会产生副作用。
3.对消息去重:
我们可以在Redis中维护一个已处理消息的Set,确保处理过的信息被忽略掉。
4.一个合理的异常处理和重试机制:
在消费者端我们有异常处理和重试机制,当消息处理失败后,会记录日志并允许Kafka进行重试,但同时通过上述的幂等性设计确保充实不会产生副作用。
3.“如果消息积压了怎么办?”
增加并发+消息分片+批量处理+动态扩容
1.增加消费者并发度:
在demo03feed流推送服务的配置文件中,我们设置了Kafka消费者的并发度为5(concurrency:5),这样可以同时运行多个消费者线程来处理消息,提高消费速度。
2.消息分区策略:
对于大量粉丝用户采用分片策略,如果这个发布视频的用户粉丝超过10w,我们将会对其进行分片处理。
先做一个判断,在调用方法将消息分片发送到专门的主题,由专门的服务来处理,实现并行处理。
3.Redis批量操作优化:
在消费者处理消息时,我们使用了Redis的管道功能来批量执行操作,减少网络往返次数,提高处理效率。
4.动态扩容:
当消息积压严重时,我们可以动态增加消费者实例或者增加分区数量来提升消费者能力。
5.监控和警告:
我们采用了Spring Boot Admin和Zipkin来监控服务状态和追踪调用链,可以及时发现消息积压问题并进行处理。
二、深入原理
1.“Kafka为什么能支持高吞吐量?”
1.顺序写入磁盘:比随机写入性能高的多,接近于内存的读写速度;
2.批量处理:生产者和消费者都支持批量处理数据;
3.零拷贝技术:来传输数据,直接将数据从磁盘文件传输到网络接口,避免了不必要的数据复制和上下文转换。
4.分区机制:Kafka主题可以分为多个区,不同分区可以并行处理,同时每个分区又可以进一步细分为多个分段,建立了稀疏索引。
5.采用二进制存储;
6.使用异步处理。
2.“谈谈你对Kafka副本机制的理解。”
类型+分布+机制+故障恢复
1.Kafka有两个副本类型:
- Leader副本:每个分区有且仅有一个Leader副本,负责处理所有的读写请求
- Follower副本:其余副本为Follower,从Leader异步复制数据,不直接处理客户端请求
2.副本分布:
- 副本分布在不同的节点上,确保单点故障数据不丢失;
- 每个分区的副本数量由复制因子决定,通常设置为3
3.数据同步机制:
- Follower副本周期性从Leader拉取数据保持同步;
- Kafka使用ISR机制跟踪Leader保持同步的副本列表
4.故障恢复:
- 当Leader副本故障,Kafka会从ISR中的Follower副本中选取新的Leader
- 新的Leader必须在其他Broker上,防止同一节点故障导致数据不可用
5.优势:
- 可用性高;
- 数据冗余不易丢失;
- 负载分散,Leader压力小;
- 故障可自动回复。