4.2.3 Kafka高级特性解析(主题--shell管理、增加分区、分区副本分配、app操作;分区--leader选举、重新分配、自动再均衡、分区策略)

Kafka高级特性解析



2.3 主题

2.3.1 管理

使用kafka-topics.sh脚本:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
主题中可以使用的参数定义:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3.1.1 创建主题
[root@linux01 ~]# kafka-topics.sh --zookeeper linux01:2181/mykafka --create --topic topic_x --partitions 1 --replication-factor 1

[root@linux01 ~]# kafka-topics.sh --zookeeper linux01:2181/mykafka --create --topic topic_test_02 --partitions 3 --replication-factor 1 --config max.message.bytes=1048576 --config segment.bytes=10485760
2.3.1.2 查看主题
[root@linux01 ~]# kafka-topics.sh --zookeeper linux01:2181/mykafka --list
[root@linux01 ~]# kafka-topics.sh --zookeeper linux01:2181/mykafka --describe --topic topic_x
[root@linux01 ~]# kafka-topics.sh --zookeeper linux01:2181/mykafka --topics-with-overrides --describe

在这里插入图片描述

2.3.1.3 修改主题
[root@linux01 ~]# kafka-topics.sh --zookeeper linux01:2181/mykafka --create --topic topic_test_01 --partitions 2 --replication-factor 1
[root@linux01 ~]# kafka-topics.sh --zookeeper linux01:2181/mykafka  --alter --topic topic_test_01 --config max.message.bytes=1048576
[root@linux01 ~]# kafka-topics.sh --zookeeper linux01:2181/mykafka --describe --topic topic_test_01
[root@linux01 ~]# kafka-topics.sh --zookeeper linux01:2181/mykafka  --alter --topic topic_test_01 --config segment.bytes=10485760
[root@linux01 ~]# kafka-topics.sh --zookeeper linux01:2181/mykafka --alter --delete-config max.message.bytes --topic topic_test_01
2.3.1.4 删除主题
[root@linux01 ~]# kafka-topics.sh --zookeeper linux01:2181/mykafka --delete --topic topic_test_02

在这里插入图片描述
[root@linux01 ~]# cd /var/lagou/kafka/kafka-logs/
在这里插入图片描述
如上,给主题添加删除的标记:
topic_test_02-0.5f680b9bc37a4b669b906009155d886a-delete
要过一段时间删除。

2.3.2 增加分区

通过命令行工具操作,主题的分区只能增加,不能减少。否则报错:
在这里插入图片描述
通过–alter修改主题的分区数,增加分区。

kafka-topics.sh --zookeeper linux01/mykafka --alter --topic topic_test_01 --partitions 3

在这里插入图片描述

2.3.3 分区副本的分配-了解

副本分配的三个目标:

  1. 均衡地将副本分散于各个broker上
  2. 对于某个broker上分配的分区,它的其他副本在其他broker上
  3. 如果所有的broker都有机架信息,尽量将分区的各个副本分配到不同机架上的broker。

在不考虑机架信息的情况下:

  1. 第一个副本分区通过轮询的方式挑选一个broker,进行分配。该轮询从broker列表的随机位
    置进行轮询。
  2. 其余副本通过增加偏移进行分配。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3.4 必要参数配置

kafka-topics.sh --config xx=xx --config yy=yy
配置给主题的参数。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3.5 KafkaAdminClient应用

说明
除了使用Kafka的bin目录下的脚本工具来管理Kafka,还可以使用管理Kafka的API将某些管理查看的功能集成到系统中。在Kafka0.11.0.0版本之前,可以通过kafka-core包(Kafka的服务端,采用Scala
编写)中的AdminClient和AdminUtils来实现部分的集群管理操作。Kafka0.11.0.0之后,又多了一个AdminClient,在kafka-client包下,一个抽象类,具体的实现是org.apache.kafka.clients.admin.KafkaAdminClient。

功能与原理介绍
Kafka官网:The AdminClient API supports managing and inspecting topics, brokers, acls, and other Kafka objects。
KafkaAdminClient包含了一下几种功能(以Kafka1.0.2版本为准):

  1. 创建主题:
    createTopics(final Collection newTopics, final CreateTopicsOptions options)
  2. 删除主题:
    deleteTopics(final Collection topicNames,DeleteTopicsOptions options)
  3. 列出所有主题:
    listTopics(final ListTopicsOptions options)
  4. 查询主题:
    describeTopics(final Collection topicNames, DescribeTopics Options options)
  5. 查询集群信息:
    describeCluster(DescribeClusterOptions options)
  6. 查询配置信息:
    describeConfigs(Collection configResources, final
    DescribeConfigsOptions options)
  7. 修改配置信息:
    alterConfigs(Map<ConfigResource, Config> configs, final AlterConfigsOptions options)
  8. 修改副本的日志目录:
    alterReplicaLogDirs(Map<TopicPartitionReplica, String> replicaAssignment,final AlterReplicaLogDirsOptions options)
  9. 查询节点的日志目录信息:
    describeLogDirs(Collection brokers,DescribeLogDirsOptions options)
  10. 查询副本的日志目录信息:
    describeReplicaLogDirs(Collection replicas,
    DescribeReplicaLogDirsOptions options)
  11. 增加分区:
    createPartitions(Map<String, NewPartitions> newPartitions, final
    CreatePartitionsOptions options)

