Kafka 之深入理解

Kafka 基础概念

Broker: 一台 kafka 服务节点就是一个 broker,一个集群由多个 broker 组成,一个 broker 可以有多个 topic。
Producer: 消息生产者,向 kafka broker 发消息的客户端。
Consumer: 消息消费者,从 kafka broker 取消息的客户端。
Consumer Group: 消费者组,多个 consumer组成。每个消费者负责消费不同分区的数据,一个分区只能由一个消费者消费。
Topic: 可以理解为一个队列,逻辑上的概念,区分不同的业务。
Partition: 为了提高一个队列 topic 的吞吐量,Kafka 把 topic 进行分区 Partition,每个分区都分布到不同的 broker,每个 partition 是一个有序的队列。
Replica: 为了保证集群中的某个节点发生故障时,该节点上的 partition 数据不丢失,kafka提供了副本机制,一个 topic 的每个 partition 都有若干个副本,一个 leader 和若干个 follower。
leader: 分区多个副本的主,生产者发送数据和消费者消费数据的对象都是 leader。
follower: 分区多个副本的从,实时从 leader 中同步数据,leader 发生故障时,某个 follower 会成为新的 follower。
offset: 表示消费者的消费进度,每个消费者会都有自己的 offset。

Kafka 工作流程

TopicA、TopicA对应3个分区(partition0、partition1、partition2)、每个分区有两个副本(leader、follower)
在这里插入图片描述
Kafka 中消息是以 topic 进行分类的,生产者生产消息,消费者消费消息,都是面向 topic的。
topic 是逻辑上的概念,而 partition 是物理上的概念,每个 partition 对应于一个 log 文件,该 log 文件中存储的就是 producer 生产的数据。Producer 生产的数据会被不断追加到该log 文件末端,且每条数据都有自己的 offset。消费者组中的每个消费者,都会实时记录自己消费到了哪个 offset,以便出错恢复时,从上次的位置继续消费。

Kafka 文件存储机制

在这里插入图片描述
由于生产者生产的消息会不断追加到 log 文件末尾,为防止 log 文件过大导致数据定位效率低下,Kafka 采取了分片和索引机制,将每个 partition 分为多个 segment。每个 segment对应两个文件——“.index”文件和“.log”文件。这些文件位于一个文件夹下,该文件夹的命名规则为:topic 名称+分区序号。例如first 这个 topic 有三个分区,则其对应的文件夹为 first-0,first-1,first-2。

00000000000000000000.index
00000000000000000000.log
00000000000000170410.index
00000000000000170410.log
00000000000000239430.index
00000000000000239430.log

index 和 log 文件以当前文件的第一条消息的 偏移量 offset 命名。

index文件和log文件详解:
在这里插入图片描述
.log 文件存储数据。
.index 文件存储索引信息,索引文件中的数据存储了对应数据文件中 message 的物理偏移地址。

读取某个offset偏移量数据流程:

  1. 根据 offset 值定位索引和数据文件。
  2. 从索引文件中获取 offset 对应消息在数据文件的物理偏移量地址。

面试题: 从 Kafka 读取数据后,数据会自动删除吗?
不会,Kafka 中数据的删除和消费者是否消费无关,数据的删除,只跟 kafka broker 上的这两个配置有关。

log.retention.hours=48  #数据最多保存48小时
log.retention.bytes=1073741824  #每个数据最大为1G

Kafka 生产者分区策略

在这里插入图片描述

  • 指明 partition 的情况下,直接发送到该 partiton 。
  • 没有指明 partition 值但有 key 的情况下,根据 key 的 hash 值和 partition 数进行取余得到 partition 值。
  • 既没有 partition 值又没有 key 值的情况下,第一次调用时随机生成一个整数(后面每次调用在这个整数上自增),将这个值和 partition 数取余得到 partition 值,也就是常说的 round-robin 轮询算法。

Kafka 生产者保证数据可靠性

ack 决定数据是否丢失。
为保证 producer 发送的数据,能可靠的发送到指定的 topic,topic 的每个 partition 收到 producer 发送的数据后,都需要向 producer 发送 ack(acknowledgement 确认收到),如果 producer 收到 ack,就会进行下一轮的发送,否则重新发送数据。
在这里插入图片描述
何时发送 ack:

  • 半数以上的 follower 同步完成,发送ack。
  • 全部的 follower 同步完成,发送ack。Kafka 默认方案。

ISR,同步副本: 和 leader 保持连接的 follower 集合。
Leader 维护了一个动态的 in-sync replica set (ISR),表示和 leader 保持同步的 follower 集合。当 ISR 中的 follower 完成数据的同步之后,leader 就会给 follower 发送 ack。如果 follower长时间未向 leader 同步数据 , Leader 发生故障之后,就会从 ISR 中选举新的 leader。

