Kafka客户端是如何找到Leader分区的 (转载)

正常情况下kafka的每个topic都会有很多partition,每个partition又有几个副本,这些副本中会有一个leader,其余的都是follower,所有对分区的读写操作都是对leader分区进行的。所以当我们向kafka发起读写的请求时,必须先找到对应分区的leader以及所在Broker地址,这样才能进行后续的工作。、

Kafka内部的Metadata协议

Metadata协议主要解决的问题:

①kafka中存在哪些主题

②每个主题有几个分区

③Leader分区所在的broker地址及端口

④每个broker的地址及端口号是多少

客户端只需要构造相应的请求,并发送到Broker端,即可获得上面四个答案。整个过程如下:

●客户端构造相应的请求

●客户端将请求发送到Broker端

●Broker端接受请求处理,并将结果发送到客户端。

Metadata请求协议(v0-v3版本)如下:=

TopicMetadataRequest => [TopicNames]
  TopicNames => string

客户端只需要构造一个TopicMetadataRequest,里面包括我们查询的主题名字(TopicName);也可以一次查询多个主题,只需要将这些主题放到一个List里面。同时也可以不传任何主题名字,这时kafka将会把所有的主题相关的信息发送给客户端。

kafka的Broker收到客户端请求后,会构造一个TopicMetadataResponse返回给客户端,TopicMetadataResponse协议如下:

MetadataResponse => [Broker][TopicMetadata]
  Broker => NodeId Host Port  (any number of brokers may be returned)
    NodeId => int32
    Host => string
    Port => int32
  TopicMetadata => TopicErrorCode TopicName [PartitionMetadata]
    TopicErrorCode => int16
  PartitionMetadata => PartitionErrorCode PartitionId Leader Replicas Isr
    PartitionErrorCode => int16
    PartitionId => int32
    Leader => int32
    Replicas => [int32]
    Isr => [int32]

协议中包含了每个分区的Leader、Replicas、以及lsr信息,同时也包含了kafka集群所有的Broker的信息。如果处理出现问题,会出现相应的错误提示:

UnknownTopic (3)
LeaderNotAvailable (5)
InvalidTopic (17)
TopicAuthorizationFailed (29)

********************************

构造TopicMetadataResquest是通过simpleConsumer的send方法发送的,返回的就是TopicMetadataResponse.

package com.iteblog.kafka
 
import kafka.api.TopicMetadataRequest._
import kafka.api.{TopicMetadataRequest, TopicMetadataResponse}
import kafka.consumer.SimpleConsumer
 
/////////////////////////////////////////////////////////////////////
 User: 过往记忆
 Date: 2017年07月28日
 Time: 22:12:43
 bolg: https://www.iteblog.com
 本文地址:https://www.iteblog.com/archives/2215
 过往记忆博客,专注于hadoop、hive、spark、shark、flume的技术博客,大量的干货
 过往记忆博客微信公共帐号:iteblog_hadoop
/////////////////////////////////////////////////////////////////////
 
object MetaDataDemo {
  def main(args: Array[String]): Unit = {
    val consumer = new SimpleConsumer("1.iteblog.com", 9092, 50, 1024 * 4, DefaultClientId)
 
    val req: TopicMetadataRequest = new TopicMetadataRequest(CurrentVersion, 0, DefaultClientId, List("iteblog_hadoop"))
    val resp: TopicMetadataResponse = consumer.send(req)
 
    println("Broker Infos:")
    println(resp.brokers.mkString("\n\t"))
    val metadata = resp.topicsMetadata
    metadata.foreach { topicMetadata =>
      val partitionsMetadata = topicMetadata.partitionsMetadata
      partitionsMetadata.foreach { partitionMetadata =>
        println(s"partitionId=${partitionMetadata.partitionId}\n\tleader=${partitionMetadata.leader}" +
          s"\n\tisr=${partitionMetadata.isr}\n\treplicas=${partitionMetadata.replicas}")
      }
    }
  }
}

运行上面程序输出如下:

