消息在经过拦截器、序列化后,就需要确定它发往哪个分区,如果在ProducerRecord中指定了partition字段,那么就不再需要partitioner分区器进行分区了,如果没有指定,那么会根据key来将数据进行分区,如果partitioner和key都没有指定,那么就会采用默认的方式进行数据分区。

  有没有指定partition可以从源码中看出:

 public ProducerRecord(String topic, Integer partition, K key, V value) {}

 如果指定的partition,那就指定了数据发往哪个分区上,如果没有就会根据key来进行数据分区,如果2个都没有,那么会采用默认的分区策略来进行数据分区

1.根据key进行分区

public class CustomPartitioner {

    private static final Logger LOG = LoggerFactory.getLogger(CustomPartitioner.class);

    public static void main(String[] args) {
//1.加载配置信息
Properties prop = loadProperties(); //2.创建生产者
KafkaProducer<Integer,String> producer = new KafkaProducer<>(prop); String sendContent = "hello_kafka";
IntStream.range(0, 10).forEach(i ->{
try {
ProducerRecord<Integer,String> record = new ProducerRecord<>("test1",i,sendContent+"_"+i);  //topic key value
Future<RecordMetadata> future = producer.send(record);
RecordMetadata recordMetadata = future.get();
LOG.info("发送的数据是 :{},offset:是{},partition是:{}",sendContent,recordMetadata.offset(),recordMetadata.partition());
} catch (Exception e) {
e.printStackTrace();
} }); }
//配置文件的设置
public static Properties loadProperties() {
Properties prop = new Properties();
prop.put("bootstrap.servers", "192.168.100.144:9092,192.168.100.145:9092,192.168.100.146:9092");
prop.put("key.serializer", "org.apache.kafka.common.serialization.IntegerSerializer");
prop.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
prop.put("acks", "all"); //发送到所有的ISR队列中
return prop;
}
}

 2.自定义分区

  同样在使用自定义分区的时候,需要写实现类和在producer中配置引用

  我们在这个示例中,根据key来分区,key在序列化的时候用的是IntegerSerializer,在ProducerRecord中我们没有指定partition

  自定义分区器

public class CustomPartition implements Partitioner{

    @Override
public void configure(Map<String, ?> configs) {
// TODO Auto-generated method stub } @SuppressWarnings({ "null", "unused" })
@Override
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) { int partitionNum = cluster.partitionsForTopic(topic).size();
int partition = (Integer)key%partitionNum;
return key == null? 0:partition;
} @Override
public void close() {
// TODO Auto-generated method stub }
}

  生产者

public class ProducerDemo {

    private static final Logger LOG = LoggerFactory.getLogger(ProducerDemo.class);

    public static void main(String[] args) throws InterruptedException, ExecutionException {
//1.加载配置信息
Properties prop = loadProperties(); //2.创建生产者
KafkaProducer<Integer,String> producer = new KafkaProducer<>(prop); //3.发送内容
String sendContent = "hello_kafka";
IntStream.range(0, 10).forEach(i ->{
try {
ProducerRecord<Integer,String> record = new ProducerRecord<>("test1",i,sendContent+"_"+i);
Future<RecordMetadata> future = producer.send(record);
RecordMetadata recordMetadata = future.get();
LOG.info("发送的数据是 :{},offset:是{},partition是:{}",sendContent,recordMetadata.offset(),recordMetadata.partition());
} catch (Exception e) {
e.printStackTrace();
} });
producer.close(); //回调拦截器中的close方法 } //配置文件的设置
public static Properties loadProperties() {
Properties prop = new Properties();
prop.put("bootstrap.servers", "192.168.100.144:9092,192.168.100.145:9092,192.168.100.146:9092");
prop.put("key.serializer", "org.apache.kafka.common.serialization.IntegerSerializer");
prop.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
prop.put("partitioner.class", "com.zpb.partitioner.CustomPartition");
prop.put("acks", "all");
return prop;
}
}

 

kafka producer partitions分区器(七)的更多相关文章

  1. 玩转Kafka的生产者——分区器与多线程

    上篇文章学习kafka的基本安装和基础概念,本文主要是学习kafka的常用API.其中包括生产者和消费者, 多线程生产者,多线程消费者,自定义分区等,当然还包括一些避坑指南. 首发于个人网站:链接地址 ...

  2. kafka producer interceptor拦截器(五)

    producer在发送数据时,会经过拦截器和序列化,最后到达相应的分区.在经过拦截器时,我们可以对发送的数据做进步的处理. 要正确的使用拦截器需要以下步骤: 1.实现拦截器ProducerInterc ...

