Kafka进阶

Kafka进阶

Kafka事务

kafka的事务机制是指kafka支持跨多个主题和分区的原子性写入,即在一个事务中发送的所有消息要么全部成功,要么全部失败。

kafka的事务机制涉及到以下几个方面:

  • 事务生产者(transactional producer):可以在一个事务中发送多个消息到不同的主题和分区,也可以从其他主题消费消息并发送到新的主题(实现流处理)。事务生产者需要指定一个唯一的transactional.id,用于标识不同的事务。
  • 事务消费者(transactional consumer):可以消费事务生产者发送的消息,并且只有当事务提交后才能看到这些消息。事务消费者需要设置isolation.level为read_committed,以过滤掉未提交或中止的事务消息。
  • 事务协调器(transaction coordinator):是运行在每个kafka broker上的一个模块,负责管理和分配ProducerID,维护每个transactional.id对应的事务状态,以及处理事务的提交或中止。
  • 事务日志(transaction log):是kafka的一个内部主题,用于存储每个transactional.id对应的事务元数据,包括ProducerID、epoch、分区列表、状态等。¹²

kafka的事务机制大致流程如下:

  • 事务生产者调用initTransactions方法,向集群请求一个ProducerID,并找到对应的事务协调器。
  • 事务生产者调用beginTransaction方法,向事务协调器发送开始事务的请求,并递增epoch。
  • 事务生产者调用send方法,向目标主题和分区发送消息,并将这些分区注册到事务协调器。
  • 事务生产者调用commitTransaction或abortTransaction方法,向事务协调器发送提交或中止事务的请求,并将控制消息写入到已注册的分区中。
  • 事务协调器根据控制消息和事务状态,决定是否将该事务标记为已提交或已中止,并更新事务日志。
  • 事务消费者根据isolation.level设置,只消费已提交的事务消息,并忽略未提交或已中止的事务消息。

Kafka生产者幂等性

幂等性介绍

Kafka的幂等性是指生产者在发送消息时,可以保证同一个消息不会被重复写入到同一个分区中,即使发生了网络错误或者重试;

幂等性原理

Kafka的幂等性是基于生产者的ID和序号来实现的,每个生产者都有一个唯一的ID和一个递增的序号,当生产者发送消息时,会把这两个信息附加到消息中,当分区收到消息时,会根据这两个信息来判断是否是重复的消息。
Kafka的幂等性只能保证单个分区内的消息不重复,不能保证跨分区或跨主题的消息不重复。如果要实现更强的事务保证,需要使用Kafka的事务机制。

分区机制

分区的文件存储形式

Kafka分区中的文件是按照一定的规则进行存储的,主要有以下几个特点:

  • 每个分区对应一个日志文件夹(log file),日志文件中存储的是生产者发送的消息。
  • 日志文件又被分成多个段文件(segment file),每个段文件都有固定的大小限制,当达到限制时,就会关闭当前段文件,创建新的段文件。
  • 段文件由两部分组成:一个是存储消息内容的“.log”文件,另一个是存储消息位置信息的“.index”文件。
  • “.index”文件是稀疏索引文件,它记录了消息的偏移量(offset)和物理位置(position)之间的映射关系,方便消费者快速定位消息。
  • 消息在日志文件中是顺序追加的,消息在分区中也是有序的,每个消息都有一个递增的偏移量,偏移量在分区内是唯一的。
  • Kafka会定期删除过期的或者超过大小限制的段文件,以回收磁盘空间。删除策略可以根据时间或者大小来配置。

消费者如何消费分区

  • 消费者消费数据时,首先需要知道自己要消费的分区和偏移量
  • 分区是由消费者组(Consumer Group)内部的分区分配策略(Partition Assignor)来决定的,不同的策略会有不同的分配逻辑
  • 偏移量是由消费者自己维护的,每次消费完一批消息后,消费者会把当前的偏移量提交到 Kafka 或者其他存储中,下次消费时会从上次提交的偏移量开始继续消费
  • 当消费者知道了要消费的分区和偏移量后,它会向分区的 Leader Broker 发送拉取请求,请求从指定的偏移量开始拉取一批消息。
  • Leader Broker 收到请求后,会根据偏移量在“.index”文件中查找对应的物理位置(Position),然后从“.log”文件中读取一批消息返回给消费者。

这样,消费者就可以在多个段文件中找到自己要消费的数据了。

生产者分区写入策略

按key分配策略(默认)

它会根据消息的键(key)来计算一个哈希值,并根据哈希值对分区数取模,得到目标分区的编号。如果消息没有键,或者键为空,它会随机选择一个可用的分区。

轮询策略

轮询的分区写入策略,它会按照分区的顺序依次将消息发送到每个分区上,不考虑消息的键或者值。这种策略可以实现消息的均匀分布。

自定义分区策略

自行实现Partitioner接口,自定义分区策略。

指定分区(与写入策略无关)

手动指定写入哪个分区。

随机策略(较早版本)

随机写入某个分区。

消息乱序问题

  • 轮询策略和随机策略,造成kafka中的数据是乱序存储的
  • 按 key 分区,一定程度上可以实现数据的有序存储——局部有序,但是又可能会造成数据倾斜
    Kafka进阶_第1张图片

Producer的ACKs参数

producer配置的acks参数了,acks参数表示当生产者生产消息的时候,写入到副本的要求严格程度。它决定了生产者如何在性能和可靠性之间做取舍。

acks有3个值可选 0、1和-1(或者all),默认值为1,值为字符串类型,不是整数类型

  • 0:producer发送后即为成功,无需分区partition的leader确认写入成功,性能最高

  • 1:producer发送后需要接收到partition的leader发送确认收到的回复,性能中等

  • -1或者all:producer发送后,需要ISR中所有副本都成功写入成功才能收到成功响应,性能最慢

分区的leader与follower机制

AR、ISR、OSR

在实际环境中,leader有可能会出现一些故障,所以Kafka一定会选举出新的leader。在讲解leader选举之前,我们先要明确几个概念。Kafka中,把follower可以按照不同状态分为三类——AR、ISR、OSR

  • AR(Assigned Replicas) 分区的所有副本
  • ISR(In-Sync Replicas) 所有与leader副本保持一定程度同步的副本(包括 leader 副本)
  • OSR(Out-of-Sync Replias) 由于follower副本同步滞后过多的副本(不包括 leader 副本)

AR = ISR + OSR, 正常情况下,所有的follower副本都应该与leader副本保持同步,即AR = ISR,OSR集合为空。

Leader选举

  • kafka启动时,会在所有的broker中选择一个controller,controller的选举由broker竞争决定。controller会负责创建topic、或者添加分区、修改副本数量之类的管理任务,包括leader的选举。controller也是高可用的,一旦某个broker崩溃,其他的broker会重新注册为controller

  • controller读取到当前分区的ISR,只要有一个Replica还幸存,就选择其中一个作为leader否则,则任意选这个一个Replica作为leader

Kafka生产、消费数据工作流程

Kafka数据写入流程

Kafka进阶_第2张图片

Kafka数据消费流程

Kafka进阶_第3张图片

消息不丢失机制

broker数据不丢失

生产者通过分区的leader写入数据后,所有在ISR中follower都会从leader中复制数据,这样,可以确保即使leader崩溃了,其他的follower的数据仍然是可用的

生产者数据不丢失

通过ACK机制来确保数据已经成功写入。

消费者数据不丢失

在消费者消费数据的时候,只要每个消费者记录好offset值即可,就能保证数据不丢失。offset值记录在zk中。

你可能感兴趣的:(kafka,kafka,数据库,分布式)