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

kafka 面试总结

Kafka的幂等性是一种机制,确保生产者发送的每条消息在Broker端只被持久化一次,即使生产者因网络问题等原因重试发送,也不会导致消息重复。

实现原理
生产者ID(PID)
每个生产者实例在初始化时,会被分配一个全局唯一的PID。
PID在整个Kafka集群中保持唯一,用于标识特定的生产者。
序列号(Sequence Number)
生产者对每个<Topic, Partition>维护一个单调递增的序列号。
每条消息都会附带其对应的序列号。
Broker端处理
Broker为每个<PID, Partition>组合记录最近接收到的序列号。
当收到新消息时:
如果消息的序列号等于上次接收的序列号加一,则接受并存储消息。
如果消息的序列号小于或等于已记录的序列号,则视为重复消息,直接丢弃。
如果消息的序列号大于已记录的序列号加一,说明有消息丢失,通常会拒绝该消息并报错。
配置方法
要启用Kafka生产者的幂等性,只需在配置中设置:

Properties
深色版本
enable.idempotence = true
注意事项
仅保证单分区幂等性
幂等性机制仅作用于单个分区,无法保证跨分区的消息不重复。
自动调整相关配置
启用幂等性后,Kafka会自动调整以下配置:
acks = all:确保消息被所有副本确认。
retries = Integer.MAX_VALUE:允许生产者无限次重试发送。
max.in.flight.requests.per.connection = 5:限制每个连接上未确认请求的最大数量。
版本支持
幂等性特性从Kafka 0.11.0版本开始引入,需确保使用的Kafka版本支持该功能。
使用场景
金融交易
确保每笔交易只被处理一次,防止重复扣款或结算。
订单处理
避免订单重复生成,保证订单数据的准确性。
日志收集
确保日志数据的唯一性,避免重复记录影响分析。
总结
Kafka的幂等性通过PID和序列号机制,有效解决了生产者端消息重复发送的问题,保证了消息在分区级别的唯一性,为构建可靠的数据处理系统提供了重要保障。


在Kafka中,**Partition(分区)**是Topic数据存储和并行处理的基本单元。

定义
Partition是Topic的物理分割,每个Topic可以包含一个或多个Partition。
每个Partition是一个有序的、不可变的消息序列,消息按照追加的顺序存储,每条消息在Partition内都有一个唯一的偏移量(Offset)标识其位置。
作用
提高并发处理能力
并行生产与消费:多个生产者可以同时向不同的Partition写入消息,多个消费者也可以并行地从不同的Partition读取消息,大幅提升系统的吞吐量。
实现负载均衡
分布式存储:Partition均匀分布在Kafka集群的各个Broker上,实现数据和负载的均衡分布,避免单点瓶颈。
保障数据可靠性
副本机制:每个Partition可以有多个副本(Replica),分布在不同的Broker上。其中,一个副本是Leader,负责处理读写请求;其余副本是Follower,同步Leader的数据。当Leader宕机时,会自动选举新的Leader,确保数据不丢失。
特点
有序性
消息顺序:在单个Partition内,消息严格按照追加顺序存储和消费,保证了消息的有序性。
全局无序:不同Partition之间的消息顺序不保证,如果需要全局有序,应将消息发送到同一个Partition。
可扩展性
水平扩展:通过增加Partition数量,可以扩展Topic的容量和处理能力,适应数据量的增长。
动态调整:支持在不停机的情况下增加Partition数量,但减少Partition数量会涉及数据迁移,操作较为复杂。
数据存储
日志文件:每个Partition对应一组日志文件,消息以追加的方式写入,文件分段存储,方便管理和清理。
索引文件:为了提高查找效率,每个Partition还有对应的索引文件,通过Offset快速定位消息。
消息分配策略
Key哈希:如果消息指定了Key,Kafka会根据Key的哈希值将消息分配到特定的Partition,确保相同Key的消息进入同一个Partition,常用于需要保证消息顺序的场景。
轮询策略:当消息没有指定Key时,Kafka会采用轮询方式,依次将消息发送到Topic的各个Partition,实现负载均衡。
总结
Partition是Kafka实现高吞吐量、高可扩展性和高可靠性的关键机制。通过将Topic划分为多个Partition,Kafka能够充分利用集群资源,实现消息的并行处理、分布式存储和负载均衡,满足大规模数据处理的需求。


