当前位置: 首页 > news >正文

【西瓜带你学Kafka | 第八期】 Kafka的主从同步、消息可靠性、流处理与顺序消费(文含图解)

文章目录

    • 前言
    • 一、Kafka 中如何进行主从同步
      • ISR 机制
      • 同步复制
      • 异步复制
      • 异步复制的利与弊
    • 二、Kafka 中什么情况下会出现消息丢失/不一致的问题
      • 消息发送时丢失
      • 消息消费时丢失
    • 三、Kafka 作为流处理平台的特点
      • 什么是流处理
      • Kafka 作为流处理平台的五大特性
      • 与其他流处理框架的定位差异
    • 四、消费者故障,出现活锁问题如何解决
      • 什么是活锁
      • 解决方案
      • 相关参数调优建议
    • 五、Kafka 中如何保证顺序消费
      • 顺序性的边界
      • 解决方案:指定 MessageKey
      • 需要注意的问题
    • 六、Kafka 是否支持多租户隔离
      • 什么是多租户
      • Kafka 的多租户方案
    • 总结

前言

用 Kafka 做基础消息收发并不难,但真正上生产之后,一连串棘手的问题就来了:消息怎么就丢了?消费者明明活着却不干活?多个业务共用一个集群怎么互不影响?消息顺序怎么就乱了?

这些问题的答案散落在 Kafka 的各个机制里——ISR 同步决定了副本一致性,ACK 配置决定了丢消息的概率,活锁检测决定了消费者的健康判定,分区模型决定了顺序性的边界。

本期西瓜带你学Kafka把这六个机制串起来,从同步复制讲到消息丢失,从流处理特性讲到顺序消费,帮助建立一个完整的 Kafka 可靠性认知框架。


一、Kafka 中如何进行主从同步

主从同步是 Kafka 高可用的基石。理解了这个机制,后面讲消息丢失时就能准确判断"丢在了哪个环节"。

ISR 机制

Kafka 动态维护了一个同步状态的副本的集合(a set of In-Sync Replicas),简称ISR。在这个集合中的节点都是和 Leader 保持高度一致的。

核心规则:任何一条消息只有被 ISR 集合中的每个节点读取并追加到日志中,才会向外部通知"这个消息已经被提交"。

ISR 不是固定的,它是动态维护的——如果某个 Follower 落后太多,会被踢出 ISR;追上来之后又会被重新加入。

同步复制

Kafka 通过配置producer.type来确定是异步还是同步,默认是同步

同步复制的完整流程:

  1. Producer 会先通过Zookeeper 识别到 Leader
  2. 然后向 Leader 发送消息
  3. Leader 收到消息后写入到本地 log 文件
  4. 这个时候 Follower 再向 LeaderPull 消息
  5. Pull 回来的消息会写入本地 log
  6. 写入完成后会向 Leader发送 Ack 回执
  7. 等到 Leader收到所有 Follower 的回执之后,才会向 Producer 回传 Ack

异步复制

Kafka 中 Producer 异步发送消息是基于同步发送消息的接口来实现的,实现方式如下:

  1. 客户端消息发送过来以后,会先放入一个BlockingQueue 队列中然后就返回了
  2. Producer 再开启一个线程ProducerSendThread不断从队列中取出消息
  3. 然后调用同步发送消息的接口将消息发送给 Broker

异步复制的利与弊

优势:Producer 在内存缓存消息,当累计达到阈值时批量发送请求。小数据 I/O 太多会拖慢整体的网络延迟,批量延迟发送事实上提升了网络效率

风险:如果在达到阈值前,Producer 不可用了,缓存的数据将会丢失


二、Kafka 中什么情况下会出现消息丢失/不一致的问题

理解了主从同步机制之后,消息丢失的场景就很容易推导出来了。丢失可能发生在两个阶段:生产端消费端

消息发送时丢失

消息发送有两种方式:同步(sync)异步(async)。默认是同步的方式,可以通过producer.type属性进行配置。

Kafka 也可以通过配置acks属性来确认消息的生产:

acks 值含义丢失风险
0不进行消息接收是否成功的确认网络异常、缓冲区满即丢失
1当 Leader 接收成功时确认Leader 宕机且 Follower 未同步时丢失
-1Leader 和 Follower 都接收成功时确认几乎不丢失

acks=0 的丢失场景

