Kafka notes
kafka 学习笔记
一.基础架构与核心概念(优先掌握核心高频知识点(必须掌握))
-
基础架构与核心概念
-
Producer & Consumer 核心机制
-
存储与持久化
-
常见面试高频问题
基础架构与核心概念
Producer & Consumer 核心机制
存储与持久化
常见面试高频问题
写在前面 kafka是一个分布式的集群。
1. Producer、Consumer、Broker、Topic、Partition、Replica、ISR(In-Sync Replicas)、ZooKeeper 的作用。
Producer -> 作用就是负责向kafka写入数据的应用程序。
Topic -> 概念上来说,topic 只是一个逻辑概念,代表了一类消息,也可以认为是消息被发送到的地方。
作用:a. 使用topic来区分实际业务,比如业务A使用一个topic,业务B使用另外一个topic。
如何找到kafka消息 -> Kafka 中的一条消息其实就是一个<topic,partition,offset>三元组(tuple),通过该元组值我们可以在 Kafka 集群中找到唯一对应的那条消息。
Partition-> 主要作用就是 Partition(分区) 是 Kafka 实现高吞吐、可扩展性和并行处理的核心机制。
1.并行处理与扩展性
类比:想象一个快递仓库(Topic)需要处理海量包裹(消息)。如果只有一个分拣员(单线程),效率会非常低。
解决方案:把仓库分成多个隔间(Partition),每个隔间由独立的分拣员处理包裹。
效果:多个隔间可以并行分拣和发货,吞吐量大幅提升。
技术体现:
一个 Topic 可以划分为多个 Partition,每个 Partition 在物理上对应一个有序的日志文件。
Producer 可以向多个 Partition 并行写入,Consumer 也可以从多个 Partition 并行读取。
2. 负载均衡与分布式存储
类比:如果所有包裹都堆在一个隔间,分拣员会累垮(单节点瓶颈)。
解决方案:将隔间(Partition)分散到多个仓库(Broker)中。
效果:数据分散存储,避免单个 Broker 成为性能瓶颈。
技术体现:
Partition 会被分配到多个 Broker 上,实现横向扩展。
Kafka 通过分区策略(如轮询、哈希)自动平衡各 Broker 的负载。
3. 保证消息顺序性
类比:每个隔间(Partition)内的包裹必须按顺序分拣,但不同隔间的包裹顺序无关。
技术体现:
单个 Partition 内:消息按写入顺序严格有序(通过 Offset 标记顺序)。
跨 Partition:消息全局无序,但可以通过分区键(Key) 将需要保序的消息发送到同一 Partition。
例如:订单状态变更消息,用订单ID作为 Key,确保同一订单的消息在同一个 Partition 内顺序处理。
4. 消费者组的并行消费
类比:多个快递员(Consumer)可以同时从不同隔间(Partition)取包裹。
技术体现:
一个 Consumer Group 中的每个 Consumer 实例负责消费一个或多个 Partition。
Partition 数量决定了 Consumer Group 的最大并行度(例如:3 个 Partition 最多允许 3 个 Consumer 同时消费)。
如果 Consumer 数量超过 Partition 数,多余的 Consumer 会处于闲置状态。
5. 容错与副本机制
技术补充:
每个 Partition 可以有多个副本(Replica),其中一个是 Leader(负责读写),其他是 Follower(同步备份)。
如果 Leader 宕机,Kafka 会从 Follower 中选举新的 Leader,保证 Partition 的高可用。
实际应用中的关键点
分区数的选择:
分区数决定了 Kafka 的最大并行度,但过多的分区会导致元数据膨胀和性能下降。
经验值:分区数 = Broker 数量 × 2~4(根据业务吞吐量调整)。
分区键(Key)的设计:
使用业务关键字段(如用户ID、订单ID)作为 Key,确保相关消息进入同一分区,保序且方便局部处理。
热点问题
如果 Key 分布不均匀(例如某个 Key 的流量极大),会导致单个 Partition 成为性能瓶颈(需优化 Key 设计或使用随机分区策略)。
Partition 是 Kafka 的“并行单元”,解决了以下问题:
并行处理:提升吞吐量。
负载均衡:数据分散存储,避免单点瓶颈。
顺序性保证:单分区内有序,全局可控。
扩展性:通过增加 Partition 和 Broker 实现横向扩容。
实际的使用方式
如何自定义分区策略
Replica ->
作用: 既然我们已知 partition 是有序消息日志,那么一定不能只保存这一份日志,否则一旦保存 partition 的 Kafka 服务器挂掉了,其上保存的消息也就都丢失了。分布式系统必然要实现高可靠性,
而目前实现的主要途径还是依靠冗余机制——简单地说,就是备份多份日志。这些备份日志在Kafka中被称为副本(replica),它们存在的唯一目的就是防止数据丢失,这一点一定要记住!
副本分为两类: 领导者副本(leader replica)和追随者副本(follower replica)。follower replica 是不能提供服务给客户端的,也就是说不负责响应客户端发来的消息写入和消息消费请求。它只是被动地向领导者副本(leader replica)获取数据,而一旦 leader replica 所在的broker宕机,Kafka会从剩余的replica中选举出新的 leader继续提供服务。下面我们就来看看什么是leader和follower。
Kafka保证同一个partition的多个replica一定不会分配在同一台broker上。毕竟如果同一个broker上有同一个partition的多个replica,那么将无法实现备份冗余的效果。
ISR(In-Sync Replicas)-> 通俗的说是 同步副本集合,可以理解为一个“实时同步小分队”,它的作用是确保消息在分布式系统中既能安全存储,又能快速响应。
解决了什么问题?->
1.高可用性:如果 Leader 挂了,可以快速从 ISR 中选新 Leader,服务不中断。
2.数据一致性:只有 ISR 中的副本才有资格成为 Leader,确保新 Leader 的数据是最新的。
3.平衡性能与安全:生产者(Producer)可以配置是否等待 ISR 中的所有副本确认写入(比如 acks=all),在安全性和延迟之间做权衡。
举个实际场景 ->
假设 Kafka 的某个分区有 3 个副本(1 Leader + 2 Follower),ISR 包含这 3 个副本:
1.生产者发送一条消息到 Leader。
2.Leader 将消息同步给两个 Follower,只有成功同步的副本才会留在 ISR 中。
3.如果某个 Follower 网络延迟了 30 秒(超过 Kafka 配置的阈值 replica.lag.time.max.ms),它会被踢出 ISR。
4.此时 Leader 挂了,Kafka 会从剩下的 ISR(比如 2 个副本)中选新 Leader,而不是那个掉队的副本
关键配置:
replica.lag.time.max.ms:副本多久没同步会被踢出 ISR(默认 30 秒)。
min.insync.replicas:生产者要求至少写入多少个 ISR 副本才算成功(比如 acks=all 时,这个值决定最小副本数)。
说明:Kafka 承诺只要这个集合中至少存在一个 replica,那些“已提交”状态的消息就不会丢失——记住这句话的两个关键点:①ISR 中至少存在一个活着的replica;②“已提交”消息。有些Kafka用户经常抱怨:我向 Kafka发送消息失败,然后造成数据丢失。其实这是混淆了 Kafka 的消息交付承诺(messagedelivery semantic):Kafka 对于没有提交成功的消息不做任何交付保证,它只保证在ISR存活的情况下“已提交”的消息不会丢失。
offset->
2.分区(Partition)的作用:负载均衡、并行处理、消息顺序性。
负载均衡:
什么是负载均衡? -> 顾名思义就是让系统的负载根据一定的规则均衡地分配在所有参与工作的服务器上,从而最大限度地提升系统整体的运行效率。
对应到kafka上来说: 具体到Kafka来说,默认情况下 Kafka的每台服务器都有均等的机会为 Kafka的客户提供服务,可以把负载分散到所有集群中的机器上,避免出现“耗尽某台服务器”的情况发生。
kafka的负载均衡是怎么实现的呢?-> Kafka 实现负载均衡实际上是通过智能化的分区领导者选举(partition leader election)来实现的。 Kafka 默认提供了很智能的 leader 选举算法,可以在集群的所有机器上以均等机会分散各个partition的leader,从而整体上实现了负载均衡。
这里在介绍一下故障转移? -> 所谓故障转移,是指当服务器意外中止时,整个集群可以快速地检测到该失效(failure),并立即将该服务器上的应用或服务自动转移到其他服务器上。故障转移通常是以“心跳”或“会话”的机制来实现的,即只要主服务器与备份服务器之间的心跳无法维持或主服务器注册到服务中心的会话超时过期了,那么就认为主服务器已无法正常运行,集群会自动启动某个备份服务器来替代主服务器的工作。
具体到Kafka 服务器支持故障转移的方式就是使用会话机制。每台 Kafka 服务器启动后会以会话的形式把自己注册到ZooKeeper 服务器上。一旦该服务器运转出现问题,与ZooKeeper 的会话便不能维持从而超时失效,此时 Kafka 集群会选举出另一台服务器来完全代替这台服务器继续提供服务。
并行处理:
消息顺序性:
消息的伸缩性(暂时不作为重点):
有了消息的持久化,Kafka 实现了高可靠性;有了负载均衡和使用文件系统的独特设计,Kafka实现了高吞吐量;有了故障转移,Kafka 实现了 高可用性。
那么伸缩性又是如何实现的呢?->
首先来解释一下 什么叫做伸缩性:英文名是 scalability。根据 Java 大神 Brian Goetz 在其经典著作 JavaConcurrency in Practice中的定义,伸缩性表示向分布式系统中增加额外的计算资源(比如CPU、内存、存储或带宽)时吞吐量提升的能力。
那么kafka的 伸缩性是如何实现的呢?->
3.副本机制(Replication):Leader/Follower 分工、高可用性如何实现。
4.为什么 Kafka 快?顺序写磁盘、PageCache、零拷贝(Zero-Copy)、批量发送/压缩。
Producer & Consumer 核心机制
1.Producer 发送流程:acks 参数(0/1/-1/all)、消息发送的可靠性(Exactly-Once、At-Least-Once、At-Most-Once)。
2.Consumer 消费机制:Consumer Group、Rebalance 触发条件(新Consumer加入、宕机、Topic分区数变化)、Offset 提交方式(自动提交风险)。
3.如何保证消息顺序性?单分区内顺序写入,多分区时全局顺序无法保证。
存储与持久化
1.消息存储结构:Segment 文件(.log 和 .index)、如何通过 Offset 快速定位消息。
持久化代表着消息的高可靠性
2.日志清理策略:delete(基于时间/大小)和 compact(基于Key压缩)。
常见面试高频问题
1.Kafka 为什么用 ZooKeeper?新版本(KIP-500)为什么计划移除 ZooKeeper?
2.如何保证消息不丢失?Producer端(acks=-1 + 重试)、Broker端(副本同步)、Consumer端(手动提交Offset)。
3.如何实现 Exactly-Once 语义?幂等Producer + 事务机制。
4.如何处理重复消费?Consumer 幂等处理或去重(如数据库唯一键)。
二、结合项目实战场景(重点准备)
- 项目中的具体应用
- 典型场景问题
1.消息传输 -> Kafka非常适合替代传统的消息总线(message bus)或消息代理(message broker)。传统的这类系统擅长于解耦生产者和消费者以及批量处理消息,而这些特点 Kafka都具备。除此之外,Kafka 还具有更好的吞吐量特性,其内置的分区机制和副本机制既实现了高性能的消息传输,同时还达到了高可靠性和高容错性。因此 Kafka特别适合用于实现一个超大量级消息处理应用。
2.网站行为日志追踪 -> Kafka 最早就是用于重建用户行为数据追踪系统的。很多网站上的用户操作都会以消息的形式发送到 Kafka 的某个对应的topic 上。这些点击流蕴含了巨大的商业价值,事实上,目前就有很多创业公司使用机器学习或其他实时处理框架来帮助收集并分析用户的点击流数据。鉴于这种点击流数据量是很大的,Kafka超强的吞吐量特性此时就有了用武之地。
3. 审计数据收集-> 很多企业和组织都需要对关键的操作和运维进行监控和审计。这就需要从各个运维应用程序处实时汇总操作步骤信息进行集中式管理。在这种使用场景下,你会发现 Kafka是非常适合的解决方案,它可以便捷地对多路消息进行实时收集,同时由于其持久化的特性,使得后续离线审计成为可能。
4. 日志收集-> 这可能是 Kafka最常见的使用方式了——日志收集汇总解决方案。每个企业都会产生大量的服务日志,这些日志分散在不同的机器上。我们可以使用 Kafka对它们进行全量收集,并集中送往下游的分布式存储中(比如 HDFS 等)。比起其他主流的日志抽取框架(比如 Apache Flume),Kafka 有更好的性能,而且提供了完备的可靠性解决方案,同时还保持了低延时的特点。
5. event sourceing -> Event Sourcing实际上是领域驱动设计(Domain-DrivenDesign,DDD)的名词,它使用事件序列来表示状态变更,这种思想和 Kafka 的设计特性不谋而合。还记得吧,Kafka 也是用不可变更的消息序列来抽象化表示业务消息的,因此Kafka特别适合作为这种应用的后端存储。
6. 流式处理 -> Kafka社区推出了一个全新的流式处理组件Kafka Streams。这标志着Kafka正式进入流式处理框架俱乐部。相比老牌流式处理框架Apache Storm、Apache Samza,或是最近风头正劲的Spark Streaming,抑或是Apache Flink,Kafka Streams的竞争力如何?让我们拭目以待。
具体在项目中的应用->
1.项目中的具体应用
-
举例说明你如何设计 Kafka Topic(分区数设置依据?副本数设置?)。
-
项目中如何监控 Kafka(Lag 监控、Broker 负载)?遇到过哪些问题(如 Consumer Lag 突增)?如何解决的?
-
是否优化过 Kafka 性能?参数调优(batch.size、linger.ms、fetch.min.bytes等)。
2.典型场景问题
-
如何实现延迟消息?(外部存储 + 定时任务,或使用 Kafka 的 DelayedProducer 插件)
-
如何保证跨地域数据同步?(MirrorMaker 2.0 或 Confluent Replicator)
-
如何处理消息积压?(扩容 Consumer、增加分区、优化消费逻辑)
三、选择性补充进阶知识(时间允许时)
- 高级特性
-
Kafka Streams 的简单使用(如窗口聚合、状态存储)。
-
Kafka Connect 的 Source/Sink 连接器(如数据库同步)。
-
事务消息(跨多个分区的原子性写入)。
- 底层原理(大厂常问)
-
Controller 选举机制、Leader 选举流程(Unclean Leader Election 的取舍)。
-
副本同步机制(HW高水位、LEO的作用)。
-
新版本特性(如 Kraft 模式、ZooKeeper 替代方案)。
四、学习资源与技巧
- 快速上手资料
-
官方文档:Apache Kafka Documentation(重点看 Design 和 Configuration 部分)。
-
书籍:《Kafka 权威指南》第 1-5 章。
-
视频:B站/YouTube 的 Kafka 核心原理精讲(2-3小时速览)。
- 模拟面试自测
-
自问自答:如果让你设计一个分布式消息队列,你会考虑哪些问题?(对比 Kafka 的设计思路)
-
画图:手绘 Kafka 架构图,并解释数据流向(面试中常要求画图)。
总结
-
优先级排序:核心概念(70%) > 项目实战(20%) > 进阶原理(10%)。
-
一句话策略:“先会用再懂原理,先高频再低频”。确保在面试中能流畅回答 80% 的通用问题,再通过项目经验展示你的实战能力。时间紧张时,直接参考 Kafka 面试题列表 查漏补缺。
目前广泛使用的Kafka版本应该是0.8.2.x、0.9.x、0.10.x和0.11.x。注意,Kafka从0.11.0.0版本开始不再支持Scala 2.10,故用户在下载0.11.0.x版本的Kafka时不会再看到kafka_2.10-0.11.0.0字样的下载包。
kafka的版本选择
1.根据功能场景
-> 在生产环境中应用流式处理组件KafkaStreams,那么就必须使用Kafka0.10.0.0(含)之 后的版本。
-> 若是从零开始搭建或处于技术选型阶段,笔者推荐使用最新版本的Kafka,即 1.0.0,毕 竟这个版本中修复了很多关于 Streams 的 bug,并且完善了KafkaStreams的各种API接口。
-> 如果要在生产环境中启用KafkaSecurity,那么至少要使用 0.9.0.0及以后的Kafka版本,但最好能使 用0.10.0.1之后的版本。
关于kafka的线上环境部署