Kafka的分区分配策略决定了如何将主题的分区分配给消费者组内的消费者,以实现负载均衡和高可用性。主要有以下三种内置策略:

1. RangeAssignor(范围分配策略)
原理:

排序分区和消费者: 对每个主题的分区按分区ID排序,消费者按名称字典序排序。
计算分配跨度: 计算每个消费者应分配的分区数 R = 分区总数 / 消费者数,余数 M = 分区总数 % 消费者数。
分配分区: 前 M 个消费者各分配 R+1 个分区,其余消费者各分配 R 个分区。每个消费者的分区是连续的。
示例:

假设有主题 T,包含 10 个分区 P0~P9,消费者组内有 3 个消费者 C0、C1、C2。

R = 10 / 3 = 3,M = 10 % 3 = 1
分配结果:
C0:P0、P1、P2、P3
C1:P4、P5、P6
C2:P7、P8、P9
优缺点:

优点: 实现简单,适合分区数较多且消费者数较少的场景。
缺点: 可能导致消费者负载不均衡,特别是分区数不能被消费者数整除时。
2. RoundRobinAssignor(轮询分配策略)
原理:

排序分区和消费者: 将所有主题的分区和消费者分别按字典序排序。
轮询分配: 按轮询方式依次将分区分配给消费者,直到所有分区分配完毕。
示例:

假设有两个主题 T1(分区 P0、P1、P2)和 T2(分区 P0、P1),消费者组为 C0、C1。

排序后的分区:T1P0、T1P1、T1P2、T2P0、T2P1
分配结果:
C0:T1P0、T1P2、T2P1
C1:T1P1、T2P0
优缺点:

优点: 在消费者订阅相同主题时,分配均匀,实现简单。
缺点: 当消费者订阅的主题不同时,可能导致分配不均衡。
3. StickyAssignor(粘性分配策略)
原理:

目标: 在保持分区分配均匀的同时,尽量减少再平衡时的分区变动。
分配过程:
初始分配: 采用轮询或范围策略进行初始分配。
再平衡: 当消费者加入或离开时,尽量保持现有分配不变,仅调整必要的最小分区数。
示例:

初始分配同轮询策略示例。若 C1 离开,C0 的分配结果可能变为:

C0:T1P0、T1P1、T1P2、T2P0、T2P1
优缺点:

优点: 减少再平衡时的分区变动,降低对系统的影响,提高稳定性。
缺点: 实现复杂,分配过程可能耗时较长。
选择策略
RangeAssignor: 适用于分区数较多、消费者数较少,且需要保持分区顺序的场景。
RoundRobinAssignor: 适用于消费者订阅相同主题,希望均匀分配分区的场景。
StickyAssignor: 适用于对稳定性要求高,希望减少再平衡影响的场景。
可通过配置消费者客户端的 partition.assignment.strategy 参数来选择分区分配策略,多个策略以逗号分隔。


Kafka本身不直接支持延迟消息,但可以通过以下方法实现:

1. 多级重试主题
原理:

创建多个具有不同延迟时间的重试主题(如order.retry.1m、order.retry.5m等)。生产者发送消息时,根据所需的延迟时间将消息发送到对应的重试主题。消费者监听这些重试主题,并在消息达到指定延迟后,将其转发到目标业务主题。

步骤:

创建重试主题: 创建多个主题,用于存储不同延迟时间的消息。
发送消息: 生产者根据延迟需求,将消息发送到相应的重试主题。
消费者处理: 消费者监听重试主题,当消息达到延迟时间后,将其消费并转发到目标主题。
优点:

