Kafka 中 topic、partition、offset、replica、ISR 等概念详解

本文详细介绍了Kafka的消息数据结构,包括消息头部、Key和Value,以及时间戳和位移(Offset)。此外,阐述了Topic和Partition的概念,解释了Partition如何通过位移确保消息的有序性。Kafka的副本机制,包括Leader和Follower Replicas,以及ISR(In-Sync Replicas)的重要性被深入探讨,强调了ISR在保证消息不丢失中的作用。最后,讨论了如何通过配置Partition数量来优化系统性能和高可用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


先说一个题外话,就是 Kafka 名字的由来:

I thought that since Kafka was a system optimized for writing using a writer’s name would make sense. I had taken a lot of lit classes in college and liked Franz Kafka. Plus the name sounded cool for an open source project.

Kafka 三位原作者之一 Jay Kreps:因为Kafka 系统的写操作性能特别强,所以找个作家的名字来命名似乎是一个好主意。我在大学时上了很多文学课,非常喜欢 Franz Kafka。另外为开源项目起 Kafka 这个名字听上去很酷。

消息的数据结构

Kafka 中的消息格式由很多字段组成,其中的很多宇段都是用于管理消息的元数据字段,对用户来说是完全透明的。Kafka 消息格式共经历过 3 次变迁,它们被分别称为 VO、V1 和 V2 版本。V1 版本消息的完整格式如下图所示:
u4DfIg
消息由消息头部、 key 和 value 组成。消息头部包括消息的 CRC 码、消息版本号、属性、时间戳、键长度和消息体长度等信息。

  • Key:消息键,对消息做 partition 时使用,即决定消息被保存在某 topic 下的哪个 partition。
  • Value:消息体,保存实际的消息数据。
  • Timestamp:消息发送时间戳,用于流式处理及其他依赖时间的处理语义。如果不指定则取当前时间。

Kafka 为消息的属性字段分配了 1 字节 。 目前只使用了最低的 3 位用于保存消息的压缩类型,其余 5 位尚未使用。当前只支持 4 种压缩类型:0(无压缩)、1(GZIP)、2(Snappy)和 3(LZ4)。
Kafka 在消息设计时直接使用紧凑二进制字节数组 ByteBuffer。当出现 Kafka broker 进程崩溃时,堆内存上的数据也一并消失,但页缓存的数据依然存在。下次 Kafka broker 重启后可以继续提供服务。

topic 和 partition

topic 只是一个逻辑概念,代表了一类消息,也可以认为是消息被发送到的地方。通常我们可以使用 topic 来区分实际业务,比如业务 A 使用一个 topic,业务 B 使用另外一个 topic 。
Kafka 中的 topic 通常都会被多个消费者订阅,因此出于性能的考量,Kafka 并不是 topic-message 的两级结构,而是采用了 topic-partition-message 的三级结构来分散负载。从本质上说,每个 Kafka topic 都由若干个 partition 组成,如图下图所示。
NuShoU
这张来自 Kafka 官网的 topic 和 partition 关系图非常清楚地表明了它们二者之间的关系:topic 是由多个 partition 组成的,而 Kafka 的 partition 是不可修改的有序消息序列,也可以说是有序的消息日志。每个 partition 有自己专属的 partition 号,通常是从 0 开始的。用户对 partition 唯一能做的操作就是在消息序列的尾部追加写入消息。partition 上的每条消息都会被分配一个唯一的序列号——按照 Kafka 的术语来讲,该序列号被称为位移(offset)。该位移值是从 0 开始顺序递增的整数。位移信息可以唯一定位到某 partition 下的一条消息。
Kafka 的 partition 实际上并没有太多的业务含义,它的引入就是单纯地为了提升系统的吞吐量,因此在创建 Kafka topic 的时候可以根据集群实际配置设置具体的 partition 数,实现整体性能的最大化。

位移(offset)

关于 offset,需要区分是消费者端的 offset 还是 topic partition 下的每条消息的位移。
VHI8rL
如上图所示,每条消息在某个 partition 的位移是固定的,但消费该 partition 的消费者的位移会随着消费进度不断前移,但终究不可能超过该分区最新一条消息的位移。
其实,Kafka 中的一条消息其实就是一个<topic,partition,offset>三元组(tuple),通过该元组值我们可以在 Kafka 集群中找到唯一对应的那条消息。

replica