  3. kafka 自定义分区器

    package cn.xiaojf.kafka.producer; import org.apache.kafka.clients.producer.Partitioner; import org.a ...

  4. Kafka producer拦截器(interceptor)

    Kafka producer拦截器(interceptor) 拦截器原理 Producer拦截器(interceptor)是在Kafka 0.10版本被引入的,主要用于实现clients端的定制化控制 ...

  5. Kafka Producer源码解析一:整体架构

    一.Producer整体架构 Kafka Producer端的架构整体也是一个生产者-消费者模式 Producer线程调用send时,只是将数据序列化后放入对应TopicPartition的Deque ...

  6. 详解Kafka Producer

    上一篇文章我们主要介绍了什么是 Kafka,Kafka 的基本概念是什么,Kafka 单机和集群版的搭建,以及对基本的配置文件进行了大致的介绍,还对 Kafka 的几个主要角色进行了描述,我们知道,不 ...

  7. kafka partition(分区)与 group

    kafka partition(分区)与 group   一. 1.原理图 2.原理描述 一个topic 可以配置几个partition,produce发送的消息分发到不同的partition中,co ...

  8. kafka partition(分区)与 group(转)

    原文  https://www.cnblogs.com/liuwei6/p/6900686.html 一. 1.原理图 2.原理描述 一个topic 可以配置几个partition,produce发送 ...

  9. Kafka producer介绍

    Kafka 0.9版本正式使用Java版本的producer替换了原Scala版本的producer.本文着重讨论新版本producer的设计原理以及基本的使用方法. 新版本Producer 首先明确 ...

随机推荐

  1. 028_切割 Nginx 日志文件(防止单个文件过大,后期处理很困难)

    mkdir /data/scriptsvim /data/scripts/nginx_log.sh #!/bin/bashlogs_path="/usr/local/nginx/logs/& ...

  2. [CQOI2016]手机号码 数位DP

    [CQOI2016]手机号码 用来数位DP入门,数位DP把当前是否需要限制取数范围(是否正在贴着临界值跑,即下面的limited)和一切需要满足的条件全部塞进记忆化搜索参数里面就好了,具体情况转移便好 ...

  3. LibreOJ #102. 最小费用流

    二次联通门 : LibreOJ #102. 最小费用流 /* LibreOJ #102. 最小费用流 Spfa跑花费 记录路径 倒推回去 */ #include <cstring> #in ...

  4. mfc编程之发送wm_paint消息时绘图界面只出现一瞬间

    实现的功能是在打开一个文件然后把文件的图形信息绘制在picture控件上. 问题描述:我把绘制的操作放在了窗口中onpaint()函数里,打开文件后发送一个wm_paint的消息,发现picture控 ...

  5. c语言 宏

    #代表命令要被预处理器处理#define 定义的宏可以出现在程序的任意位置#define 定义之后的代码都可以使用这个宏 宏是字面量,不占用内存 单步编译预处理器,只进行文本替换,不进行语法检查:gc ...

  6. DockerFile体系结构(保留字指令)

    1.FROM --基础镜像,当前新镜像是基于那个镜像的 2.MAINTAINER --镜像维护者的姓名和邮箱地址 3.RUN --容器构建时需要运行的指令 4.EXPOSE --当前容器对外暴露出的端 ...

  7. docker 容器内部访问宿主机

    在宿主机执行: ifconfig 然后查看 docker0 的那个网卡的 ip 地址,比如我的是 172.18.0.1

  8. ASP.NET的MVC设计模式

    当开发者听到“设计模式”这个词时,他们通常联想到两个场景.一组开发者正在讨论许多创造性意见,正在开会,但是却没有进行编码.另外一组人能制定出正确的计划,保证系统能够开发成功,代码可以重用. 而现实一般 ...

  9. 重读APUE(12)-SIGCHLD与僵尸进程

    SIGCHLD信号是当子进程终止时向父进程发送的信号:它的语义如下: 如果进程明确的将该信号设置为SIG_IGN,则调用进程不会产生僵尸进程:这种情况下,wait是等不到给子进程收尸的,所以wait阻 ...

  10. iOS-VideoToolbox硬编码H264

    前言 VideoToolBox是iOS8之后,苹果开发的用于硬解码编码H264/H265(iOS11以后支持)的API. 对于H264还不了解的童鞋一定要先看下这边的H264的简介. 编码流程 我们实 ...