KafkaJavaApi操作案例:Kafka数据分区

案例一: 当没有指定分区号和key时使用轮训(轮训分区)策略存储数据

  • Producer生产者代码:
public class Producer {
    //程序的入口
    public static void main(String[] args){
        //1、配置kafka集群
        Properties props = new Properties();
        //kafka服务器地址
        props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
        //消息确认机制
        props.put("acks", "all");
        //重试机制
        props.put("retries", 0);
        //批量发送的大小
        props.put("batch.size", 16384);
        //消息延迟
        props.put("linger.ms", 1);
        //批量的缓冲区大小
        props.put("buffer.memory", 33554432);
        //kafka数据中key  value的序列化
       props.put("key.serializer","org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer","org.apache.kafka.common.serialization.StringSerializer");
        //props.put("partitioner.class", "ProducerPartition");

        //2、获取producer实例
        KafkaProducer<String, String> kafkaProducer = new KafkaProducer<String, String>(props);

        //3、通过实例发送数据到kafka集群
        for (int i = 0; i <9; i++) {
            //1、当没有指定分区号和key时使用轮训(轮训分区)策略存储数据
            ProducerRecord producerRecord = new ProducerRecord("student","生产的数据:------>"+"Kafka"+i);
            kafkaProducer.send(producerRecord);

        }

        kafkaProducer.close();

    }
}

  • Consumer消费者代码:
public class Consumer {
    public static void main(String[] args) {

        //1、添加配置
        Properties props = new Properties();
        //指定kafka服务器
        props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
        //消费组
        props.put("group.id", "test");
        //以下两行代码 ---消费者自动提交offset值
        props.put("enable.auto.commit", "true");
        //自动提交的周期
        props.put("auto.commit.interval.ms",  "1000");
        //设置key value的序列化
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

        KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<>(props);
        kafkaConsumer.subscribe(Arrays.asList("student"));
        while (true){
            ConsumerRecords<String, String> poll = kafkaConsumer.poll(1000);
            for (ConsumerRecord<String, String> consumerRecord : poll) {
                String value = consumerRecord.value();
                System.out.println("消费的数据:"+value);
            }

        }

    }
}

  • 消费者拉取的数据:
消费的数据:生产的数据:------>Kafka1
消费的数据:生产的数据:------>Kafka4
消费的数据:生产的数据:------>Kafka7
消费的数据:生产的数据:------>Kafka2
消费的数据:生产的数据:------>Kafka5
消费的数据:生产的数据:------>Kafka8
消费的数据:生产的数据:------>Kafka0
消费的数据:生产的数据:------>Kafka3
消费的数据:生产的数据:------>Kafka6

案例二: 当制定了key时,分区策略为对key求hash, hash后的值角色存在哪个分区。

  • Producer:
public class Producer {

    //程序的入口
    public static void main(String[] args){

        //1、配置kafka集群
        Properties props = new Properties();

        //kafka服务器地址
        props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
        //消息确认机制
        props.put("acks", "all");
        //重试机制
        props.put("retries", 0);
        //批量发送的大小
        props.put("batch.size", 16384);
        //消息延迟
        props.put("linger.ms", 1);
        //批量的缓冲区大小
        props.put("buffer.memory", 33554432);
        //kafka数据中key  value的序列化
        props.put("key.serializer","org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer","org.apache.kafka.common.serialization.StringSerializer");
        //props.put("partitioner.class", "ProducerPartition");

        //2、获取producer实例
        KafkaProducer<String, String> kafkaProducer = new KafkaProducer<String, String>(props);

        //3、通过实例发送数据到kafka集群
        for (int i = 0; i <9; i++) {




            //2、当制定了key时,分区策略为对key求hash,  hash后的值角色存在哪个分区。"
            ProducerRecord producerRecord = new ProducerRecord("student","test"+i,"Producer生产的数据:------>"+"Kafka"+i);
            kafkaProducer.send(producerRecord);
        }
        kafkaProducer.close();

    }
}
  • Consumer:
public class Consumer {
    public static void main(String[] args) {

        //1、添加配置
        Properties props = new Properties();
        //指定kafka服务器
        props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
        //消费组
        props.put("group.id", "test");
        //以下两行代码 ---消费者自动提交offset值
        props.put("enable.auto.commit", "true");
        //自动提交的周期
        props.put("auto.commit.interval.ms",  "1000");
        //设置key value的序列化
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

        KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<>(props);
        kafkaConsumer.subscribe(Arrays.asList("student"));
        while (true){
            ConsumerRecords<String, String> poll = kafkaConsumer.poll(1000);
            for (ConsumerRecord<String, String> consumerRecord : poll) {
                String value = consumerRecord.value();
                System.out.println("Consumer消费的数据---->"+value+"^^^^所属分区------>"+consumerRecord.partition());
            }

        }

    }
}

在这里插入图片描述

  • key不可变:

