Kafka的基本概念和Dokcer中部署Kafka

Kafka是消息队列的一种实现,类似的还有RocketMQ 和 RabbitMQ

消息队列的基本形态,就是有N个生产者,N个消费者

这种形态下,生产者和消费者就解耦了

Kafka中的基本概念

  • 生产者 producer
  • 消费者 consumer
  • broker 可以理解为消息服务器
  • topic与分区(partition)
  • 消费者组和消费者

Broker

Broker 的意思是"中间人",是一个逻辑上的概念。

在实际中,一个broker就是一个消息队列进程,也可以认为一个broker就是一台机器。

topic 和 分区

Topic 是消息队列上代表不同业务的东西

简单来说,一个业务场景就是一个topic。

一个topic有多个分区

需要多少分区:max(发送者总速率/单一分区写入速率,发送者总速率/单一消费者速率)+buffer

下图中topic1有两个分区,而topic2有一个分区

主分区和从分区

实际上,我们说某个topic有多少个分区的时候,指的是有多少个主分区。

但是事实上,Kafka为了保证高可用和数据不丢失,分区有主分区和从分区。

当发送消息到Kafka上的时候,Kafka会把消息写入主分区之后,再同步到从分区。

如下图所示,每一个分区实际上是一主两从(不是固定的规则)的结构。

分区和broker的关系

正常情况下,同一个topic的分区会尽量均匀分散到所有的broker上。

这意味着两件事:

  • 主分区之间,不会在同一个broker上。
  • 同一个分区的主分区和从分区,也不会在同一个broker上。

核心目标:保证当某个broker崩溃的时候,对业务的影响最小,满足上面两个要求的话,某一个broker崩溃,最多导致topic的某一个主分区不可用,不至于完全不可用。

分区和生产者的关系

正常情况下吗,一个topic 都会有多个分区,所以发送者在发送消息的时候,就需要选择一个目标分区

比较常用的有三种:

  • 轮询:一个分区发送一次,挨个轮流。
  • 随机:随机挑选一个。
  • 哈希:根据消息中的key来筛选一个目标分区。

遵循QPS均匀比较好

也可以自己设计一些比较复杂的路由策略,用在面试中效果会比较好。

分区和消息有序性

Kafka中的消息有序性保证是以分区为单位的。

也就是说,一个分区内的消息是有序的。即,消息在一个分区内的顺序,就是分区的消息被消费的顺序。

因此,如果要做到全局有序,就只能有一个分区。

如果要做到业务有序,就需要保证业务的消息都丢到同一个分区里面。

下图是一个不同分区上的消息失序的例子。生产者发送msgA和msgB,但是消费者的消费顺序是msgB,msgA。

分区和消费者组,消费者的关系

在Kafka中,消费者都是归属于某一个消费者组的。

**一个消费者组可以看作是关心这个topic的一个业务方。**比如说在创建用户的时候,搜素关心新用户,推荐也关心新用户,那么搜索自己是一个消费者组,推荐也是一个消费者组。

**同一个消费者组里面,一个分区最多只有一个消费者。**也就是在同一个消费者组里面:

  • 一个消费者可以消费多个分区的数据。
  • 一个分区在同一时刻,只可能被一个消费者消费。

最多一个消费者的内涵

一个分区最多一个消费者!!!

下图中的分区2被两个消费者消费,这种是不允许的。

由此衍生出来:

  • 如果一个topic有N个分区,那么同一个消费者组最多有N个消费者。多于这个数字的消费者会被忽略。

  • 如果消费者性能很差,那么并不能通过无限增加消费者来提高消费速率。

这就是典型的面试热点:消息积压问题。

面试题:消息积压问题

消息积压问题 (Message Backlog / Message Queue Backlog)是指消息系统(如 Kafka、RabbitMQ、RocketMQ 等)中的消息生产速度大于消费速度,导致未被及时处理的消息不断堆积,形成队列积压。


一、具体表现
  • 消息队列的未消费消息数量持续上升
  • 消费者处理延迟增加,甚至发生超时或阻塞。
  • 系统下游(如数据库、缓存)负载飙升,进一步加剧问题。

二、常见原因
消费者处理能力不足
  • 单个消费者处理速度慢(CPU、IO瓶颈等)。
  • 消费者数量不足,未充分利用并行处理能力。
  1. 消费逻辑复杂或存在性能问题

    • 业务逻辑太重,如耗时操作、远程调用、数据库慢查询等。
    • 消费端存在阻塞、锁竞争、批处理效率低等问题。
  2. 系统异常或崩溃

    • 消费者崩溃未及时恢复。
    • 消息堆积后触发重试机制,造成雪崩效应。
  3. 消息生产突增

    • 突发业务高峰(如秒杀、双十一)。
    • 上游程序错误导致消息量异常增长。
  4. 消息队列配置不合理

    • 分区/主题配置不当,消费者未能均匀分担压力。
    • 消息堆积阈值设置过高,未能及时预警。

三、危害
  • 消息处理延迟,影响业务实时性(如用户通知、订单处理等)。
  • 可能导致系统雪崩,甚至消息丢失或重复消费
  • 增加恢复难度,影响用户体验与系统稳定性。