不和 Kafka 进行消息接收确认,可能会因为网络异常、缓冲区满的问题,导致消息丢失。Producer 以为发成功了,实际上 Broker 根本没收到。

acks=1 的丢失场景

只有 Leader 同步成功而 Follower 尚未完成同步,如果 Leader 挂了,就会造成数据丢失。新选举出来的 Leader(原来的某个 Follower)并没有这条消息。

消息消费时丢失

Kafka 有两个消息消费的 Consumer 接口:

1. low-level 接口

消费者自己维护 offset 等值,可以实现对 Kafka 的完全控制。由于 offset 完全由消费者管理,可以精确控制消费进度,不容易丢消息。

2. high-level 接口

封装了对 partition 和 offset 的管理,使用简单。

high-level 接口的丢失场景

如果使用高级接口,可能存在这样的情况:一个消费者提取了一个消息后便提交了 offset,那么还没来得及消费就已经挂了。下次消费时的数据就是offset+1的位置,那么原先 offset 的数据就丢失了。

时间线: 1. Consumer 拉取 offset=100 的消息 2. Consumer 提交 offset=100(标记为已消费) ← 先提交了 3. Consumer 开始处理消息... 4. Consumer 宕机!消息还没处理完 ← 但还没消费完 5. Consumer 重启,从 offset=101 开始消费 ← offset=100 的消息丢了

解决思路:先消费再提交 offset,或者使用手动提交 offset 的方式,确保消息处理完成后再提交。


三、Kafka 作为流处理平台的特点

前面讲的都是 Kafka 作为"消息队列"的机制,但 Kafka 的定位远不止于此——它是一个分布式流处理平台

什么是流处理

流处理就是连续、实时、并发和以逐条记录的方式处理数据的意思。与批处理不同,流处理强调的是数据到达即处理,而不是攒一批再处理。

Kafka 作为流处理平台的五大特性

Kafka 的高吞吐量、低延时、高可靠性、容错性、高可扩展性都使得 Kafka 非常适合作为流式平台。具体来说:

1. 轻量级 Java 类库

它是一个简单的、轻量级的 Java 类库,能够被集成到任何 Java 应用中。不需要独立部署流处理集群,直接在应用内引入即可。

2. 零外部依赖

除了 Kafka 之外没有任何其他的依赖。利用 Kafka 的分区模型支持水平扩容保证顺序性。不像 Spark Streaming 或 Flink 需要额外的计算集群。

3. 本地状态容错

支持本地状态容错,可以执行非常快速有效的有状态操作。比如窗口聚合、Join 等操作的中间状态可以存储在本地,故障时通过 changelog topic 恢复。

4. Exactly-Once 语义

支持exactly-once语义,保证每条消息恰好被处理一次,不多不少。这对金融、交易等场景至关重要。

5. 毫秒级延迟

支持一次处理一条记录,实现ms 级的延迟。真正的逐条处理,而不是微批(micro-batch)。

与其他流处理框架的定位差异

特性Kafka StreamsSpark StreamingFlink
部署方式嵌入应用独立集群独立集群
外部依赖仅 KafkaSpark + 存储Flink 集群
处理模型逐条记录微批逐条记录
延迟ms 级秒级ms 级
状态管理本地 + changelog外部存储本地 + checkpoint

四、消费者故障,出现活锁问题如何解决

什么是活锁

活锁和死锁不同。死锁是线程卡住不动了,而活锁是:消费者持续地维持心跳,但没有进行消息处理。

从 Broker 的角度看,这个 Consumer 是"活着的"(心跳正常),所以不会触发 Rebalance 把分区分配给其他 Consumer。但实际上这个 Consumer 什么都没干,它持有的分区就这样被"空占"了。

解决方案

为了预防消费者在这种情况下一直持有分区,通常会利用max.poll.interval.ms活跃检测机制。

工作原理:

  • Kafka 不仅检查心跳,还检查 Consumer调用 poll() 的频率
  • 如果调用 poll 的频率大于最大间隔(即两次 poll 之间的时间超过了max.poll.interval.ms),那么消费者将会主动离开消费组
  • 分区会被重新分配给其他消费者接管
正常情况: poll() → 处理消息 → poll() → 处理消息 → poll() |<--- 间隔在 max.poll.interval.ms 内 --->| 活锁情况: poll() → 心跳正常但消息处理卡住/不处理 → 超过 max.poll.interval.ms |<--- 超时!Consumer 被踢出消费组 --->|

