正常情况下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
=
> int
32
Host
=
> string
Port
=
> int
32
TopicMetadata
=
> TopicErrorCode TopicName [PartitionMetadata]
TopicErrorCode
=
> int
16
PartitionMetadata
=
> PartitionErrorCode PartitionId Leader Replicas Isr
PartitionErrorCode
=
> int
16
PartitionId
=
> int
32
Leader
=
> int
32
Replicas
=
> [int
32
]
Isr
=
> [int
32
]
协议中包含了每个分区的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的过程相同