kafka同步方式发送 kafka 同步机制_isr

kafka replication副本

  • 所谓副本,通产指分布式系统中不同机器中保存相同的数据拷贝,本质就是一个只能追加写消息的提交日志
  • 提供数据冗余。即使系统部分组件失效,系统依然能够继续运转,因而增加了整体可用性以及数据持久性。
  • 提供高伸缩性。支持横向扩展,能够通过增加机器的方式来提升读性能,进而提高读操作吞吐量。
  • 改善数据局部性。允许将数据放入与用户地理位置相近的地方,从而降低系统延时。

假如kafka一个主题有3个分区3个副本部署在三台Broker上,在实际生产环境中,每台 Broker 都可能保存有各个主题下不同分区的不同副本,因此,单个 Broker 上存有成百上千个副本的现象是非常正常的。

kafka同步方式发送 kafka 同步机制_isr_02

关键性问题:如何保证副本中的数据是一致的?

kafka采用了常见的解决方案:基于领导者(Leader-based)的副本机制

这样做的优缺点:

  • 没能提供读操作横向扩展以及改善局部性。
  • 方面实现立即读Read-your-writes,写完就能读到
  • 方面实现单调读Monotonic Reads,同一消费者,多次消费消息,不会看到某条消息一会存在一会儿不存在

kafka同步副本集合In-sync Replicas(ISR)

如何定义同步,追随者副本到底在什么条件下才算与 Leader 同步。kafka引入了同步副本ISR集合,ISR 中的副本都是与 Leader 同步的副本,凡是在ISR集合中的副本都认为是同步的。

kafka同步方式发送 kafka 同步机制_java_03

上图中哪些follower副本是同步的,kafka it depends,视情况而定,不一定是严格的相同

  • Broker参数replica.lag.time.max.ms ,默认10秒钟
  • 如果一个follower在这个时间内没有发送fetch请求或消费leader日志到结束的offset,leader将从ISR中移除这个follower,并认为这个follower已经挂了

倘若该副本后面慢慢地追上了 Leader 的进度,那么它是能够重新被加回 ISR 的。这也表明,ISR 是一个动态调整的集合,而非静态不变的。

如果ISR为空该如何选举

因为 Leader 副本天然就在 ISR 中,如果 ISR 为空了,就说明 Leader 副本也挂掉了,此时该怎么选举新 Leader 。

Kafka 把所有不在 ISR 中的存活副本都称为非同步副本。通常来说,非同步副本落后 Leader 太多,如果选择这些副本作为新 Leader,就可能出现数据丢失的情况。在 Kafka 中,选举这种副本的过程称为 Unclean 领导者选举。

Broker 端参数 unclean.leader.election.enable 控制是否允许 Unclean 领导者选举。
如果想保证数据的一致性,禁用Unclean。

一个分布式系统通常只能同时满足一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)中的两个。显然,在这个问题上,Kafka 赋予你选择 C 或 A 的权利。
ISR副本同步机制

与 Leader 副本保持同步的条件有两个:

1.该远程 Follower 副本在 ISR 中。

2.该远程 Follower 副本 LEO 值落后于 Leader 副本 LEO 值的时间,不超过 Broker 端参数 replica.lag.time.max.ms 的值。如果使用默认值的话,就是不超过 10 秒。

  • Committed Message:已提交消息,已经被所有ISR同步的消息。
  • Lagging Message:未提交消息,没有达到所有ISR同步的消息。
  • Hight Watermark:副本高水位值,表示分区中最新一条已提交(Committed)的消息的Offset。位移值等于高水位的消息也属于未提交消息。也就是说,高水位上的消息是不能被消费者消费的。
  • LEO:Log End Offset,Leader中最新消息的Offset,它表示副本写入下一条消息的位移值。
  • kafka同步方式发送 kafka 同步机制_java_04

  • 高水位和 LEO 是副本对象的两个重要属性。Kafka 所有副本都有对应的高水位和 LEO 值,而不仅仅是 Leader 副本。只不过 Leader 副本比较特殊,Kafka 使用 Leader 副本的高水位来定义所在分区的高水位。换句话说,分区的高水位就是其 Leader 副本的高水位

kafka高水位更新机制

Kafka 所有副本都有对应的高水位和 LEO 值,在 Leader 副本所在的 Broker 上,还保存了其他 Follower 副本的 LEO 值。

leader副本更新HW和LEO流程:

1.处理生产者请求的逻辑如下:

  • 获取 Leader 副本所在 Broker 端保存的所有远程副本 LEO 值{LEO-1,LEO-2,……,LEO-n}。
    获取 Leader 副本高水位值:currentHW。
  • 更新 currentHW = min(currentHW, LEO-1,LEO-2,……,LEO-n)。
  • 写入消息到本地磁盘。
  • 更新分区高水位值。

2.处理 Follower 副本拉取消息的逻辑如下:

  • 读取磁盘(或页缓存)中的消息数据。
  • 使用 Follower 副本发送请求中的位移值更新远程副本 LEO 值。
  • 更新分区高水位值(具体步骤与处理生产者请求的步骤相同)

Follower 副本更新HW和LEO流程

从 Leader 拉取消息的处理逻辑如下: a.获取 Leader 发送的高水位值:currentHW。 b.获取步骤 2 中更新过的 LEO 值:currentLEO。 c.更新高水位为 min(currentHW, currentLEO)。 c1.写入消息到本地磁盘。 c2. 更新 LEO 值。 c3.更新高水位值。

下一节预告

  • kafka副本同步机制Leader Epoch

推荐阅读

  • 深入浅出kafka原理-1-初识只作乍见之欢
  • 深入浅出kafka原理-2-Kafka为何那么快(高效)
  • 深入浅出kafka原理-3-高效文件存储设计特点