相关参数调优建议

参数作用建议
max.poll.interval.ms两次 poll 的最大间隔根据消息处理耗时设置,默认 300000ms(5 分钟)
max.poll.records单次 poll 返回的最大消息数如果处理慢,可以减小这个值,确保在间隔内处理完
session.timeout.ms心跳超时时间检测 Consumer 是否真正宕机

max.poll.interval.mssession.timeout.ms的区别:前者检测"活着但不干活"(活锁),后者检测"真的挂了"(宕机)。


五、Kafka 中如何保证顺序消费

顺序性的边界

Kafka 的消费单元是Partition。同一个 Partition 使用offset作为唯一标识保证顺序性。

但这里有一个关键限制:这只是保证了在 Partition 内部的顺序性,而不是 Topic 中的顺序。

一个 Topic 通常有多个 Partition,消息被分散到不同 Partition 后,跨 Partition 之间是没有顺序保证的。

解决方案:指定 MessageKey

如果需要保证某一类消息的顺序消费,可以在发送的时候指定 MessageKey。同一个 Key 的消息会发到同一个 Partition 中。

Topic: order-topic (3 个 Partition) 消息: orderId=1001, action=创建 → Key=1001 → Partition-1 消息: orderId=1001, action=支付 → Key=1001 → Partition-1 顺序保证 消息: orderId=1001, action=发货 → Key=1001 → Partition-1 顺序保证 消息: orderId=1002, action=创建 → Key=1002 → Partition-2 消息: orderId=1002, action=支付 → Key=1002 → Partition-2 顺序保证

同一个订单的所有操作都落在同一个 Partition,消费时自然就是有序的。

需要注意的问题

1. 全局顺序 vs 分区顺序

如果业务要求全局严格有序(所有消息按发送顺序消费),那只能设置 Topic 只有1 个 Partition。但这会牺牲并行度和吞吐量。

大多数场景其实只需要同一业务实体内有序(比如同一个订单、同一个用户),用 MessageKey 就够了。

2. Key 的选择要均匀

如果所有消息的 Key 都一样,那所有消息都会落到同一个 Partition,等于退化成了单分区,失去了并行消费的优势。Key 的选择应该保证消息能均匀分布到各个 Partition。


六、Kafka 是否支持多租户隔离

什么是多租户

多租户技术(multi-tenancy technology)是一种软件架构技术,它是实现如何在多用户的环境下共用相同的系统或程序组件,并且仍可确保各用户间数据的隔离性

简单来说:多个业务团队共用一个 Kafka 集群,但彼此之间互不影响、数据互不可见。

Kafka 的多租户方案

Kafka 支持多租户,解决方案主要通过两个层面实现:

1. 主题级别的访问控制

通过配置哪个主题可以生产或消费数据来启用多租户。不同租户只能访问自己被授权的 Topic,无法读写其他租户的数据。

如何实现
依靠SASL 做身份认证 + ACL 做资源授权,给每个租户独立账号,通过Topic前缀+ACL规则限制只能访问自己的主题,实现多租户数据隔离。

    1. 服务端开启认证授权(server.properties 核心配置)
# 开启SASL端口 listeners=SASL_PLAINTEXT://:9092 # 启用SCRAM账号密码认证 sasl.enabled.mechanisms=SCRAM-SHA-256 # 开启ACL授权器 authorizer.class.name=org.apache.kafka.metadata.authorizer.StandardAuthorizer
    1. 创建租户账号
# 创建租户用户 tenant-a,设置密码kafka-configs.sh --bootstrap-server127.0.0.1:9092\--alter--entity-typeusers--entity-name tenant-a\--add-config SCRAM-SHA-256=[password=123456]
    1. 配置ACL权限(核心:前缀匹配隔离)
# 允许租户 tenant-a 读写前缀为 tenant-a- 的所有Topickafka-acls.sh --bootstrap-server127.0.0.1:9092--add\--allow-principal User:tenant-a\--operationRead--operationWrite--operationDescribe\--resource-pattern-type prefixed\--topictenant-a-
    1. 客户端配置指定账号(生产者/消费者)
security.protocol=SASL_PLAINTEXT sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required \ username="tenant-a" password="123456"; sasl.mechanism=SCRAM-SHA-256

2. 配额(Quota)机制

