Kafka 副本管理模块(五):副本读取 fetchMessages 方法

副本读取:fetchMessages方法读取需要的消息,它逻辑如下:

  def fetchMessages(timeout: Long, // 请求处理超时时间。
                    replicaId: Int, // 副本 ID。对于消费者而言,该参数值是 -1;对于 Follower 副本而言,该值就是 Follower 副本所在的 Broker ID。
                    fetchMinBytes: Int, // 够获取的最小字节数。
                    fetchMaxBytes: Int, // 够获取的最大字节数。
                    hardMaxBytesLimit: Boolean, // 对能否超过最大字节数做硬限制。
                    fetchInfos: Seq[(TopicPartition, PartitionData)], // 规定了读取分区的信息,比如要读取哪些分区、从这些分区的哪个位移值开始读、最多可以读多少字节,等等。
                    quota: ReplicaQuota, // 这是一个配额控制类,主要是为了判断是否需要在读取的过程中做限速控制。
                    responseCallback: Seq[(TopicPartition, FetchPartitionData)] => Unit, // Response 回调逻辑函数。当请求被处理完成后,调用该方法执行收尾逻辑。
                    isolationLevel: IsolationLevel,
                    clientMetadata: Option[ClientMetadata]): Unit = {
    // 判断该读取请求是否来自于Follower副本或Consumer
    val isFromFollower = Request.isValidBrokerId(replicaId)
    val isFromConsumer = !(isFromFollower || replicaId == Request.FutureLocalReplicaId)
    // 根据请求发送方判断可读取范围
    // 如果请求来自于普通消费者,那么可以读到高水位值
    // 如果请求来自于配置了READ_COMMITTED的消费者,那么可以读到Log Stable Offset值
    // 如果请求来自于Follower副本,那么可以读到LEO值
    val fetchIsolation = if (!isFromConsumer)
      FetchLogEnd
    else if (isolationLevel == IsolationLevel.READ_COMMITTED)
      FetchTxnCommitted
    else
      FetchHighWatermark

    // Restrict fetching to leader if request is from follower or from a client with older version (no ClientMetadata)
    val fetchOnlyFromLeader = isFromFollower || (isFromConsumer && clientMetadata.isEmpty)
    // 定义readFromLog方法读取底层日志中的消息
    def readFromLog(): Seq[(TopicPartition, LogReadResult)] = {
      val result = readFromLocalLog(
        replicaId = replicaId,
        fetchOnlyFromLeader = fetchOnlyFromLeader,
        fetchIsolation = fetchIsolation,
        fetchMaxBytes = fetchMaxBytes,
        hardMaxBytesLimit = hardMaxBytesLimit,
        readPartitionInfo = fetchInfos,
        quota = quota,
        clientMetadata = clientMetadata)
      if (isFromFollower) updateFollowerFetchState(replicaId, result)
      else result
    }

    val logReadResults = readFromLog()

    // check if this fetch request can be satisfied right away
    var bytesReadable: Long = 0
    var errorReadingData = false
    val logReadResultMap = new mutable.HashMap[TopicPartition, LogReadResult]
    var anyPartitionsNeedHwUpdate = false
    // 统计总共可读取的字节数
    logReadResults.foreach { case (topicPartition, logReadResult) =>
      if (logReadResult.error != Errors.NONE)
        errorReadingData = true
      bytesRe
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值