Kafka消息队列学习笔记 | 青训营

64 阅读4分钟

中间件——消息队列

对于新的技术产品,在学习之前首先肯定要知道为什么要用它。对于消息队列来说,它可以在很多场景下发挥重要的作用:解耦,异步,削峰。我们先通过以下四个实际案例,引入消息队列的概念和作用。

案例一:系统崩溃

6c6f88f9a465fd3d34fd2fe1b2f003e.png

  • 想象一个场景:用户打开抖音,搜索某个特定直播间,点击某个特定商品,这一连串行为(一条链路)都应被记录存储,但如果在存储一环中服务器发生了问题怎么办?

案例二:服务能力有限

087dbc1b4ab88aab0025bd7b0ee3aba.png* 想象一个场景:某购物节零点时刻,有大量用户在短时间内同时发起了订单,但服务器能力有限每次只能同时处理10个订单处理,如何解决?

案例三:链路耗时长尾

  • 想象一个场景:某用户在购买商品时,从下单到完成订单的步骤中,在某一步花费了过长的等待时间。如何优化?

案例四:日志存储

  • 假如服务器发生问题,程序在当天运行时的部分日志信息丢失,如何解决?

解决方案

案例一:解决方案:解耦

  • 将搜索行为、点击商品、点击行为的信息记录都发送到消息队列里,随后可以由存储服务来拉取消息队列中的消息(生产-消费模型)进行存储。此时,即便存储服务发生故障,但我们的记录都发送到了消息队列中,不会影响整个记录流程。

案例二:解决方案:削峰

  • 既然服务器处理能力有限,那我们可以将所有订单请求发送进消息队列,每次服务器处理订单时,每次只拉取10个请求进行处理。

案例三:解决方案:异步

8860aac7c639334ee33a8336b7480a2.png

  • 将发起订单的请求发送进消息队列,然后异步处理每个环节。

案例四:解决方案:日志处理

  • 把日志发送进消息队列。

由以上几个场景,可以看出消息队列(MQ)本质上是个队列,用于保存消息。具有三个特点:支持高吞吐、高并发、高可用。

消息队列模型-Kafka

  1. 使用场景
    • 日志信息、Metrics数据、用户行为。
  2. 如何使用
    • 创建集群——新增Topic——编写生产者逻辑——编写消费者逻辑
  3. 基本概念
    • 概念图,注意每个partition间是并发处理的。 96100f351cd70e314cbab341c1cd7a6.png
  • Offset:消息在partition内部相对位置信息,可以理解为唯一ID,严格递增。
  • Replica:每个partition有多个副本,以此达到容灾目的。有一个Leader和Follower的概念,由ISR(In-Sync Replicas)管理。
  1. 一条消息的自述:Producer->Broker->Comsumer,从三个环节来深入理解Kafka。
    • Producers
      • 单条发送不妨批量发送,将message做一个Batch批量处理,减少IO次数。但如果单条消息很大,网络带宽不够怎么办?可以通过压缩算法减少。
    • Broker
      • 说白了就是消息队列的服务器。数据的存储。Producer发送数据到Broker,采用末尾添加的机制(顺序写)存储到磁盘,效率较高。
      • 如何快速找到消息?通过上文提到的Offset,以二分方式寻找,当然也可以二分时间戳来索引文件。
      • 零拷贝技术,有效减少磁盘读写开销,提高性能。
    • Consumer-消息的接收端
      • 如何确定Comsumer要消费哪一块partition?
        • 可以手动提前分配,完全由业务需求决定:Low-Level
          • 缺点1:在于假如某个Consumer挂掉了,那么要被其消费的partition数据就丢失了
          • 缺点2:如果后续发现Consumer服务能力不够,要添加时,不得不涉及到机器和服务的启停。
        • High-Level:Rebalance机制,可以自动维护上述两种场景。这种机制的底层比较复杂,理解难度较高,能力有限这里就不记录了。
  2. 当然Kafka也是有一些缺点的,可以总结如下:
    • 运维成本高
    • 负载不均衡场景下解决方案复杂
    • 没有自己的缓存,完全依赖Page Cache
    • Controller和Coordinater和Broker在同进程中,大量IO会出现性能下降

文章总结:

理论还是比较抽象难懂的,希望能尽快实践一下。