【中间件开发】kafka使用场景与设计原理

news/2025/2/22 6:17:41

文章目录

  • 前言
  • 一、MessageQueue
    • 1.1 定义
    • 1.2 使用消息队列的场景
      • 1.2.1 异步处理
      • 1.2.2 流量控制
      • 1.2.3 服务解耦
      • 1.2.4 发布订阅
      • 1.2.5 高并发缓冲
      • 1.3 基本概念和原理
        • 1.3.1 点对点消息队列模型 -- 线程池
        • 1.3.2 发布订阅消息模型-Topic --上课通知
        • 1.3.3 消息的ACK确认机制
  • 二、Kafka
    • 2.1 Kafka的架构设计及名词解释
    • 2.2 工作流程
      • 2.2.1 Producer
        • 分区策略
      • 2.2.2 Consumer
        • 消费方式
        • 分区分配策略
    • 2.3 partition和topic的关系
  • 总结


前言

本文首先介绍了消息队列,然后详细阐述了Kafka的架构设计和工作流程。


一、MessageQueue

1.1 定义

消息 + 队列 (Message + Queue) 简称 MQ。消息队列本质就是个队列,FIFO 先入先出,只不过队列中存放的内容是 Message,从而叫消息队列。消息队列的主要用途就是在不同的服务server、进程process、线程thread之间进行通信。

Q:那么是如何进行通信的呢?

1.2 使用消息队列的场景

1.2.1 异步处理

场景:短信通知、终端状态推送、App推送、用户注册等。

image.png

image.png

很明显,同步处理的性能远不如可并发的异步处理,多线程处理“库存”是趋势。

1.2.2 流量控制

场景:秒杀场景下的下单状态。

image.png

这种场景下网关生产的消息远大于服务器处理的速度,使用消息队列隔离网关和后端服务,以达到流量控制和保护后端服务的目的。

1.2.3 服务解耦

可以使用消息队列将各系统进行隔离,以达到修改更少的代码的目的,逻辑层次也更清晰。

image.png

使用消息队列:
image.png

消息队列在这里充当了一个中介的位置,各系统只需分清生产和消费的位置即可通过消息队列进行通信。

1.2.4 发布订阅

在一些跨服游戏中,当玩家对全服进行喊话,或者系统进行播报的操作。这些展现出来的消息就是通过消息队列,按着先进先出的规则播报出来的。

比如广播用户获得高阶武器的消息。

1.2.5 高并发缓冲

场景:kafka日志服务、监控上报

image.png

1.3 基本概念和原理

1.3.1 点对点消息队列模型 – 线程池

image.png

消息生产者向一个特定的队列发送消息,消息消费者从该队列中接收消息;一条消息只有一个消费者能收到;

1.3.2 发布订阅消息模型-Topic --上课通知

image.png

发布订阅消息模型中,支持向一个特定的主题 Topic 发布消息,0 个或多个订阅者接收来自这个消息主题的消息。 在这种模型下,发布者和订阅者彼此不知道对方。当发布者向这个主题发布消息,然后所有的订阅者会接收这个消息。

1.3.3 消息的ACK确认机制

为了保证消息的不丢失,消息队列中提供了消息的 ACknowledge 机制,即 ACK 机制。当消费者确认这个消息已经消费掉了,那么会向消息队列发送一个 ACK,消息队列收到后会将这个消息进行删除。但是当系统宕机,消息队列并未收到 ACK 的话,消息队列会认为这个消息并未被消费掉,便会将这个消息继续发送给其他的消费者重新处理。这样 ACK 的实时性会牺牲一定的吞吐量。

二、Kafka

解耦:允许我们独立的扩展或修改队列两边的处理过程。
可恢复性:即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
缓冲:有助于解决生产消息和消费消息的处理速度不一致的情况。
灵活性和峰值处理能力:不会因为突发的超负荷的请求而完全崩溃,消息队列能够使关键组件顶住突发的访问压力。
异步通信:消息队列允许用户把消息放入队列但不立即处理它。

典型应用:链接

2.1 Kafka的架构设计及名词解释

image.png