我们已知 partition 是有序消息日志,那么一定不能只保存这一份日志,否则一旦保存 partition 的 Kafka 服务器挂掉了,其上保存的消息也就都丢失了。分布式系统必然要实现
高可靠性,而目前实现的主要途径还是依靠冗余机制——简单地说,就是备份多份日志。这
些备份日志在 Kafka 中被称为副本(replica),它们存在的唯一目的就是防止数据丢失。
副本分为两类:领导者副本(leader replica)和追随者副本(follower replica)。follower
replica 是不能提供服务给客户端的,也就是说不负责响应客户端发来的消息写入和消息消费请
求。它只是被动地向领导者副本(leader replica)获取数据,而一旦 leader replica 所在的
broker 宕机,Kafka 会从剩余的 replica 中选举出新的 leader 继续提供服务。

leader 和 follower

Kafka 的 replica 分为两个角色:领导者(leader)和追随者(follower)。和传统主备系统(比如 MySQL)不同的是,在这类 leader-follower 系统中通常只有 leader 对外提供服务,follower 只 是被动地追随 leader 的状态,保持与 leader 的同步。follower 存在的唯一价值就是充当 leader 的候补:一旦 leader 挂掉立即就会有一个追随者被选举成为新的 leader 接替它的工作。Kafka 就是这样的设计,如下图所示:
y7NMT6
Kafka 保证同一个 partition 的多个 replica 一定不会分配在同一台 broker 上。毕竟如果同一个 broker 上有同一个 partition 的多个 replica,那么将无法实现备份冗余的效果。

ISR

ISR 的全称是 in-sync replica,翻译过来就是与 leader replica 保持同步的 replica 集合。这是一个特别重要的概念。前面讲了很多关于 Kafka 的副本机制,比如一个 partition 可以配置 N 个 replica,那么这是否就意味着该 partition 可以容忍 N-1 个 replica 失效而不丢失数据呢?答案是“否”!
Kafka 为 partition 动态维护一个 replica 集合。该集合中的所有 replica 保存的消息日志都与 leader replica 保持同步状态。只有这个集合中的 replica 才能被选举为 leader,也只有该集合中所有 replica 都接收到了同一条消息,Kafka 才会将该消息置于“已提交”状态,即认为这条消息发送成功。回到刚才的问题,Kafka 承诺只要这个集合中至少存在一个 replica,那些“已提交”状态的消息就不会丢失-记住这句话的两个关键点:

  1. ISR 中至少存在一个“活着的”replica;
  2. “已提交”消息。

有些 Kafka 用户经常抱怨:我向 Kafka 发送消息失败,然后造成数据丢失。其实这是混淆了 Kafka 的消息交付承诺(message delivery semantic):Kafka 对于没有提交成功的消息不做任何交付保证,它只保证在 ISR 存活的情况下“已提交”的消息不会丢失。
正常情况下,partition 的所有 replica(含 leader replica)都应该与 leader replica 保持同步,即所有 replica 都在 ISR 中。因为各种各样的原因,一小部分 replica 开始落后于 leader replica 的进度。当滞后到一定程度时,Kafka 会将这些 replica“踢”出 ISR。相反地,当这些 replica 重新“追上”了 leader 的进度时,那么 Kafka 会将它们加回到 ISR 中。这一切都是自动维护的,不需要用户进行人工干预,因而在保证了消息交付语义的同时还简化了用户的操作成本。

