kafka学习笔记-客户端操作

kafka学习笔记-客户端操作

​ kafka其实没有所谓单节点这一说,即使是一个节点也是一个节点的集群,所以kafka默认就是一个集群的形式。

在这里插入图片描述

kafka客户端API类型

  • AdminClient API:允许管理和检测Topic、broker以及其他kafka对象。类似服务器上命令行对topic等操作。
  • Producer API:发布消息到1个或多个Topic
  • Consumer API:订阅一个或多个Topic,并处理产生的消息,相对比较复杂的API
  • Streams API:高效地将输入流转换到输出流
  • Connector API:从一些源系统或应用程序中拉取数据到kafka

Admin API

我们先新建一个SpringBoot项目,并引入web及kafka的依赖,kafka的依赖可以在maven repository或者kafka官网中获取

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

常见Admin API

API作用
AdminClientAdminClient客户端对象
NewTopic创建Topic
CreateTopicsResult创建Topic的返回结果
ListTopicsResult查询Topic列表
ListTopicsOptions查询Topoic列表及选项
DescribeTopicsResult查询Topics
DescribeConfigsResult查询Topics配置项
  • AdminClient:
public class AdminSample {

    public static void main(String[] args) {
        AdminClient adminClient = getAdminClient();
        System.out.println("adminClient: " + adminClient);
    }

    private static AdminClient getAdminClient() {
        // 启动AdminClient时需要的配置信息
        Properties properties = new Properties();
        // 具体需要配置什么我们可以点进AdminClientConfig中查看,目前只为了启动可以只配置bootstrap_server
        // 可以新建一个类专门用于存放kafka的配置信息,也可直接写入
        properties.setProperty(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, KafkaConfig.BOOTSTRAP_SERVER);
        // properties.setProperty(AdminClientConfig.BOOTSTRAP_SERVERS_CONFIG, xxx.xxx.xxx.xxx:9092);

        // 最后返回.create(Properties properties),将写好的配置放进去即可
        return AdminClient.create(properties);
    }
}
  • NewTopic:
/**
     * 创建Topic实例
     */
private static void createNewTopic() throws Exception {
    // 先获取到我们的adminClient
    AdminClient adminClient = getAdminClient();
    // 实例化我们所需要创建的topic,点进源码我们可看到该构造函数需要传入三个值:
    // name:待创建的topic的名称
    // numPartitions:新topic的分区数
    // replicationFactor:副本因子
    NewTopic newTopic = new NewTopic(KafkaConfig.TOPIC_NAME, KafkaConfig.NUM_PARTITIONS, KafkaConfig.REPLICATION_FACTOR);
    // 调用adminClient的createTopics方法,传入待创建的topic的集合即可
    // 为此操作设置请求超时(以毫秒为单位),如果应使用AdminClient的默认请求超时,则设置为null
    CreateTopicsResult topics = adminClient.createTopics(Arrays.asList(newTopic), new CreateTopicsOptions().timeoutMs(10000));
    // all():如果所有topic都创建成功,则返回一个成功的future。 get():如有必要,等待此future完成,然后返回其结果
    topics.all().get();

    System.out.println("新的topic已创建成功");
}

​ 点进源码我们能看到,NewTopic的构造函数中,有这么几个参数:

public NewTopic(String name, int numPartitions, short replicationFactor) {
    this(name, Optional.of(numPartitions), Optional.of(replicationFactor));
}

​ 在官网上也有对于这几个参数的文档说明,是这么描述的:

/*
name: The name of the topic to be created
      待创建的topic的名称
    
numPartitions: The number of partitions for the new topic or -1 if a replica assignment has been specified
    		   新主题的分区数,如果指定了副本分配,则为 -1
    
replicationFactor: The replication factor for the new topic or -1 if a replica assignment has been specified
    			   新主题的复制因子,如果已指定副本分配,则为 -1
*/
  • ListTopicsResult
/**
     * 打印topic的信息列表
     * @throws Exception
     */
private static void showTopicsList() throws Exception {
    AdminClient adminClient = getAdminClient();
    // listInternal:是否为内部topic,默认为false
    ListTopicsOptions listTopicsOptions = new ListTopicsOptions();
    listTopicsOptions.listInternal(true);
    // ListTopicsResult listTopicsResult = adminClient.listTopics(listTopicsOptions);
    // 无参的listTopics查看的是listInternal = false的topic
    ListTopicsResult listTopicsResult = adminClient.listTopics();
    // 获取listTopic的name及listInternal信息
    Collection<TopicListing> topicListings = listTopicsResult.listings().get();
    // 打印该信息列表
    topicListings.stream().forEach((topicList -> {
        System.out.println(topicList);
    }));

    // 获取topic的名字列表
    //        Set<String> topicNames = listTopicsResult.names().get();
    //        topicNames.stream().forEach(System.out::println);
}
  • deleteTopics
/**
 * 删除topic
 * @throws Exception
 */
public static void delTopic() throws Exception {
    AdminClient adminClient = getAdminClient();
    // 该结果也是返回一个Future
    DeleteTopicsResult delRes = adminClient.deleteTopics(Arrays.asList(KafkaConfig.TOPIC_NAME));
    delRes.all().get();
}
  • DescribeTopicsResult