实现简单,无需引入外部组件。
缺点:

需要创建和管理多个主题,增加了复杂性。
延迟时间固定,不够灵活。
2. 使用Redis存储延迟任务
原理:

利用Redis的有序集合(ZSET)存储待发送的延迟消息,以消息的执行时间为分数。生产者将消息和延迟时间存储到Redis的ZSET中。启动一个定时任务,定期检查ZSET中的消息,当消息的延迟时间到达时,从ZSET中取出消息并发送到Kafka。

步骤:

生产者: 将消息和延迟时间存储到Redis的ZSET中。
定时任务: 使用Redis的ZREMRANGEBYSCORE命令,移除并获取已到期的消息。
发送消息: 将到期的消息发送到Kafka的目标主题。
优点:

延迟时间灵活,可精确控制。
支持动态调整延迟时间。
缺点:

引入了Redis作为外部依赖,增加了系统复杂性。
3. 利用Kafka的时间戳特性
原理:

生产者在发送消息时,给消息设置一个未来的时间戳。消费者在消费消息时,检查消息的时间戳,如果时间戳未到,则暂不处理该消息。

步骤:

发送消息: 生产者使用ProducerRecord设置未来的时间戳。
消费消息: 消费者获取消息后,判断时间戳是否到达,未到达则等待或重新入队。
优点:

无需额外的主题或组件。
缺点:

消费者需要实现复杂的逻辑来处理延迟消息。
消息可能在消费者内存中停留较长时间,占用资源。
4. 使用第三方库或工具
原理:

利用支持延迟消息的第三方库或工具,如Confluent Platform提供的confluent-kafka-go库,简化延迟消息的实现。

步骤:

引入依赖: 添加第三方库到项目中。
发送延迟消息: 使用库提供的API发送具有延迟时间的消息。
优点:

简化了实现,提供了现成的解决方案。
缺点:

引入了额外的依赖,可能增加学习成本。
选择建议
简单延迟,固定时间: 选择多级重试主题方案,适用于延迟时间固定的场景。
灵活延迟,精确控制: 选择Redis存储延迟任务方案,适用于需要动态调整延迟时间的场景。
简化实现,引入依赖: 选择第三方库或工具方案,快速实现延迟消息功能。
根据业务需求和系统架构,选择合适的方案实现Kafka的延迟消息功能。

参考来源 · 9
kafka顺序消息


已完成搜索
Kafka通过以下机制实现消息的顺序性:

生产者端
分区键(Partition Key)
生产者发送消息时,可以为消息指定一个分区键。
Kafka根据分区键的哈希值将消息分配到特定的分区。
相同分区键的消息会被发送到同一个分区,从而保证这些消息在该分区内的顺序。
禁用重试或限制重试
将max.in.flight.requests.per.connection设置为1,确保在收到前一条消息的确认前,不会发送下一条消息。
避免因重试导致的消息顺序错乱。
消费者端
单线程消费
使用单线程消费分区内的消息,确保消息按顺序处理。
适用于对顺序要求严格且吞吐量要求不高的场景。
多线程有序消费
将分区内的消息根据业务键(如订单ID)进一步划分,分配到不同的线程处理。
每个线程负责处理具有相同业务键的消息,保证局部顺序。
适用于需要高吞吐量且保持局部顺序的场景。
Topic和分区设计
单分区
将主题配置为只有一个分区,所有消息都会进入该分区,实现全局顺序。
适用于消息量不大且需要严格全局顺序的场景。
缺点是会降低系统的并行处理能力和吞吐量。
多分区
使用多个分区提高整体吞吐量。
通过合理设计分区键,将需要保持顺序的消息发送到同一个分区,实现局部顺序。
消费者组配置
每个分区仅由一个消费者消费
确保分区内的消息顺序不被多个消费者并行消费打乱。
消费者组内的消费者数量应小于或等于分区数量。
幂等性和事务性
幂等生产者
设置enable.idempotence为true,确保消息在重试时不会重复,保持顺序。
事务性生产者
使用事务将多条消息作为一个原子操作发送,保证要么全部成功,要么全部失败,维护消息的顺序性和一致性。
注意事项
避免频繁的重平衡
重平衡可能导致分区分配变化,影响消息顺序。
确保消费者及时处理消息,避免因消费滞后触发重平衡。
处理消息延迟
如果消费者处理速度慢,可能导致消息积压,影响后续消息的顺序。
优化消费者性能或增加消费线程。
通过以上策略,Kafka可以在不同场景下实现消息的顺序性,满足业务需求。