<think>嗯,用户现在问的是Kafka中的ISR,之前他们问过默认发送方式是同步还是异步,可能是在实际使用Kafka时遇到了性能或可靠性问题,需要深入理解内部机制。首先,我需要确认ISR的定义和作用。ISR全称是In-Sync Replicas,也就是同步副本集合。这是Kafka确保数据高可用性和一致性的关键机制。 接下来,用户可能想知道ISR的工作机制,比如Leader如何处理消息,副本如何同步,以及ISR如何应对节点故障。需要解释清楚生产者发送消息到Leader,Follower从Leader拉取数据,保持同步的过程。还要提到ISR的动态调整,当Follower滞后超过一定阈值时会被移出ISR,恢复后重新加入。 用户可能还会关心ISR相关的配置参数,比如replica.lag.time.max.ms,这个参数控制副本在多久没同步后会被踢出ISR。还有min.insync.replicas,这个参数影响生产者的acks设置,确保至少有多少个副本确认写入才算成功。这些配置对于生产环境调优很重要,需要详细说明。 另外,用户可能想知道ISR如何保证数据一致性。比如,当Leader失效时,Kafka会从ISR中选举新的Leader,避免数据丢失。但如果有副本不在ISR中,可能不会被选为Leader,避免数据不一致的问题。这里需要强调ISR在故障恢复中的作用。 之前的对话中用户问到过acks参数,现在ISR中的min.insync.replicas和acks=all的关系可能需要进一步解释。用户可能在实际配置中需要结合这两个参数来平衡可靠性和性能。例如,设置acks=all和min.insync.replicas=2可以确保至少两个副本写入成功,防止数据丢失。 还要考虑用户可能的误区,比如认为所有副本都在ISR中,但实际上只有同步的副本才会被保留。如果网络延迟高或者Follower处理慢,可能导致ISR收缩,影响可用性。这时候需要调整参数或者检查系统性能。 最后,总结ISR的重要性,确保用户理解其在Kafka高可用和数据一致性中的核心作用,并能够根据实际需求配置相关参数。可能还需要提醒用户监控ISR的状态,及时发现和处理副本同步的问题,避免生产环境中的潜在风险。</think>Kafka 中的 **ISR(In-Sync Replicas,同步副本集合)** 是保证数据高可用性和一致性的核心机制。以下是关于 ISR 的详细介绍: --- ### **1. ISR 的作用** Kafka 通过多副本(Replica)机制实现数据的冗余存储,而 ISR 是**所有与 Leader 副本保持同步的副本集合**(包括 Leader 自身)。它的核心目标是: - **数据可靠性**:确保消息在多个副本间同步后才视为提交成功。 - **故障恢复**:当 Leader 副本失效时,能够从 ISR 中快速选举新 Leader,避免数据丢失。 --- ### **2. ISR 的工作机制** 1. **消息写入流程**: - 生产者将消息发送到 Partition 的 **Leader 副本**。 - **Follower 副本**(属于 ISR 的副本)从 Leader 拉取消息并写入本地日志。 - 当所有 ISR 中的副本都同步了消息后,该消息才被标记为**已提交**(committed),消费者才能读取。 2. **ISR 的动态维护**: - **同步条件**:Follower 副本需定期向 Leader 同步数据(通过心跳和拉取消息)。 - **剔除机制**:如果 Follower 副本长时间未同步(例如网络故障或宕机),则会被移出 ISR。 - **恢复机制**:当副本重新追上 Leader 的进度后,会被重新加入 ISR。 --- ### **3. 关键参数与配置** - **`replica.lag.time.max.ms`**(默认 30 秒): - 定义 Follower 副本允许的最大滞后时间。超过此时间未同步的副本会被移出 ISR。 - **`min.insync.replicas`**(默认 1): - 生产者要求消息至少写入多少个 ISR 副本才算成功(需配合 `acks=all` 使用)。 - **示例**:若设置 `min.insync.replicas=2`,则至少需要两个 ISR 副本确认写入,否则生产者会抛出异常。 --- ### **4. ISR 与数据一致性的关系** - **生产者可靠性**: - 当生产者设置 `acks=all` 时,消息必须被所有 ISR 副本确认后才返回成功。 - 若 ISR 副本数量不足(例如小于 `min.insync.replicas`),生产者会收到 `NotEnoughReplicasException`。 - **故障恢复**: - 新 Leader 只能从 ISR 中选举,确保新 Leader 的数据是最完整的。 - 非 ISR 的副本(滞后或故障的副本)不会被选为 Leader,避免数据不一致。 --- ### **5. 示例场景** 假设一个 TopicPartition 有 3 个副本(Leader、Follower1、Follower2): - **正常情况**:所有副本同步,ISR = [Leader, Follower1, Follower2]。 - **Follower2 故障**:若 Follower2 超过 30 秒未同步,ISR 会变为 [Leader, Follower1]。 - **Leader 宕机**:KafkaISR([Follower1])中选举新 Leader,确保数据不丢失。 --- ### **6. ISR 的监控** 通过 Kafka 命令行工具或监控系统(如 Prometheus + JMX)可以查看 ISR 状态: ```bash # 查看 TopicISR 信息 kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic your-topic ``` --- ### **总结** ISRKafka 实现**高可靠、低延迟**消息传递的核心机制,通过动态维护同步副本集合,平衡了数据一致性与系统可用性。合理配置 `replica.lag.time.max.ms` 和 `min.insync.replicas` 参数,可以适应不同场景的可靠性需求。 --相关问题-- 1. Kafka 的 `acks` 参数如何与 ISR 协同工作? 2. 如果 ISR 中只剩一个副本,会对系统产生什么影响? 3. 如何优化 Kafka 副本同步性能以避免频繁的 ISR 收缩?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值