Producer:消息生产者,向 Kafka Broker 发消息的客户端。
Consumer:消息消费者,从 Kafka Broker 取消息的客户端。
Consumer Group:消费者组(CG),消费者组内每个消费者负责消费不同分区的数据,提高消费能力。一个分区只能由组内一个消费者消费,消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
Broker:一台 Kafka 机器就是一个 Broker。一个集群 (kafka C1uster) 由多个 Broker 组成。一 个 Broker 可以容纳多个 topic。
topic:可以理解为一个队列,topic 将消息分类,生产者和消费者面向的是同一个 topic。
Partition:为了实现扩展性,提高并发能力,一个非常大的 topic 可以分布到多个 Broker (即服务器)上,一个 topic 可以分为多个 Partition,同一个 topic 在不同的分区的数据是不重复的,每个 Partition 是一个有序的队列,其表现形式就是一个一个的文件夹。
Replication:每一个分区都有多个副本,副本的作用是做备胎。当主分区(Leader)故障的时候 会选择一个备胎(Follower)上位,成为 Leader。在 kafka 中默认副本的最大数量是 10 个,且副本的数量不能大于 Broker 的数量,follower 和 leader 绝对是在不同的机器,同一机器对同一个分区也 只可能存放一个副本(包括自己)。
Message:消息,每一条发送的消息主体。
Leader:每个分区多个副本的 “主” 副本,生产者发送数据的对象,以及消费者消费数据的对象,都是 Leader。
Follower:每个分区多个副本的 “从” 副本,实时从 Leader 中同步数据,保持和 Leader 数据的同 步。Leader 发生故障时,某个 Follower 还会成为新的 Leader。
Offset:消费者消费的位置信息,监控数据消费到什么位置,当消费者挂掉再重新恢复的时候,可以从消费位置继续消费。同一主题,不同的分区,他们的 offset 是独立的。
ZooKeeper:Kafka 集群能够正常工作,需要依赖于 ZooKeeper,ZooKeeper 帮助 Kafka 存储和管理集群信息。


在这里还需要注意,一个Partition下有多个segment,segment下由.log和.index文件组成,.index文件用于索引.log中的最终文件位置。

2.2 工作流程

image.png

在上述工作图中可以发现副本被存储在不同的Broker中,这些副本同样需要和leader通过ACK机制保持通信。Kafka数据冗余主要是为了系统高可用和高持久性,而fastdfs、mongodb可以通过副本机制提高读的请求量。

2.2.1 Producer

image.png

Producer在写入数据时永远只会找leader。

分区策略

决定生产者将消息发送到那个分区的算法。

  1. 轮询策略:每个分区按顺序每次分配一条消息;
  2. 随机策略:随意地将消息放置到任意一个分区上;
  3. 按消息键保序策略:一旦消息被定义了 Key,那么你就可以保证同一个 Key 的所有消息都进入到相同的分区里面;
  4. 默认分区规则:
    1. 指明 Partition 的情况下,直接将给定的 Value 作为 Partition 的值。
    2. 没有指明 Partition 但有 Key 的情况下,将 Key 的 Hash 值与分区数取余得到 Partition 值。
    3. 既没有 Partition 有没有 Key 的情况下,第一次调用时随机生成一个整数(后面每次调用都在这个整数上自增),将这个值与可用的分区数取余,得到 Partition 值,也就是常说的 Round-Robin轮询算法

2.2.2 Consumer

传统的消息队列模型的缺陷在于消息一旦被消费,就会从队列中被删除(zeromq),而且只能被下游的一个Consumer消费。严格来说,这一点不算是缺陷,只能算是它的一个特性。但是这种模型的可伸缩性差。

Kafka使用Consumer Group机制,实现了两大模型:

  1. 如果所有实例(消费者)都属于同一个 Group,那么它实现的就是点对点消息队列模型;
  2. 如果所有实例(消费者)分别属于不同的 Group,那么它实现的就是发布 / 订阅模型。

image.png

消费方式

Consumer 采用 **Pull(拉取)**模式从 Broker 中读取数据。Pull 模式则可以根据 Consumer 的消费能力以适当的速率消费消息。Pull 模式不足之处是,如果 Kafka没有数据,消费者可能会陷入循环中,一直返回空数据。

因为消费者从 Broker 主动拉取数据,需要维护一个长轮询,针对这一点, Kafka 的消费者在消费数据时会传入一个时长参数 timeout。如果当前没有数据可供消费,Consumer 会等待一段时间之后再返回,这段时长即为 timeout。

分区分配策略

