kafka(三)kafka核心类

本文详细介绍了ApacheKafka3.0.0版本中Producer和Consumer的关键特性,包括Producer的发送流程、主要参数如acks、buffer.memory和compression.type,以及ProducerRecord的分区策略和KafkaConsumer的订阅和消费。还探讨了同步和异步发送消息的方法,以及回调函数的应用。
摘要由CSDN通过智能技术生成

目录

一、kafkaProducer

1、介绍

2、发送流程

3、主要参数

3.1、acks:

3.2、 buffer.memory

3.3、compression.type

3.4、batch.size

二、ProducerRecord

1、介绍

2、发送消息分区策略

 (1)指定了分区:

(2)轮询

(3)key哈希分区策略

(4)自定义分区策略(即自定义Partitioner)

三、 KafkaConsumer

1、使用

2、消费者分配策略

2.1、RangeAssignor 范围分配

2.2、RoundRobinAssignor  轮询分配

2.3、StickyAssignor 黏性分配

2.4、CooperativeSticky(合作者粘性)

四、ConsumerRecord




基于kafka新版本

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

一、kafkaProducer

1、介绍

设计上比consumer要简单一些,因为不涉及组管理,即每个producer都是独立工作的。

(1)目前producer的主要功能是向某个topic的某个分区发送一条消息,这就涉及分区选择策略,在ProducerRecord中介绍。

(2)因为有ISR,因此在发送消息时,producer有多种选择来实现消息发送,如不等待任何副本的影响便返回、只等待leader副本响应返回等等。

2、发送流程

produce的发送主要流程概述如下:

  1. 拦截器对发送的消息拦截处理;

  2. 获取元数据信息;

  3. 序列化处理;

  4. 分区处理;

  5. 批次添加处理;

  6. 发送消息。

 

3、主要参数
3.1、acks:

有三个参数:0、1、all,数据可靠性的重要参数,可以保证消息不丢失。

Properties properties = new Properties();
properties.put(ProducerConfig.ACKS_CONFIG,"1");
3.2、 buffer.memory

指定了producer端用于缓冲消息的缓冲区大小,单位是字节。

3.3、compression.type

producer是否压缩消息。

3.4、batch.size

二、ProducerRecord

1、介绍

发送给Kafka Broker的key/value 值对,producer将待发送的消息封装进ProducerRecord实例类。

不设置分区时,默认只有一个分区;如果需要设置分区数量,需要在创建topic时指定。

2、发送消息分区策略
 (1)指定了分区:

partition不为空。

当发送时指定了partition就使用该partition。即kafka生产者发送的消息ProducerRecord(String topic, Integer partition, K key, V value)指定了发送到哪个具体的分区。

(2)轮询

partition=null && key=null。

既没有partition值又没有key值的情况下,第一次调用是随机生成一个整数(后面调用在这个整数上自增),将这个值与topic可用的parition总数取余得到partition值,也就是常说的round-robin算法。

如果kafka生产者发送的消息ProducerRecord(String topic, Integer partition, K key, V value)没有指定发送到哪个具体的分区,即partition=null(并且key也为空时,如果此时key不为空的话就会采用另一种分区策略key哈希分区策略),并且使用了默认的分区器,那么消息将被随机的发送到主题的各个可用分区上,分区器使用轮询的算法将消息均衡的分布到各个分区。

(3)key哈希分区策略

partition=null && key != null。

没有指明partition但有key,将key的hash值与topic的partition数据进行取余得到partition值。

根据消息的key进行哈希计算,并将消息发送到对应的分区。保证相同key的消息始终被发送到同一个分区,确保消息的顺序性。

(4)自定义分区策略(即自定义Partitioner)

用户可以根据自己的需求实现自定义的分区策略,通过实现org.apache.kafka.clients.producer.Partitioner接口来自定义分区选择逻辑。

三、 KafkaConsumer

1、使用
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import org.apache.kafka.common.serialization.StringDeserializer;
 
import java.time.Duration;
import java.util.ArrayList;
import java.util.Properties;
 
public class CustomConsumer {
    public static void main(String[] args) {
        // 1. 创建消费者配置对象
        Properties properties = new Properties();
        // 2. 给消费者配置对象添加参数(不同于生产者,消费者有 4个必要的配置参数)
        //  broker的ip地址
        properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "hadoop102:9092");
        // 配置  反序列化
        properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        //配置消费者组(组名必须)
        properties.put(ConsumerConfig.GROUP_ID_CONFIG, "group1");
        // 3. 创建消费者对象
        KafkaConsumer<String, String> consumer = new KafkaConsumer<String, String>(properties);
        // 注册消费主题
        ArrayList<String> topics = new ArrayList<>();
        topics.add("first");
        consumer.subscribe(topics);
        // 4.调用方法消费数据
        // 如果kafka集群没有新数据会造成空转
        // 填写参数为时间,如果没有拉取数据,线程睡眠一会
        while (true) {
            // 设置1s中消费的一批数据
            // Duration.ofSeconds(1)不会导致空转,拉取不到的时候睡眠1s
            ConsumerRecords<String, String> consumerRecords = consumer.poll(Duration.ofSeconds(1));
            // 打印消费数据
            for (ConsumerRecord<String, String> consumerRecord : consumerRecords) {
                System.out.println(consumerRecord.topic() + "-" + consumerRecord.partition() + "-" + consumerRecord.offset());
            }
        }
        //5.关闭资源
//        consumer.close();不使用的原因是,已关闭进程,就不会再消费数据了,进程停止就以为着JVM为断电了,不再工作
    }
}
2、消费者分配策略

