Kafka: Get broker host from ZooKeeper

前端 未结 5 1037
伪装坚强ぢ
伪装坚强ぢ 2020-12-02 13:32

For particular reasons I need to use both - ConsumerGroup (a.k.a. high-level consumer) and SimpleConsumer (a.k.a. low-level consumer) to read from

5条回答
  •  无人及你
    2020-12-02 14:18

    It turns out that Kafka uses ZKStringSerializer to read and write data into znodes. So, to fix the error I only had to add it as a last parameter in ZkClient constructor:

    val zkClient = new ZkClient(zkQuorum, Integer.MAX_VALUE, 10000, ZKStringSerializer)
    

    Using it, I wrote several useful functions for discovering broker ids, their addresses and other stuff:

    import kafka.utils.Json
    import kafka.utils.ZKStringSerializer
    import kafka.utils.ZkUtils
    import org.I0Itec.zkclient.ZkClient
    import org.apache.kafka.common.KafkaException
    
    
    def listBrokers(): List[Int] = {
      zkClient.getChildren("/brokers/ids").toList.map(_.toInt)
    }
    
    def listTopics(): List[String] = {
      zkClient.getChildren("/brokers/topics").toList
    }
    
    def listPartitions(topic: String): List[Int] = {
      val path = "/brokers/topics/" + topic + "/partitions"
      if (zkClient.exists(path)) {
        zkClient.getChildren(path).toList.map(_.toInt)
      } else {
        throw new KafkaException(s"Topic ${topic} doesn't exist")
      }
    }
    
    def getBrokerAddress(brokerId: Int): (String, Int) = {
      val path = s"/brokers/ids/${brokerId}"
      if (zkClient.exists(path)) {
        val brokerInfo = readZkData(path)
        (brokerInfo.get("host").get.asInstanceOf[String], brokerInfo.get("port").get.asInstanceOf[Int])
      } else {
        throw new KafkaException("Broker with ID ${brokerId} doesn't exist")
      }
    }
    
    def getLeaderAddress(topic: String, partitionId: Int): (String, Int) = {
      val path = s"/brokers/topics/${topic}/partitions/${partitionId}/state"
      if (zkClient.exists(path)) {
        val leaderStr = zkClient.readData[String](path)
        val leaderId = Json.parseFull(leaderStr).get.asInstanceOf[Map[String, Any]].get("leader").get.asInstanceOf[Int]
        getBrokerAddress(leaderId)
      } else {
        throw new KafkaException(s"Topic (${topic}) or partition (${partitionId}) doesn't exist")
      }
    }
    

提交回复
热议问题