Broker Infos:
    id:5,host:5.iteblog.com,port:9092
    id:1,host:1.iteblog.com,port:9092
    id:6,host:6.iteblog.com,port:9092
    id:2,host:2.iteblog.com,port:9092
    id:7,host:7.iteblog.com,port:9092
    id:3,host:3.iteblog.com,port:9092
    id:8,host:8.iteblog.com,port:9092
    id:4,host:4.iteblog.com,port:9092
partitionId=0
    leader=Some(id:1,host:1.iteblog.com,port:9092)
    isr=Vector(id:1,host:1.iteblog.com,port:9092)
    replicas=Vector(id:1,host:1.iteblog.com,port:9092, id:8,host:8.iteblog.com,port:9092)
partitionId=1
    leader=Some(id:2,host:2.iteblog.com,port:9092)
    isr=Vector(id:2,host:2.iteblog.com,port:9092, id:1,host:1.iteblog.com,port:9092)
    replicas=Vector(id:2,host:2.iteblog.com,port:9092, id:1,host:1.iteblog.com,port:9092)
partitionId=2
    leader=Some(id:3,host:3.iteblog.com,port:9092)
    isr=Vector(id:3,host:3.iteblog.com,port:9092, id:2,host:2.iteblog.com,port:9092)
    replicas=Vector(id:3,host:3.iteblog.com,port:9092, id:2,host:2.iteblog.com,port:9092)
partitionId=3
    leader=Some(id:4,host:4.iteblog.com,port:9092)
    isr=Vector(id:4,host:4.iteblog.com,port:9092, id:3,host:3.iteblog.com,port:9092)
    replicas=Vector(id:4,host:4.iteblog.com,port:9092, id:3,host:3.iteblog.com,port:9092)
partitionId=4
    leader=Some(id:5,host:5.iteblog.com,port:9092)
    isr=Vector(id:5,host:5.iteblog.com,port:9092, id:4,host:4.iteblog.com,port:9092)
    replicas=Vector(id:5,host:5.iteblog.com,port:9092, id:4,host:4.iteblog.com,port:9092)
partitionId=5
    leader=Some(id:6,host:6.iteblog.com,port:9092)
    isr=Vector(id:6,host:6.iteblog.com,port:9092, id:5,host:5.iteblog.com,port:9092)
    replicas=Vector(id:6,host:6.iteblog.com,port:9092, id:5,host:5.iteblog.com,port:9092)
partitionId=6
    leader=Some(id:7,host:7.iteblog.com,port:9092)
    isr=Vector(id:6,host:6.iteblog.com,port:9092, id:7,host:7.iteblog.com,port:9092)
    replicas=Vector(id:7,host:7.iteblog.com,port:9092, id:6,host:6.iteblog.com,port:9092)
partitionId=7
    leader=Some(id:8,host:8.iteblog.com,port:9092)
    isr=Vector(id:8,host:8.iteblog.com,port:9092)
    replicas=Vector(id:8,host:8.iteblog.com,port:9092, id:7,host:7.iteblog.com,port:9092)
partitionId=8
    leader=Some(id:1,host:1.iteblog.com,port:9092)
    isr=Vector(id:2,host:2.iteblog.com,port:9092, id:1,host:1.iteblog.com,port:9092)
    replicas=Vector(id:1,host:1.iteblog.com,port:9092, id:2,host:2.iteblog.com,port:9092)
partitionId=9
    leader=Some(id:2,host:2.iteblog.com,port:9092)
    isr=Vector(id:3,host:3.iteblog.com,port:9092, id:2,host:2.iteblog.com,port:9092)
    replicas=Vector(id:2,host:2.iteblog.com,port:9092, id:3,host:3.iteblog.com,port:9092)
partitionId=10
    leader=Some(id:3,host:3.iteblog.com,port:9092)
    isr=Vector(id:4,host:4.iteblog.com,port:9092, id:3,host:3.iteblog.com,port:9092)
    replicas=Vector(id:3,host:3.iteblog.com,port:9092, id:4,host:4.iteblog.com,port:9092)
partitionId=11
    leader=Some(id:6,host:6.iteblog.com,port:9092)
    isr=Vector(id:6,host:6.iteblog.com,port:9092, id:1,host:1.iteblog.com,port:9092)
    replicas=Vector(id:6,host:6.iteblog.com,port:9092, id:1,host:1.iteblog.com,port:9092)