消费者的基本规则:1)一个分区的数据只能由这个消费者组中的某一个消费者消费;

2)一个消费者可以消费多个分区的数据。

决定多个分区如何分配给多个消费者,即我们所说的消费者分配策略,它由 partition.assignment.strategy 属性的值来决定

这里要与 Kafka 生产者的分区规则区分开,

  • 生产者的分区规则指的是:
    生产者在生产数据过程中,一个Topic有多个分区,数据写入哪个分区。

  • 而 Kafka 消费者分配策略指的是:多个Topic 多个分区,一个消费者组有多个消费者(即多个相同的groupId),Kafka 是怎么样自动分配保证消费的负载均衡的。

    Kafka 消费者的分配策略有三种:范围分配、轮询分配、黏性分配。Kafka 默认的分配策略是范围分配。在Kafka 2.0版本之前,一般用轮询分配,但是Kafka 2.0 版本之后,建议使用黏性分配。因为黏性分配不仅考虑了分配的均衡度之外,在重分配的情况代价更低,效率更高。

2.1、RangeAssignor 范围分配

默认的分配策略。

针对每个消费者的每个Topic 进行范围分配。即每个消费者消费一定范围的分区,尽量地实现将分区均分给不同的消费者,如果不能均分,优先将分区分配给消费者编号比较小的消费者。并且每个消费者消费的范围是连续的;不能均分的情况下:消费者由Kafka 自动编号。Kafka 会优行把多出来的分区分给消费者组中编号比较小的消费者。

如只有1个Topic,共6个分区。有4个消费者共同订阅了这个Topic。如果平均每人消费1个分区,则最后多出来2个分区 Kafka 会默认分给编号较小的消费者。并且每个消费者消费的范围是连续的:
consumer1: t0-0 t0-1
consumer2: t0-2 t1-0
consumer3: t1-1
consumer4: t1-2

优点:如果Topic 的个数比较少,分配会相对均衡(只有一个Topic的情况下,消费者消费分区的个数最多只差1个);

缺点:因为范围分配是针对每个Topic对消费者进行范围分配。当存在多个Topic,并且分区个数都不能均分的情况,会导致负载不均衡的问题(即编号比较小的消费者负担会更重)。

2.2、RoundRobinAssignor  轮询分配

Kafka 2.0 版本之前使用。按字面意思,Kafka 会根据 Topic 订阅来轮询分配,将所有的分区 按 Topic名称和分区编号进行排序,轮询分配给每个消费者(如果第一轮轮询结束,会接着上一轮轮询分配的结果继续轮询分配)。
优点:如果有多个消费者,消费的Topic 都是一样的,实现将所有的Topic 的所有分区轮询分配给所有消费者,尽量地实现负载均衡。
缺点:
(1)遇到极端情况下,消费者订阅的 Topic 是不一致的,不同的消费者订阅了不同 Topic ,Kafka 只基于订阅的消费者进行轮询分配,导致整体消费负载不均衡。

假设有3个消费者消费3个Topic。
Topic1 有1 个分区;
Topic2 有2个分区;
Topic3 有3个分区;

Topic1 数据比较多,所以消费者c1、c2、c3都订阅了 Topic1;
Topic2 数据较少些,所以消费者c2、c3 订阅了 Topic2;
Topic3 数据最少,所以只有消费者 c3 订阅了 Topic3;

此时,根据轮询规则,则
Topic : 对应的消费者
T1 - 0 :c1
T2 - 0 :c2
T2 - 1 :c3
T3 - 0 :c3
T3 - 1 :c3
T3 - 2 :c3

(2)负载不均衡,如果遇到某个消费者故障,范围分配和轮询分配策略都会将所有的分区重新分配【性能较差】

应用:所有消费者都订阅共同的 Topic,能实现让所有Topic 的分区轮询分配给所有的消费者

2.3、StickyAssignor 黏性分配

这是 Kafka 2.0 版本之后建议使用。
优点:黏性分配除了考虑分配的均衡度以外,重分配的效率更高。
规则:类似于轮询分配,尽量地将分区均衡地分配给消费者;

这种策略下,消费者会尽量保持与之前分配的分区相同。如果有新的消费者加入或有消费者退出,分区的重新分配会尽量减少。这个策略对于需要保持状态的应用程序比较有用。

特点:
(1)相对保证分配的均衡【比轮询还要均衡】;
(2)如果某个消费者故障,尽量地避免网络传输,不会重新分配
· 尽量保证原来的消费的分区不变,将多出来分区均衡给剩余的消费者;

假设原来有3个消费者,消费6个分区,平均每个消费者消费2个分区;如果有一个消费者故障了,这个消费者负责的分区交给剩下的消费者来做:消费重平衡

2.4、CooperativeSticky(合作者粘性)

后面版本加的分配策略:

这是Kafka 2.4.0版本引入的新策略,通过考虑消费者的健康状况、处理速度、网络延迟等因素,动态地进行分区分配,以实现更好的负载均衡和消费者协作。

四、ConsumerRecord

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w_t_y_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值