replica分析

Kafka引入副本机制的目的主要是为了增加kafka集群的高可用性。Kafka实现副本机制后,每个分区可以有多个副本,并且会从其副本集合(AR)中选举出一个Leader副本,负责所有的读写请求,剩余作为follower副本,follower副本会从leader副本fetch 消息到自己的log,以防止leader挂了,其余broker上的follower可以选举为leader继续对外提供服务。一般情况下,同一个分区的多个副本会均匀分配到集群中不同broker,如果一个分区的全部副本都在同一个broker上,那么该broker出现故障后,就会导致整个分区不可用。

 

一个分区的leader副本中会维护自身以及所有follower的状态,但是follower副本只是维护自己的状态

 

一Replica核心字段

brokerId:Int 表示该副本属于哪一个broker

partition:Partition 表示属于哪一个分区的副本

highWatermarkMetadata:LogOffsetMetadata 用来记录HighWatermark

(HW)的值(最高水位线)。消费者只能获取HighWatermark之前的消息,后面的消息对消费者不可见。该字段是由leader副本维护的,更新的时机是消息被ISR同步列表的副本全部成功同步,即消息被提交成功

logEndOffsetMetadata:LogOffsetMetadata 对于本地副本,此字段主要记录追加到log的最新消息的offset,可以直接从Log.nextOffsetMeta

data获取;对于远程副本,含义相同但是需要其他broker发送请求来更新这个值,并不能从本地直接获取到

log: Log 副本对应的Log对象,远程副本此字段为空

lastCaughtUpTimeMsUnderlying:AtomicLong 用于记录follower上一次赶上leader的时间戳

 

二 Replica重要方法

2.1 isLocal 根据日志对象是否为空判断该副本是本地副本还是远程副本

def isLocal: Boolean = {
  log match {
    case Some(l) =>true
    case
None => false
 
}
}

 

2.2 logEndOffset 获取本地或者远程副本的LEO

private def logEndOffset_=(newLogEndOffset: LogOffsetMetadata) {
  // 对于本地副本不能直接更新LEO,LEOLoglogEndOffsetMetadata字段决定
  if (isLocal) {
    throw new KafkaException("Should not set log end offset on partition [%s,%d]'s local replica %d".format(topic, partitionId, brokerId))
  } else {
    // 如果是远程副本,LEO是通过请求进行更新的
    logEndOffsetMetadata = newLogEndOffset
    trace("Setting log end offset for replica %d for partition [%s,%d] to [%s]"
      .format(brokerId, topic, partitionId, logEndOffsetMetadata))
  }
}

def logEndOffset =
  // 对于本地副本不能直接更新LEO,LEOLoglogEndOffsetMetadata字段决定
  if (isLocal)
    log.get.logEndOffsetMetadata
  else // 远程副本应该从leader处通过LEO的请求更新
    logEndOffsetMetadata

 

2.3 highWatermark 更新HighWatermark,只有本地才可以

def highWatermark_=(newHighWatermark: LogOffsetMetadata) {
  // 只有本地副本才可以更新HighWatermark
  if (isLocal) {
    highWatermarkMetadata = newHighWatermark
    trace("Setting high watermark for replica %d partition [%s,%d] on broker %d to [%s]"
      .format(brokerId, topic, partitionId, brokerId, newHighWatermark))
  } else {
    throw new KafkaException("Should not set high watermark on partition [%s,%d]'s non-local replica %d".format(topic, partitionId, brokerId))
  }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫言静好、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值