20 KafkaAdminClient

初识KafkaAdminClient

一般情况下,我们习惯使用 kafka-topics.sh 脚本来管理主题。但有些时候我们希望将主题管理类的功能集成到公司内部系统中,集管理、监控、运维、警告等一体,那么就需要以程序调用API的方式去实现。这节主要记录 KafkaAdminClient 的基本使用方式,以及采用这种方式创建主题时的合法性验证。

基本使用

在代码清单16-1中使用了 TopCommand 创建了一个主题,也可以用这样的方式实现主题的删除、修改、查看等操作,实际上与 kafka-config.sh 脚本的方式无异。但是这样的方式与应用程序的交互非常差,类似与拼写字符串,而且返回值是void类,并不能提供给调用者有效的反馈信息,代码如20-1所示。而 KafkAdminClient 不仅可以用来管理broker、配置和ACL (Access Control List),还可以用来管理主题。:

//代码清单20-1查看主题
public static void describeTopic(){
    String[] options = new String[]{
            "--zookeeper", "localhost:2181/kafka",
            "--describe",
            "--topic", "topic-create"
    };
    kafka.admin.TopicCommand.main(options);
}

KafkaAdminClient 继承了 org.apache.kafka.clients.admin.AdminClient 抽象类,并提供了多种方法,下面列出一些简单方法

  • 创建主题:CreateTopicsResult createTopics(Collection newTopics)。
  • 删除主题:DeleteTopicsResult deleteTopics(Collection topics)。
  • 列出所有可用的主题:ListTopicsResult listTopics()。
  • 查看主题的信息:DescribeTopicsResult describeTopics(Collection topicNames)。
  • 查询配置信息:DescribeConfigsResult describeConfigs(Collection resources)。
  • 修改配置信息:AlterConfigsResult alterConfigs(Map<ConfigResource, Config> configs)。
  • 增加分区:CreatePartitionsResult createPartitions(Map<String, NewPartitions> newPartitions)。

创建主题

创建一个分区数为4、副本因子为1的主题 topic-admin,代码清单20-2

		String brokerList="192.168.211.128:9092";
        String topic="topic-admin";
		//配置kafka信息
        Properties props=new Properties();
        props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG,brokerList);
        props.put(AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG,30000);
        
		//创建 KafkaAdminClient实例
        AdminClient client=AdminClient.create(props);

		//设置要创建主题的具体信息
        NewTopic newTopic= new NewTopic(topic,4,(short) 1);
        CreateTopicsResult result = client.createTopics(Collections.singleton(newTopic));

        try {
            result.all().get();
        } catch (InterruptedException |  ExecutionException e) {
            e.printStackTrace();
        }

        client.close();

NewTopic中成员变量如下:

	private final String name; //主题名称
    private final int numPartitions; //分区数量
    private final short replicationFactor; //副本因子
    private final Map<Integer, List<Integer>> replicasAssignments; //分配方案
    private Map<String, String> configs = null; //配置

和 kafka-topics.sh 脚本一样,可以通过指定分区数和副本因子创建主题,也可以通过指定分区副本的具体分配方案来创建主题,比如将创建 NewTopic 修改如下:

Map<Integer, List<Integer>> replicasAssignments = new HashMap<>();
replicasAssignments.put(0, Arrays.asList(0));
replicasAssignments.put(1, Arrays.asList(0));
replicasAssignments.put(2, Arrays.asList(0));
replicasAssignments.put(3, Arrays.asList(0));
NewTopic newTopic = new NewTopic(topic, replicasAssignments);

也可以在创建主题时,指定需要覆盖的配置。创建好 NewTopic 对象后添加配置

 		NewTopic newTopic= new NewTopic(topic,4,(short) 1);
        Map<String,String> configs = new HashMap<>();
        configs.put("cleanup.policy","compact");
        newTopic.configs(configs);
        CreateTopicsResult result = client.createTopics(Arrays.asList(newTopic));