一个消费者组中有多个 consumer,一个 topic 有多个 partition,所以必然会涉及到 partition 的分配问题。

  • Range:针对每个 topic。将 topic 中的分区与消费者排序,通过分区数/消费者数决定每个消费者消费几个分区,若除不尽则前面几个消费者会多消费1个分区。注意,如果有N个 topic,容易产生数据倾斜
  • RoundRobin:针对集群中的所有 topic。把所有分区和所有的消费者都列出来,然后按照hashcode 进行排序,最后通过轮询算法来分配分区给到各个消费者
  • Sticky:粘性分区从 0.11.x 版本开始引入,首先会尽量均衡的放置分区到消费者上面,在出现同一消费者组内消费者出现问题的时候,会尽量保持原有分配的分区不变化
  • CooperativeSticky: 在不停止消费的情况下进行增量再平衡。这与 Sticky 的逻辑相同,但具有增量支持。这种策略可能会产生不平衡的分配。

2.3 partition和topic的关系

  • 一个分区只能属于一个主题

  • 一个主题可以有多个分区

  • 同一主题的不同分区内容不一样,每个分区有自己独立的 offset

  • 同一主题不同的分区能够被放置到不同节点的 broker

  • 分区规则设置得当可以使得同一主题的消息均匀落在不同的分区


为什么会分区? ---- 可以水平扩展
Kafka 的消息组织方式实际上是三级结构:主题 - 分区 - 消息。主题下的每条消息只会保存在某一个分区中,而不会在多个分区中被保存多份。

分区的作用主要提供负载均衡的能力,能够实现系统的高伸缩性(Scalability)。


总结

本文首先介绍了消息队列,然后详细阐述了Kafka的架构设计和工作流程。Kafka通过自身的分区策略、副本冗余机制、ACK确认机制等保证了消息队列的高可用、高性能和高伸缩性。

参考链接:
https://github.com/0voice


http://www.niftyadmin.cn/n/5861766.html

相关文章

卷积与动态特征选择:重塑YOLOv8的多尺度目标检测能力

文章目录 1. YOLOv8的网络结构概述2. 添加注意力机制2.1 为什么添加注意力机制?2.2 如何将注意力机制集成到YOLOv8中?2.3 效果分析 3. C2f模块的集成3.1 C2f模块简介3.2 如何在YOLOv8中集成C2f模块?3.3 效果分析 4. 卷积操作的优化4.1 卷积操…

ABAP数据库表的增改查

数据表的增改查 接到一个任务,是对数据库表的增改查,增和查现在已经比较熟练了,关键是改,还有一个要求是要求系统能自动更新修改人和修改日期以及时间。 找到数据库表,新增这三个字段 这里另提一句,一般数…

【C/C++】合并两个有序链表 (leetcode T21)

核心考点预览:链表 (双指针) 技巧:虚拟头结点 题目描述: 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例: 输入输出示例1l1 [1,2,4], l2 [1…

3D全景沉浸式看车:虚拟现实重构汽车消费新体验

在传统的汽车消费模式中,消费者往往需要亲自前往展厅,花费大量时间和精力去挑选心仪的车型。这一过程不仅成本高,而且信息的透明度也常常受到质疑。面对琳琅满目的车型,消费者往往难以在短时间内做出决策,而车企则面临…

windows上vscode cmake工程搭建

安装vscode插件: 1.按装fastc(主要是安装MinGW\mingw64比较方便) 2.安装C,cmake,cmake tools插件 3.准备工作完成之后,按F1,选择cmake:Quick Start就可以创建一个cmake工程。 4.设置Cmake: G…

每日一题——打家劫舍

打家劫舍(一)与打家劫舍(二)动态规划解法详解 打家劫舍(一)问题描述示例解题思路动态规划 代码实现复杂度分析 打家劫舍(二)问题描述示例解题思路环形问题的拆分 代码实现复杂度分析…

豆包 Marscode + deepseek-R1 使用体验

拥抱 deepseek 这次豆包 Marscode 的新特性,是可以选择当下最热门的 deepseek 的两款模型:V3 和 R1,这让原本好用的 ai 插件,更加好用了,而且是免费使用,程序员的生产力再一次得到提升。 使用过程中的几…

OSPF基础知识总结

基本概念 协议类型:链路状态型IGP(内部网关协议),基于Dijkstra算法计算最短路径树。 协议号:IP层协议,协议号89。 特点:支持分层设计(区域划分)、快速收敛、无环路、支持VLSM/CIDR。 区域(Area) 骨干区域(Backbone Area):Area 0,所有非骨干区域必须直接或通过虚…