/**
 * 描述topic
 * @throws Exception
 */
public static void desTopic() throws Exception {
    AdminClient adminClient = getAdminClient();
    // 调用describeTopics方法,将我们要查看的topic名称列表放入即可
    DescribeTopicsResult desRes = adminClient.describeTopics(Arrays.asList(KafkaConfig.TOPIC_NAME));
    // 获取回的返回值为 topic名-topic描述 的键值对
    Map<String, TopicDescription> descriptionMap = desRes.all().get();
//  TopicDescription topicDescription = descriptionMap.get(KafkaConfig.TOPIC_NAME);
    Set<Map.Entry<String, TopicDescription>> entries = descriptionMap.entrySet();
    entries.stream().forEach(entry -> {
        System.out.println("topic名:" + entry.getKey() + ",topic描述:" + entry.getValue());
    });
}

​ 在返回的TopicDescription中,有四个参数:

name  String : topic名称
internal boolean : 是否为内部topic
partitions List<TopicPartitionInfo> : 一个分区列表,其中索引表示分区id,元素包含该分区的leader和副本信息。
authorizedOperations Set<AclOperation> : 此topic的授权操作,如果未知,则为null
  • DescribConfigsResult
/**
     * 描述配置
     * @throws Exception
     */
public static void descConfig() throws Exception {
    AdminClient adminClient = getAdminClient();
    // 表示具有配置的资源的类 (资源类的类型, 资源名称)
    ConfigResource configResource = new ConfigResource(ConfigResource.Type.TOPIC, KafkaConfig.TOPIC_NAME);
    DescribeConfigsResult describeConfigs = adminClient.describeConfigs(Arrays.asList(configResource));
    Map<ConfigResource, Config> configMap = describeConfigs.all().get();
    configMap.entrySet().stream().forEach((entry) -> {
        System.out.println(entry.getKey() + ":" + entry.getValue());
    });
}
  • alterConfigs
/**
     * 修改配置
     * @throws Exception
     */
public static void altConfig() throws Exception {
    AdminClient adminClient = getAdminClient();
    // 方式一:比较老的方式,通过传Map修改,键:ConfigResource,值:Config
    ConfigResource configResource = new ConfigResource(ConfigResource.Type.TOPIC, KafkaConfig.TOPIC_NAME);
    //        // ConfigEntry中即为要修改的配置名及值
    //        Config config = new Config(Arrays.asList(new ConfigEntry("preallocate", "true")));
    //        Map<ConfigResource, Config> mapForAlt = new HashMap<>();
    //        mapForAlt.put(configResource, config);
    //        // 将该map放入即可
    //        AlterConfigsResult alterConfigsResult = adminClient.alterConfigs(mapForAlt);
    //        alterConfigsResult.all().get();
    // 方式二:用kafka推荐的方式
    Map<ConfigResource, Collection<AlterConfigOp>> mapForAlt = new HashMap<>();
    // 其实都差不多,只是需要再添加一个操作的类型,要修改就选SET即可
    AlterConfigOp alterConfigOp = new AlterConfigOp(new ConfigEntry("preallocate", "false"), AlterConfigOp.OpType.SET);
    mapForAlt.put(configResource, Arrays.asList(alterConfigOp));

    AlterConfigsResult alterConfigsResult = adminClient.incrementalAlterConfigs(mapForAlt);
    alterConfigsResult.all().get();
}
1/kafka是一个分布式的消息缓存系统 2/kafka集群中的服务器都叫做broker 3/kafka有两类客户端,一类叫producer(消息生产者),一类叫做consumer(消息消费者),客户端和broker服务器之间采用tcp协议连接 4/kafka中不同业务系统的消息可以通过topic进行区分,而且每一个消息topic都会被分区,以分担消息读写的负载 5/每一个分区都可以有多个副本,以防止数据的丢失 6/某一个分区中的数据如果需要更新,都必须通过该分区所有副本中的leader来更新 7/消费者可以分组,比如有两个消费者组A和B,共同消费一个topic:order_info,A和B所消费的消息不会重复 比如 order_info 中有100个消息,每个消息有一个id,编号从0-99,那么,如果A组消费0-49号,B组就消费50-99号 8/消费者在具体消费某个topic中的消息时,可以指定起始偏移量 每个partition只能同一个group中的同一个consumer消费,但多个Consumer Group可同时消费同一个partition。 n个topic可以被n个Consumer Group消费,每个Consumer Group有多个Consumer消费同一个topic Topic在逻辑上可以被认为是一个queue,每条消费都必须指定它的Topic,可以简单理解为必须指明把这条消息放进哪个queue里。为了使得Kafka的吞吐率可以线性提高,物理上把Topic分成一个或多个Partition,每个Partition在物理上对应一个文件夹,该文件夹下存储这个Partition的所有消息和索引文件。若创建topic1和topic2两个topic,且分别有13个和19个分区 Kafka的设计理念之一就是同时提供离线处理和实时处理。根据这一特性,可以使用Storm这种实时流处理系统对消息进行实时在线处理,同时使用Hadoop这种批处理系统进行离线处理,还可以同时将数据实时备份到另一个数据中心,只需要保证这三个操作所使用的Consumer属于不同的Consumer Group即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值