正常情况下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的过程相同