partitionId=12
    leader=Some(id:7,host:7.iteblog.com,port:9092)
    isr=Vector(id:7,host:7.iteblog.com,port:9092, id:2,host:2.iteblog.com,port:9092)
    replicas=Vector(id:7,host:7.iteblog.com,port:9092, id:2,host:2.iteblog.com,port:9092)
partitionId=13
    leader=Some(id:8,host:8.iteblog.com,port:9092)
    isr=Vector(id:8,host:8.iteblog.com,port:9092, id:3,host:3.iteblog.com,port:9092)
    replicas=Vector(id:8,host:8.iteblog.com,port:9092, id:3,host:3.iteblog.com,port:9092)
partitionId=14
    leader=Some(id:1,host:1.iteblog.com,port:9092)
    isr=Vector(id:1,host:1.iteblog.com,port:9092, id:4,host:4.iteblog.com,port:9092)
    replicas=Vector(id:1,host:1.iteblog.com,port:9092, id:4,host:4.iteblog.com,port:9092)
partitionId=15
    leader=Some(id:2,host:2.iteblog.com,port:9092)
    isr=Vector(id:2,host:2.iteblog.com,port:9092, id:5,host:5.iteblog.com,port:9092)
    replicas=Vector(id:2,host:2.iteblog.com,port:9092, id:5,host:5.iteblog.com,port:9092)
partitionId=16
    leader=Some(id:3,host:3.iteblog.com,port:9092)
    isr=Vector(id:3,host:3.iteblog.com,port:9092, id:7,host:7.iteblog.com,port:9092)
    replicas=Vector(id:3,host:3.iteblog.com,port:9092, id:7,host:7.iteblog.com,port:9092)
partitionId=17
    leader=Some(id:4,host:4.iteblog.com,port:9092)
    isr=Vector(id:4,host:4.iteblog.com,port:9092, id:8,host:8.iteblog.com,port:9092)
    replicas=Vector(id:4,host:4.iteblog.com,port:9092, id:8,host:8.iteblog.com,port:9092)
partitionId=18
    leader=Some(id:5,host:5.iteblog.com,port:9092)
    isr=Vector(id:5,host:5.iteblog.com,port:9092, id:1,host:1.iteblog.com,port:9092)
    replicas=Vector(id:5,host:5.iteblog.com,port:9092, id:1,host:1.iteblog.com,port:9092)
partitionId=19
    leader=Some(id:6,host:6.iteblog.com,port:9092)
    isr=Vector(id:6,host:6.iteblog.com,port:9092, id:2,host:2.iteblog.com,port:9092)
    replicas=Vector(id:6,host:6.iteblog.com,port:9092, id:2,host:2.iteblog.com,port:9092)
partitionId=20
    leader=Some(id:7,host:7.iteblog.com,port:9092)
    isr=Vector(id:7,host:7.iteblog.com,port:9092, id:3,host:3.iteblog.com,port:9092)
    replicas=Vector(id:7,host:7.iteblog.com,port:9092, id:3,host:3.iteblog.com,port:9092)
partitionId=21
    leader=Some(id:8,host:8.iteblog.com,port:9092)
    isr=Vector(id:8,host:8.iteblog.com,port:9092, id:4,host:4.iteblog.com,port:9092)
    replicas=Vector(id:8,host:8.iteblog.com,port:9092, id:4,host:4.iteblog.com,port:9092)
partitionId=22
    leader=Some(id:1,host:1.iteblog.com,port:9092)
    isr=Vector(id:1,host:1.iteblog.com,port:9092, id:5,host:5.iteblog.com,port:9092)
    replicas=Vector(id:1,host:1.iteblog.com,port:9092, id:5,host:5.iteblog.com,port:9092)

***********************************

KafkaUtils.createDirectStream中通过调用kafka源码cluster.class实现自己管理offset的过程相同


阅读更多
文章标签: kafka
个人分类: BigData
上一篇深入理解java虚拟机之--数据区域
下一篇ELK原理与介绍
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