Kafka 也有对配额的操作支持。管理员可以对请求定义和强制配额,以控制客户端使用的 Broker 资源。

配额可以从以下维度进行限制:

配额维度说明
生产速率限制某个客户端每秒可以发送的数据量(bytes/sec)
消费速率限制某个客户端每秒可以拉取的数据量(bytes/sec)
请求处理时间占比限制某个客户端请求占用 Broker 处理能力的百分比

通过配额机制,即使某个租户的流量突然暴增,也不会把整个集群的资源吃光,其他租户的正常使用不受影响。


总结

  1. 主从同步:ISR 机制动态维护同步副本集合,同步复制等所有 Follower 确认,异步复制先入队再批量发送,各有利弊
  2. 消息丢失:生产端因 acks 配置不当丢失(acks=0 网络异常丢、acks=1 Leader 宕机丢),消费端因先提交 offset 后处理导致丢失
  3. 流处理平台:轻量级 Java 类库、零外部依赖、本地状态容错、exactly-once 语义、ms 级延迟,五大特性使 Kafka 不只是消息队列
  4. 活锁问题:通过max.poll.interval.ms检测"活着但不干活"的消费者,超时自动踢出消费组
  5. 顺序消费:Partition 内有序但跨 Partition 无序,通过指定 MessageKey 将同类消息路由到同一 Partition
  6. 多租户隔离:通过主题级访问控制和配额机制,实现多业务共享集群且互不影响

这六个机制构成了 Kafka 可靠性和隔离性的完整图景。从副本同步保证数据不丢,到 ACK 和 offset 管理堵住丢消息的口子,再到活锁检测和顺序消费保证消费端的正确性,最后通过多租户隔离让多个业务安全共存。

http://www.jsqmd.com/news/728783/

相关文章:

  • 2026成都阳台防水补漏技术解析与商家选择推荐 - 优质品牌商家
  • 深度学习齿轮箱故障诊断与寿命预测【附代码】
  • STBDAI7220数字输入模块
  • 2026年卡通书包定制厂家怎么选:幼儿园书包定制/开学书包定制/托管班书包定制/拉杆书包定制/男士商务包定制/皮质商务包定制/选择指南 - 优质品牌商家
  • DP World Tour欧洲巡回赛携手HCLTech重建官网与球迷应用
  • 告别固定类别!用YOLO-World+自定义词汇,5分钟打造你的专属物体检测器
  • 工业物联网网关IOT-LINK硬件架构与软件生态解析
  • SoC FPGA在汽车雷达数字信号处理中的优势与应用
  • 从Hal库到标准库:手把手教你将机智云自动代码移植到STM32F103(附完整工程)
  • 如何在 matlab 中调用 taotoken 平台的大模型 api 接口
  • Python正则表达式
  • TFTX11702示教器模块
  • ARM SVE指令集与AES加密硬件加速详解
  • 高新技术企业认定条件解读及申报流程详解
  • 【车辆控制】基于电动车静态PID与动态(动学地平线)自适应巡航控制策略的比较分析附Matlab代码
  • 用Requests和BeautifulSoup4爬取豆瓣电影Top250:手把手教你构建个人电影数据库
  • 03C++ 定位 new 运算符(Placement new)
  • Windows 多层嵌套文件夹批量整理:三级文件一键移到二级文件夹
  • 定氢探头精准把控氢含量——唐山大方汇中仪表
  • SMUDebugTool深度解析:AMD Ryzen处理器底层调试与超频实战指南
  • 微软2026财年Q3财报:营收超800亿美元,AI业务成增长核心支柱!
  • C语言数组专题:从一维到二维,吃透内存与指针
  • 动手学深度学习(PyTorch版)深度详解(5):深度学习计算核心 —— 卷积操作、填充步幅、汇聚层与 LeNet 完整精讲
  • 去年科小高频踩坑点汇总,今年直接规避!
  • 函数式程序员注意!Zig 凭编译时编程、内存管理优势,有望成未来热门语言
  • AI助手成本监控仪表盘:本地化Token用量与费用可视化方案
  • 2025届学术党必备的十大降重复率平台推荐
  • SKILL快速构建你的Java、Python和Node.js开发环境
  • 养虾成功!OpenClaw 接入微信全记录(附配置模型关键步骤)
  • 计算机系统——模拟病毒感染ELF可执行文件