ISR解决的问题: 如果 leader 收到数据,需要所有 follower 同步完成,才发送 ack 给生产者,如果有一个 follower 宕机了,不能与 leader 进行同步,那么 leader 就会一直等下去,无法发送 ack;所以 Kafka 提供了 ISR 机制,让 leader 维护一个保持连接的 follower 集合,保证 leader 可以等到所有 follower 同步完成。

leader 故障后如何选举: 从 ISR 中选举新的 leader,因为 ISR 中都是和 leader 一直保持连接的 follower。

维护 ISR 中的 follower 策略:

  • follower 和 leader 保持同步的时间,该时间阈值由 replica.lag.time.max.ms (默认10s)参数设定,同步时间高于阈值则踢出 ISR,低于阀值加入 ISR。
  • follower 和 leader 消息差距的条数,由参数 replica.lag.time.max.messages 设定,差距的条数大踢出 ISR,差距的条数小加入 ISR。

0.9版本以后移除了replica.lag.time.max.ms参数,只保留了replica.lag.time.max.messages 差距的条数这个策略,为什么选择这个,为了尽量不丢数据。

** leader 的 ack 应答机制:** 使用 acks 参数配置。
Kafka 为用户提供了三种可靠性级别,用户根据对可靠性和延迟的要求进行权衡,选择以下的配置。

  • 0: producer 不等待 broker 的 ack,broker 一接收到还没有写入磁盘就已经返回 ack,当 broker 故障时有可能丢失数据,延迟最低。
  • 1: producer 等待 broker 的 ack,partition 的 leader 落盘成功后返回 ack,如果在 follower 同步成功之前 leader 故障,那么将会丢失数据;
  • -1(all): producer 等待 broker 的 ack,partition 的 leader 和 follower 全部落盘成功后才返回 ack。但是如果在 follower 同步完成后,broker 发送 ack 之前,leader 发生故障,那么会造成数据重复。
    acks = -1 数据重复案例
    在这里插入图片描述

Kafka 出故障后如何保证副本之间数据存储的一致性

每个log文件都有一个HW和LEO。
Kafka 出故障后是通过 HW 和 LEO 来保证副本之间的数据一致性,并不能保证数据不丢失或者不重复。数据不丢失是通过 acks 参数来保证的。
LEO: 每个副本最大的 offset。
HW:高水位 消费者能见到的最大的 offset,所有副本中最小的 LEO。 HW 之前的数据才对 consumer 可见。
在这里插入图片描述

follower 出现故障:
follower 发生故障后会被临时踢出 ISR, follower 恢复后,follower 会读取本地磁盘记录的上次的 HW,并将 log 文件高于 HW 的部分截取掉,比如上图第二个 follower 发生故障并恢复后,会将 offset12 后面的数据截取掉,然后从 HW 开始向 leader 进行同步数据。等到 follower 的 LEO 大于等于该 Partition 的 HW,即 follower 追上 leader 之后,就可以重新加入 ISR 了。
leader 出现故障:
leader 发生故障之后,会从 ISR 中选出一个新的 leader,之后,为保证多个副本之间的数据一致性,其余的 follower 会先将各自的 log 文件高于 HW 的部分截掉,然后从新的 leader同步数据。比如上图 leader 发生故障,选出第一个 follower 作为新的 leader,此时 HW 为12,将第二个 follower 中 offset 12 后面的数据截取掉,从新的 leader 进行同步数据了,但是发现 offset12 后面的数据丢失了,所以 LEO、HW不保证数据丢失,应该通过 acks 参数来保证数据不丢失,如果此时 acks 设置是-1或all,producer 会重新发送 offset12后面的数据,因为 acks = -1 表示所有副本同步成功才返回 ack 给 producer,leader 出现故障显然不符合,所以会重新发送 offset13-19 的数据。

Kafka 生产者总结

通过 ack 应答机制保证数据可靠性,acks 有三种参数设置,0表示接收到数据立即返回ack,发生故障会丢失数据,1表示 leader 落盘成功后返回 ack,如果 follower 同步成功之前 leader 发生故障,数据会丢失,-1表示 leader 和所有 follower 同步完成后返回 ack,数据不会丢失,但是有可能数据重复;
如果 leader 发生故障,从 ISR 中选举新的 leader,ISR 维护的是和 leader 保持连接的 follower,选举出新的 leader 后,通过 HW、LEO来保证副本之间数据存储的一致性,除了新的 leader,将其余 follower 高于 HW 部分截取掉,从新的 leader 进行同步数据,所以 HW、LEO 保证了副本之间数据存储的一致性,不保证数据丢失,保证数据不丢失通过 acks 参数来决定的。

Kafka 消费者分区分配策略

consumer 采用 pull(拉)模式从 broker 中读取数据。

一个 consumer group 中有多个 consumer,一个 topic 有多个 partition,所以会涉及到 partition 的分配问题,即确定那个 partition 由哪个 consumer 来消费。

分区分配策略之Range(Kafka默认)。
按照范围划分,在 partition 分区除不尽且 consumer 订阅主题越来越多的情况下,可能会导致某个 consuner 负载高于其他的 consumer。
在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值