四、解决思路
问题类型 解决方案
消费能力不足 增加消费者实例、优化消费逻辑、批量处理消息
消费慢 引入异步处理、使用缓存、优化数据库操作
系统异常 设置监控报警、自动拉起消费者、实现幂等重试机制
消息突增 实现流量削峰(如削峰队列、限流器)、分布式消费
配置不合理 合理设置分区数、消费组数、预警阈值

Docker 中如何部署Kafka

Kafka 早期版本(< 2.8) 需要依赖 Zookeeper 来管理元数据(如 topic、broker 信息),但从 Kafka 2.8 开始引入KRaft 模式(Kafka Raft Metadata Mode) ,也就是所谓的 "无 Zookeeper 模式"

1.手动拉取镜像

bash 复制代码
docker pull bitnami/kafka:3.6.0

2.创建并启动Kafka

清爽版,下面有专门的注释

bash 复制代码
docker run -d \
  --name kafka \
  -p 9092:9092 \
  -p 9094:9094 \
  -e KAFKA_CFG_NODE_ID=0 \
  -e KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true \
  -e KAFKA_CFG_PROCESS_ROLES=controller,broker \
  -e KAFKA_CFG_LISTENERS=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093,EXTERNAL://0.0.0.0:9094 \
  -e KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://192.168.24.101:9092,EXTERNAL://192.168.24.101:9094 \
  -e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT \
  -e KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@localhost:9093 \
  -e KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER \
  -v kafka-data:/bitnami/kafka \
  bitnami/kafka:3.6.0
bash 复制代码
docker run -d \
  --name kafka \
  #Kafka 内部使用的端口
  -p 9092:9092 \
  #Kafka 提供给宿主机或外部客户端访问的端口
  -p 9094:9094 \
  #Kafka 节点 ID,必须在集群中唯一,这里是 0 (单节点时设置成 0 即可)
  -e KAFKA_CFG_NODE_ID=0 \
  #是否允许自动创建 topic,开发测试建议开启;线上建议关闭(手动管理更安全)
  -e KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true \
  #设置本节点既充当 controller 又充当 broker(KRaft 模式支持分离角色,但单节点要全包)。
  -e KAFKA_CFG_PROCESS_ROLES=controller,broker \
  #定义 Kafka 要监听哪些协议/端口。
  #PLAINTEXT://0.0.0.0:9092:内部通信(集群内组件用)。
  #CONTROLLER://0.0.0.0:9093:用于 KRaft 元数据 controller 间通信。
  #EXTERNAL://0.0.0.0:9094:暴露给外部客户端使用。
  -e KAFKA_CFG_LISTENERS=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093,EXTERNAL://0.0.0.0:9094 \
  #设置 Kafka 向客户端"宣传"的地址(外部怎么连)。
  #PLAINTEXT://192.168.24.101:9092:容器内其他服务连接时使用服务名 192.168.24.101
  #EXTERNAL://192.168.24.101:9094:宿主机通过 192.168.24.101:9094 访问 Kafka。
  -e KAFKA_CFG_ADVERTISED_LISTENERS=PLAINTEXT://192.168.24.101:9092,EXTERNAL://192.168.24.101:9094 \
  #定义每个 listener 对应的协议(这里全部使用明文 PLAINTEXT)
  -e KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT,EXTERNAL:PLAINTEXT \
  #声明 controller 的投票者(即 controller 之间的通信)。
  #0@kafka:9093:ID 为 0 的节点,其 controller 地址是 localhost:9093。
  #单节点配置即可,集群中要配置多个。
  -e KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@localhost:9093 \
  #告诉 Kafka 哪个 listener 是 controller 用的。
  -e KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER \
  #使用 Docker volume kafka-data 来持久化 Kafka 数据(日志、topic 等),即使容器删除数据也不会丢失。
  -v kafka-data:/bitnami/kafka \
  bitnami/kafka:3.6.0

3.验证Kafka是否创建完成

bash 复制代码
INFO ... Kafka successfully initialized
INFO ... Starting Kafka server
INFO ... [KafkaServer id=0] started (kafka.server.KafkaServer)

当最后出现"started"或"ready"字样,就表示 Broker 已经监听并可用。

相关推荐
Lucas6492 小时前
kafka的安装及简单使用
分布式·kafka
掘金-我是哪吒2 小时前
分布式微服务系统架构第127集:cassandra安装部署
分布式·微服务·云原生·架构·系统架构
MZWeiei2 小时前
Spark任务调度流程详解
大数据·分布式·spark·scala
бесплатно3 小时前
Spark-Core(RDD行动算子)
大数据·分布式·spark
搞不懂语言的程序员5 小时前
Kafka Controller的作用是什么?故障时如何恢复? (管理分区和副本状态;通过ZooKeeper选举新Controller)
分布式·zookeeper·kafka
onkel in blog8 小时前
【Docker】Docker Compose方式搭建分布式内存数据库(Redis)集群
数据库·redis·分布式·docker
努力也学不会java11 小时前
【RabbitMQ】 RabbitMQ高级特性(一)
分布式·rabbitmq·ruby
liuhongJAVAEn12 小时前
分布式-Redis分布式锁
数据库·redis·分布式
IvanCodes12 小时前
三、Hadoop1.X及其组件的深度剖析
大数据·hadoop·分布式