Kafka之生产者分区策略

在这里插入图片描述
1)默认的分区器:Defaultpartitioner,ctrl+n 全局搜索DefaultPartitioner,可以在源码中查看分区策略

#如果记录中指定了分区,请使用它
1) If a partition is specified in the record, use it
#如果未指定分区但存在key,根据key的哈希值选择分区
2) If no partition is specified but a key is present choose a partition based on a hash of the key
#如果为指定分区且不存在key的情况下,选择在批处理已满的时更改为粘性分区
3) If no partition or key is present choose the sticky partition that changes when the batch is full.

ctrl+n,全局搜索ProducerRecord可以查看到对应策略的源码,前四个对应策略一、第五个对应策略二、第六个对应策略三。

在这里插入图片描述
(1)、指明partition的情况下,直接将知名的值作为partition的值。例:partition=0,将所有数据写入分区0.

(2)、没有指明partition值但有key的情况下,将key的hash值与topic的partition数进行取余得到partition值。例:key1的hash值为5,key2的hash值为6,topic的分区数(partition)数为2。5%2=1,那么key1对应的value写入1号分区;6%2=0,那么key2对应的value写入0号分区.

(3)、既没有partition值又没有key值得情况下,kafka采用Sticky Partition(黏性分区),会随机选择一个分区,并尽可能一致使用该分区,待该分区得batch已满或者已完成,Kafka在随机一个分区进行使用(和上一次得分区不同,如果相同,则会继续随机,直到找到不同得分区为止)

例:第一次随机选择0号分区,等0好分区当前批满了(默认16K)或者linger.ms设置得时间到,kafka在随机选择一个分区进行使用。

2)自定义分区器

(1)定义类实现Partitioner接口

(2)重写partition()方法

import org.apache.kafka.clients.producer.Partitioner;
import org.apache.kafka.common.Cluster;

import java.util.Map;

/**
 * 文件名:MyDefinePartitioner
 * 创建者:CYS
 * 创建时间: 2022/10/20 15:47
 * 描述: 自定义分区器:实现发送过来的数据中如果包含huarui,就发往2号分区,不包含huarui的就发往1号分区
 *          1) 继承Partitioner
 *          2) 实现接口的三个方法:partition、close、configure
 */
public class MyDefinePartitioner implements Partitioner {

    @Override
    /**
     *
     * @Param
     * @param topic        主题名
     * @param key          消息的Key
     * @param keyBytes     消息Key序列化后的字节数
     * @param value        消息的value
     * @param valueBytes   消息的value序列化后的字节数
     * @param cluster      集群元数据可以查看的分区信息
     * @return int         返回分区号
     **/
    public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
        //获取消息
        String msgValue = value.toString();

        //创建partition
        int partition;

        //判断消息是否包含huarui
        if(msgValue.contains("huarui")){
            partition=2;
        }else{
            partition=1;
        }

        //返回分区号
        return partition;
    }

    //关闭资源
    @Override
    public void close() {

    }

    //配置方法
    @Override
    public void configure(Map<String, ?> configs) {

    }
}

import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.serialization.StringDeserializer;

import java.util.Properties;

/**
 * 文件名:CustomProducerCallbackPartitions
 * 创建者:CYS
 * 创建时间: 2022/10/20 16:00
 * 描述:
 */
public class CustomProducerCallbackPartitions {
    public static void main(String[] args) {
        //1、创建配置对象
        Properties properties = new Properties();

        //2、配置kafka参数
        properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "hadoop01:9092,hadoop02:9092,hadoop03:9092");

        //2.1 k、v序列化
        properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringDeserializer.class);

        //2.2 添加自定义分区器
        properties.put(ProducerConfig.PARTITIONER_CLASS_CONFIG, "com.cys.kafka.mydefine.MyDefinePartitioner");

        //2.3 创建生产者
        KafkaProducer<String, String> kafkaProducer = new KafkaProducer<>(properties);

        //2.4 发送数据
        for (int i = 0; i < 5; i++) {
            kafkaProducer.send(new ProducerRecord<>("first", "cys"), new Callback() {
                @Override
                public void onCompletion(RecordMetadata metadata, Exception exception) {
                    if ("null".equals(exception)) {
                        System.out.println("topic:" + metadata.topic() + "-->" + "分区:" + metadata.partition());
                    }else{
                        exception.printStackTrace();
                    }
                }
            });
        }

        //3、关闭资源
        kafkaProducer.close();

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值