其内部原理是使用Kafka自定义的一套二进制协议来实现,详细可以参见Kafka协议。
用到的参数:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
主要操作步骤:
客户端根据方法的调用创建相应的协议请求,比如创建Topic的createTopics方法,其内部就是发送CreateTopicRequest请求。

客户端发送请求至Kafka Broker。

Kafka Broker处理相应的请求并回执,比如与CreateTopicRequest对应的是CreateTopicResponse。 客户端接收相应的回执并进行解析处理。

和协议有关的请求和回执的类基本都在org.apache.kafka.common.requests包中,AbstractRequest和AbstractResponse是这些请求和响应类的两个父类。

综上,如果要自定义实现一个功能,只需要三个步骤:

  1. 自定义XXXOptions;
  2. 自定义XXXResult返回值;
  3. 自定义Call,然后挑选合适的XXXRequest和XXXResponse来实现Call类中的3个抽象方法。

具体实现:
pom.xml

<dependencies>
        <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka-clients</artifactId>
            <version>1.0.2</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

实现类:MyAdminClient

查看主题
package com.lagou.kafka;

import org.apache.kafka.clients.admin.*;
import org.apache.kafka.common.KafkaFuture;
import org.apache.kafka.common.Node;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.TopicPartitionInfo;
import org.apache.kafka.common.config.ConfigResource;
import org.apache.kafka.common.requests.DescribeLogDirsResponse;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.BiConsumer;
import java.util.function.Consumer;

public class MyAdminClient {
   

    private KafkaAdminClient client;

    @Before
    public void before() {
   

        Map<String, Object> configs = new HashMap<>();
        configs.put("bootstrap.servers", "linux01:9092");
        configs.put("client.id", "admin_001");

        client = (KafkaAdminClient) KafkaAdminClient.create(configs);
    }

    @After
    public void after() {
   
        // 关闭admin客户端
        client.close();
    }

    @Test
    public void testListTopics1() throws ExecutionException, InterruptedException {
   

        ListTopicsResult listTopicsResult = client.listTopics();


        // 1.1 将请求变成同步的请求,直接获取结果======================================
        KafkaFuture<Collection<TopicListing>> listings = listTopicsResult.listings();
        Collection<TopicListing> topicListings = listings.get();

        topicListings.forEach(new Consumer<TopicListing>() {
   
            @Override
            public void accept(TopicListing topicListing) {
   
                // 该主题是否是内部主题
                boolean internal = topicListing.isInternal();
                // 打印主题名字
                String name = topicListing.name();
                // 直接打印全部信息
                String s = topicListing.toString();
                System.out.println(s + "\t" + name + "\t" + internal);
            }
        });

    }
}

在这里插入图片描述
异步方法列出主题

@Test
    public void testListTopics1() throws ExecutionException, InterruptedException {
   

        ListTopicsResult listTopicsResult = client.listTopics();
        
        // 1.2, 异步方法列出主题======================================
        KafkaFuture<Set<String>> names = listTopicsResult.names();
        Set<String> strings = names.get();

        strings.forEach(name -> {
   
            System.out.println(name);
        });

        KafkaFuture<Map<String, TopicListing>> mapKafkaFuture = listTopicsResult.namesToListings();
        Map<String, TopicListing> stringTopicListingMap = mapKafkaFuture.get();

        stringTopicListingMap.forEach((k, v) -> {
   
            System.out.println(k + "\t" + v);
        });

    }

在这里插入图片描述
设置请求属性

@Test
    public void testListTopics1() throws ExecutionException, InterruptedException {
   
        
        //另一种方法, 可以设置请求的属性
        ListTopicsOptions options = new ListTopicsOptions();
        // 列出内部主题
        options.listInternal(true);
        // 设置超时时间
        options.timeoutMs(900);
        ListTopicsResult listTopicsResult1 = client.listTopics(options);

        Map<String, TopicListing> stringTopicListingMap1 = listTopicsResult1.namesToListings().get();

        stringTopicListingMap1.forEach((k, v) -> {
   
            System.out.println(k + "\t" + v);
        });

        // 关闭管理客户端
        client.close();
    }

在这里插入图片描述

创建主题
// 创建主题
    @Test
    public void testCreateTopic() throws ExecutionException, InterruptedException {
   

        Map<String, String> configs = new HashMap<>();

        configs.put("max.message.bytes", "1048576");
        configs.put("segment.bytes", "1048576000");

        NewTopic newTopic = new NewTopic("adm_tp_01", 2, (short) 1);
        newTopic.configs(configs);
        CreateTopicsResult topics = client.createTopics(Collections.singleton(newTopic));

        KafkaFuture<Void> all = topics.all();
        Void aVoid = all.get();

        System.out.println(aVoid);
    }

在这里插入图片描述

删除主题
@Test
    public 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值