在这里插入图片描述

  • Key可变:
    在这里插入图片描述

案例三:当指定分区编号时,所有的数据全部打入该分区

  • Producer:
public class Producer {

    //程序的入口
    public static void main(String[] args){

        //1、配置kafka集群
        Properties props = new Properties();

        //kafka服务器地址
        props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
        //消息确认机制
        props.put("acks", "all");
        //重试机制
        props.put("retries", 0);
        //批量发送的大小
        props.put("batch.size", 16384);
        //消息延迟
        props.put("linger.ms", 1);
        //批量的缓冲区大小
        props.put("buffer.memory", 33554432);
        //kafka数据中key  value的序列化
        props.put("key.serializer","org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer","org.apache.kafka.common.serialization.StringSerializer");
        //props.put("partitioner.class", "ProducerPartition");

        //2、获取producer实例
        KafkaProducer<String, String> kafkaProducer = new KafkaProducer<String, String>(props);

        //3、通过实例发送数据到kafka集群
        for (int i = 0; i <9; i++) {
            //3、当指定分区编号时,所有的数据全部打入该分区
            ProducerRecord producerRecord = new ProducerRecord("student",1,"test","Producer生产的数据:------>"+"Kafka"+i);
           kafkaProducer.send(producerRecord);

        }

        kafkaProducer.close();

    }
}
  • Consumer:
public class Consumer {
    public static void main(String[] args) {

        //1、添加配置
        Properties props = new Properties();
        //指定kafka服务器
        props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
        //消费组
        props.put("group.id", "test");
        //以下两行代码 ---消费者自动提交offset值
        props.put("enable.auto.commit", "true");
        //自动提交的周期
        props.put("auto.commit.interval.ms",  "1000");
        //设置key value的序列化
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

        KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<>(props);
        kafkaConsumer.subscribe(Arrays.asList("student"));
        while (true){
            ConsumerRecords<String, String> poll = kafkaConsumer.poll(1000);
            for (ConsumerRecord<String, String> consumerRecord : poll) {
                String value = consumerRecord.value();
                System.out.println("Consumer消费的数据---->"+value+"^^^^所属分区------>"+consumerRecord.partition());
            }

        }

    }
}
  • 结果:
    在这里插入图片描述

案例四:自定义分区

  • Producer:
//程序的入口
    public static void main(String[] args){

        //1、配置kafka集群
        Properties props = new Properties();

        //kafka服务器地址
        props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
        //消息确认机制
        props.put("acks", "all");
        //重试机制
        props.put("retries", 0);
        //批量发送的大小
        props.put("batch.size", 16384);
        //消息延迟
        props.put("linger.ms", 1);
        //批量的缓冲区大小
        props.put("buffer.memory", 33554432);
        //kafka数据中key  value的序列化
        props.put("key.serializer","org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer","org.apache.kafka.common.serialization.StringSerializer");
        //设置自定义分区                 包名+全类名
        props.put("partitioner.class", "MyPartition");

        //2、获取producer实例
        KafkaProducer<String, String> kafkaProducer = new KafkaProducer<String, String>(props);

        //3、通过实例发送数据到kafka集群
        for (int i = 0; i <9; i++) {

            //4、自定义分区
        ProducerRecord producerRecord = new ProducerRecord("student","test"+i,"Producer生产的数据:------>"+"Kafka"+i);


            kafkaProducer.send(producerRecord);

        }

        kafkaProducer.close();

    }
}
  • Consumer:
public class Consumer {
    public static void main(String[] args) {

        //1、添加配置
        Properties props = new Properties();
        //指定kafka服务器
        props.put("bootstrap.servers", "node01:9092,node02:9092,node03:9092");
        //消费组
        props.put("group.id", "test");
        //以下两行代码 ---消费者自动提交offset值
        props.put("enable.auto.commit", "true");
        //自动提交的周期
        props.put("auto.commit.interval.ms",  "1000");
        //设置key value的序列化
        props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

        KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<>(props);
        kafkaConsumer.subscribe(Arrays.asList("student"));
        while (true){
            ConsumerRecords<String, String> poll = kafkaConsumer.poll(1000);
            for (ConsumerRecord<String, String> consumerRecord : poll) {
                String value = consumerRecord.value();
                System.out.println("Consumer消费的数据---->"+value+"^^^^所属分区------>"+consumerRecord.partition());
            }

        }

    }
}
  • MyPartition:
public class MyPartition implements Partitioner {
    @Override
    public int partition(String s, Object o, byte[] bytes, Object o1, byte[] bytes1, Cluster cluster) {
        /**
         * 这里可以写逻辑性的业务需求
         */


        //返回几  就分在那个区中
        return 0;
    }

    @Override
    public void close() {

    }

    @Override
    public void configure(Map<String, ?> map) {

    }
}
  • 结果:

在这里插入图片描述

发布了104 篇原创文章 · 获赞 154 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/weixin_45737446/article/details/105230759