1.Kafka的高水位(High Watermark,简称HW)是一个关键概念,用于确保数据的一致性和可靠性,高水位是Kafka分区中一个特殊的偏移量(offset),表示所有同步副本(In-Sync Replicas,ISR)都已确认并持久化的最高消息的偏移量。这意味着:

- **消费者可见性**:消费者只能读取到高水位之前的消息,高水位之后的消息对消费者不可见。
- **数据一致性**:高水位保证了所有ISR副本中的数据一致性,确保消费者读取到的消息在所有副本中都已同步。

1. **保证数据可靠性**
   - 生产者发送消息到Leader副本后,只有当消息被所有ISR副本确认并持久化,该消息的偏移量才会被包含在高水位内。
   - 即使Leader副本发生故障,新的Leader会从ISR中选择,确保新Leader的数据不低于原Leader的高水位,避免数据丢失。

2. **控制消费者读取范围**
   - 消费者在拉取消息时,只能获取到高水位之前的消息,确保消费的数据是可靠的、已被所有副本确认的。
   - 防止消费者读取到未完全同步的不稳定消息。

1. **消息写入与同步**
   - 生产者将消息写入Leader副本,Leader追加消息到日志并更新自身的日志末端偏移量(LEO)。
   - Follower副本定期从Leader拉取消息,更新自己的LEO,并向Leader发送确认。

2. **高水位计算**
   - Leader副本计算所有ISR副本中LEO的最小值,将此值作为分区的高水位。
   - 公式:`HW = min(LEO of all ISR replicas)`
   - 每次Follower副本同步后,Leader会重新计算并更新高水位。

#### 示例说明

假设一个分区有3个副本(1个Leader,2个Follower),当前状态如下:

| 副本  | LEO  |
| ---- | --- |
| Leader  | 100  |
| Follower1 | 90  |
| Follower2 | 95  |

- **计算高水位**:`HW = min(100, 90, 95) = 90`
- **消费者可读取范围**:消费者只能读取偏移量小于等于90的消息。

当Follower1和Follower2完成同步,LEO分别更新为100时:

| 副本  | LEO  |
| ---- | --- |
| Leader  | 100  |
| Follower1 | 100  |
| Follower2 | 100  |

- **更新高水位**:`HW = min(100, 100, 100) = 100`
- **消费者可读取新消息**:消费者现在可以读取偏移量从91到100的消息。

- **高水位与LEO的关系**
  - **LEO**:每个副本的日志末端偏移量,表示该副本已写入但未完全同步的最新消息偏移量。
  - **HW**:所有ISR副本LEO的最小值,确保消费者读取的数据在所有副本中均已同步。

- **副本同步延迟**
  - 如果Follower副本同步滞后,会导致高水位更新缓慢,影响消费者的读取进度。
  - Kafka通过`replica.lag.time.max.ms`参数控制副本的最大滞后时间,超过该时间的副本会被移出ISR。

- **数据一致性保证**
  - 高水位机制确保了Kafka在分布式环境下的数据一致性,是Kafka实现可靠消息传递的重要保障。

通过理解高水位的概念和作用,可以更好地利用Kafka实现数据的高可靠性和一致性,确保消息的正确处理和消费。

在Kafka中,**Partition(分区)**是Topic数据存储和并行处理的基本单元。