在这里插入图片描述
client.createTopics() 是创建主题的核心。KafkaAdminClient 使用 kafka 自定义的一套二进制协议来实现这些管理功能。主要实现步骤如下:

  1. 客户端根据调用方法创建对应请求,比如创建主题的 createTopics 方法,内部就是发送 CreateTopicRequest 请求。
  2. 客户端将请求发送的到服务端。
  3. 服务端处理请求并返回响应,比如与 createTopicsRequest请求对应的响应为 crerateTopicsResponse
  4. 客户端接收响应并处理。和协议相关的请求和响应类基本在 org.apache.kafka.common.requests 包下,AbstractRequestAbstractResponse 是请求和响应类的两个基本父类。

创建主题方法的返回值是 CreateTopicsResult 类型,定义如下20-3

private final Map<String, KafkaFuture<Void>> futures;

    CreateTopicsResult(Map<**String, KafkaFuture<Void>> futures) {
        this.futures = futures;
    }
    public Map<String, KafkaF**uture<Void>> values() {
        return this.futures;
    }

    public KafkaFuture<Void> all() {
        return KafkaFuture.allOf((KafkaFuture[])this.futures.values().toArray(new KafkaFuture[0]));
    }

成员变量 futures 的类型是Map<String, KafkaFuture> 中的 key 代表主题名称,而 KafkaFuture 代表创建后的返回值类型。KafkaFuture 原本是为了支持jdk8以下版本自定义的一个类,实现了 Frture 接口,可以通过 Frture.get() 方法来等服务端的返回,比如20-1代码清单中 **result.all().get()**在未来的版本中,会有计划地将 KafkaFuture 替换为JDK8中引入的 CompletableFuture。
虽然创建主题之后返回值类型是Void,但是不是所有操作返回值都是Voic。比如 listTopics 方法返回值 ListTopicsResult 类型内部的成员变量 future 的类型为 KafkaFuture<Map<Striing,TopicListing>>
在使用 KafkaAdminClient 之后记得要调用 close() 方法来释放资源。

查看配置信息

KafkaAdminClient 中的 deleteTopcis()listTopics()describeTopics 都很简单。讲下 describeConfigs()alterConfigs() 这两个方法。查看刚刚创建的主题的配置信息,最终结果是主题的所有配置信息。代码清单20-4

扫描二维码关注公众号,回复: 10922087 查看本文章
String brokerList="192.168.211.128:9092";
        String topic="topic-test2";

        Properties props=new Properties();
        props.put(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG,brokerList);
        props.put(AdminClientConfig.REQUEST_TIMEOUT_MS_CONFIG,30000);
        AdminClient client=AdminClient.create(props);

        ConfigResource resource = new ConfigResource(ConfigResource.Type.TOPIC,topic);
        DescribeConfigsResult result = client.describeConfigs(Collections.singleton(resource));
        Config config = result.all().get().get(resource);
        System.out.println(config);
        client.close();

修改配置信息

		ConfigResource resource = new ConfigResource(ConfigResource.Type.TOPIC,topic);
        
        ConfigEntry entry = new ConfigEntry("cleanup.policy", "compact");
        AlterConfigOp config=new AlterConfigOp(entry,AlterConfigOp.OpType.SET);

        Map<ConfigResource, Collection<AlterConfigOp>> configs = new HashMap<>();
        configs.put(resource,Arrays.asList(config));
        //修改
        AlterConfigsResult result = client.incrementalAlterConfigs(configs);

在这里插入图片描述

增加主题分区

		NewPartitions newPartitions=NewPartitions.increaseTo(2);
        Map<String,NewPartitions> map=new HashMap<>();
        map.put(topic,newPartitions);
        CreatePartitionsResult result = client.createPartitions(map);
        result.all().get();

分区增加
在这里插入图片描述

发布了76 篇原创文章 · 获赞 1 · 访问量 5087

猜你喜欢

转载自blog.csdn.net/qq_38083545/article/details/104481199
20)
$20
20