kafka消息队列 | 青训营笔记

143 阅读3分钟

这是我参与「第三届青训营-后端场」笔记创作活动的第一篇笔记

前言

在青训营抖音项目开发的过程中,我的小组使用了MySQL来进行数据的储存。但是我们逐渐发现,当需要查询,储存的模块越来越多的时候,每一个模块和功能的耦合度和重复度可能较高。但是又没有办法轻易修改,因为可能牵一发而动全身。这时候怎么办?本质上,这是一个数据集成问题。没有任何一个系统能够解决所有的事情,所以业务数据根据不同用途存而放在不同的系统,比如归档、分析、搜索、缓存等。本身没有任何问题,但是不同系统之间像意大利面条一样复杂的数据同步却是挑战。这时候就轮到Kafka出场了。Kafka可以让合适的数据以合适的形式出现在合适的地方。Kafka的做法是提供消息队列,让生产者单往队列的末尾添加数据,让多个消费者从队列里面依次读取数据然后自行处理。之前连接的复杂度是O(N^2),而现在降低到O(N),扩展起来方便多了。

课程案例分析:

案例1. 系统崩溃。

QQ截图20220531015128.png

这时候我们发现,如果记录储存发生了故障,整个系统都会被阻塞。

解决方案:解耦

案例2. 服务能力有限。

举例:在大量用户抢购某一个商品的时候,订单程序如何处理百万级千万级别的请求呢?

QQ截图20220531015432.png

解决方案:削峰

案例3. 链路耗时长尾。

举例:当用户下单过后,如果按照如图的处理方式的话,用户会在点击下单后等待长达30秒之后才能收到反馈。也就是会在某一个页面卡住30秒。

QQ截图20220531015537.png

解决方案:异步

案例4. 日志储存

举例:如果有服务器故障,日志丢失我们应该怎么办?

什么是消息队列?

如果不看我们的前言,我们可以简单理解为消息队列是一个保存消息的队列。但是这个队列需要支持高并发,高吞吐和高可用。

使用场景

如我前面所说。在开发青训营项目的时候,会有用户的评论,点赞,关注等操作。如果使用MySQL的话,一次行为可能会触发多次的查询或更新行为。所以在这个时候我们就可以使用kafka。

如何使用kafka

1.创建集群
2.新增Topic
3.编写生产者逻辑(消息塞入队列)
4.编写消费者逻辑(消息从队列提取)\

基本概念

QQ截图20220531021152.png

Offset

Offset: 消息在partition内的相对位置信息。可以理解为偏移量或者唯一ID。严格递增。

Replica

Replica: 消息的副本。每一个partition会有多个replica。leader replica会从ISR中选出。生产者会先将消息写入leader replica,然后其余的副本replica会再从leader replica中拉取消息。当然,消费者取走消息也是从leader replica中取走的。多用于分布式。如果我leader所在的服务器出现故障,则可以在ISR中选择一个replica做为替换。

数据复制

QQ截图20220531021813.png

帮助kafka提高吞吐量和稳定性的方法

producer:批量发送,数据压缩。
broker:顺序写,消息索引,零拷贝。
consumer:rebalance。

kafka 的缺点

重启,替换,扩缩容成本高。因为需要追赶当前leader的数据进度。
负载不均衡:当某一个partion过大的时候,需要迁移。迁移又会导致新的IO开销。陷入死循环。解决方案极度复杂。
运维成本高。
没有自己的缓存,完全依赖page cache。灵活性低。
如果controller,coordinator和broker在同一个进程中,大量的IO操作会造成性能下降。