- **Partition**是Topic的物理分割,每个Topic可以包含一个或多个Partition。
- 每个Partition是一个**有序的、不可变的消息序列**,消息按照追加的顺序存储,每条消息在Partition内都有一个唯一的偏移量(Offset)标识其位置。

- **并行生产与消费**:多个生产者可以同时向不同的Partition写入消息,多个消费者也可以并行地从不同的Partition读取消息,大幅提升系统的吞吐量。

- **分布式存储**:Partition均匀分布在Kafka集群的各个Broker上,实现数据和负载的均衡分布,避免单点瓶颈。

- **副本机制**:每个Partition可以有多个副本(Replica),分布在不同的Broker上。其中,一个副本是Leader,负责处理读写请求;其余副本是Follower,同步Leader的数据。当Leader宕机时,会自动选举新的Leader,确保数据不丢失。

- **消息顺序**:在单个Partition内,消息严格按照追加顺序存储和消费,保证了消息的有序性。
- **全局无序**:不同Partition之间的消息顺序不保证,如果需要全局有序,应将消息发送到同一个Partition。

- **水平扩展**:通过增加Partition数量,可以扩展Topic的容量和处理能力,适应数据量的增长。
- **动态调整**:支持在不停机的情况下增加Partition数量,但减少Partition数量会涉及数据迁移,操作较为复杂。

- **日志文件**:每个Partition对应一组日志文件,消息以追加的方式写入,文件分段存储,方便管理和清理。
- **索引文件**:为了提高查找效率,每个Partition还有对应的索引文件,通过Offset快速定位消息。

- **Key哈希**:如果消息指定了Key,Kafka会根据Key的哈希值将消息分配到特定的Partition,确保相同Key的消息进入同一个Partition,常用于需要保证消息顺序的场景。
- **轮询策略**:当消息没有指定Key时,Kafka会采用轮询方式,依次将消息发送到Topic的各个Partition,实现负载均衡。

Partition是Kafka实现高吞吐量、高可扩展性和高可靠性的关键机制。通过将Topic划分为多个Partition,Kafka能够充分利用集群资源,实现消息的并行处理、分布式存储和负载均衡,满足大规模数据处理的需求。

相关文章:

  • 微服务中 本地启动 springboot 无法找到nacos配置 启动报错
  • Mac QT水平布局和垂直布局
  • 怎么用idea打jar包
  • 【从0带做】基于Springboot3+Vue3的文物展览系统
  • Web 架构之数据读写分离
  • 2025 年数维杯数学建模 C 题完整论文代码模型
  • javax.net.ssl.SSLHandshakeException: No appropriate protocol
  • 系分论文《论多云架构治理的分析和应用》
  • 支持向量机案例
  • 服务器不备案有影响吗
  • Docker组件详解:核心技术与架构分析
  • O2OA(翱途)服务器故障排查
  • IM系统群消息推送方案
  • 发那科机器人4(编程实例)
  • 死锁的形成
  • 嵌入式开发学习(第二阶段 C语言基础)
  • 学习黑客威胁情报(Threat Intelligence)
  • TensorFlow深度学习实战(15)——编码器-解码器架构
  • docker 日志暴露方案 (带权限 还 免费 版本)
  • 阿里云 SLS 多云日志接入最佳实践:链路、成本与高可用性优化
  • 深入贯彻中央八项规定精神学习教育中央第七指导组指导督导中国船舶集团见面会召开
  • 明天起,沪苏湖高铁、杭温高铁推出13款新型票制产品
  • 是否有中国公民受印巴冲突影响?外交部:建议中国公民避免前往冲突涉及地点
  • 于东来再次回应玉石质疑:邀请前往胖东来深入考察,随时欢迎各方调查
  • 伯克希尔董事会投票决定:阿贝尔明年1月1日起出任CEO,巴菲特继续担任董事长
  • 李学明谈笔墨返乡:既耕春圃,念兹乡土