package cn.xiaojf.kafka.producer;

import org.apache.kafka.clients.producer.Partitioner;
import org.apache.kafka.common.Cluster;
import org.apache.kafka.common.PartitionInfo;
import org.apache.kafka.common.utils.Utils; import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger; /**
* 自定义分区方式
*/
public class CustomPartitioner implements Partitioner {
private final ConcurrentMap<String, AtomicInteger> topicCounterMap = new ConcurrentHashMap(); public CustomPartitioner() {
} public void configure(Map<String, ?> configs) {
} /**
* 自定义分区规则
* @param topic
* @param key
* @param keyBytes
* @param value
* @param valueBytes
* @param cluster
* @return
*/
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
List partitions = cluster.partitionsForTopic(topic);
int numPartitions = partitions.size();
if(keyBytes == null) {
int nextValue = this.nextValue(topic);
List availablePartitions = cluster.availablePartitionsForTopic(topic);
if(availablePartitions.size() > 0) {
int part = Utils.toPositive(nextValue) % availablePartitions.size();
return ((PartitionInfo)availablePartitions.get(part)).partition();
} else {
return Utils.toPositive(nextValue) % numPartitions;
}
} else {
return Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
}
} private int nextValue(String topic) {
AtomicInteger counter = (AtomicInteger)this.topicCounterMap.get(topic);
if(null == counter) {
counter = new AtomicInteger((new Random()).nextInt());
AtomicInteger currentCounter = (AtomicInteger)this.topicCounterMap.putIfAbsent(topic, counter);
if(currentCounter != null) {
counter = currentCounter;
}
} return counter.getAndIncrement();
} public void close() {
}
}
package cn.xiaojf.kafka.producer;

import org.apache.kafka.clients.producer.*;
import org.apache.kafka.common.Cluster;
import org.apache.kafka.common.PartitionInfo;
import org.apache.kafka.common.serialization.StringSerializer;
import org.apache.kafka.common.utils.Utils; import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicInteger; /**
* 消息生产者
* @author xiaojf 2017/3/22 14:27
*/
public class MsgProducer extends Thread { private final KafkaProducer<String, String> producer;
private final String topic;
private final boolean isAsync; public MsgProducer(String topic, boolean isAsync) {
Properties properties = new Properties();
properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.59.130:9092");//broker 集群地址
properties.put(ProducerConfig.CLIENT_ID_CONFIG, "MsgProducer");//自定义客户端id
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");//key 序列号方式
properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");//value 序列号方式
properties.put(ProducerConfig.PARTITIONER_CLASS_CONFIG,CustomPartitioner.class.getCanonicalName());//自定义分区函数 // properties.load("properties配置文件"); this.producer = new KafkaProducer<String, String>(properties);
this.topic = topic;
this.isAsync = isAsync;
} @Override
public void run() {
int msgNo = 0; while (true) {
String msg = "Msg: " + msgNo;
String key = msgNo + "";
if (isAsync) {//异步
producer.send(new ProducerRecord<String, String>(this.topic,msg));
// producer.send(new ProducerRecord<String, String>(this.topic, key, msg));
} else {//同步
producer.send(new ProducerRecord<String, String>(this.topic, key, msg),
new MsgProducerCallback(System.currentTimeMillis(), key, msg));
}
}
} /**
* 消息发送后的回调函数
*/
class MsgProducerCallback implements Callback { private final long startTime;
private final String key;
private final String msg; public MsgProducerCallback(long startTime, String key, String msg) {
this.startTime = startTime;
this.key = key;
this.msg = msg;
} public void onCompletion(RecordMetadata recordMetadata, Exception e) {
long elapsedTime = System.currentTimeMillis() - startTime;
if (recordMetadata != null) {
System.out.println(msg + " be sended to partition no : " + recordMetadata.partition());
}
}
} public static void main(String args[]) {
new MsgProducer("my-replicated-topic",true).start();//开始发送消息
}
}

kafka 自定义分区器的更多相关文章

  1. kafka自定义序列化器

    <kafka权威指南> Customer.java public class Customer { private int customId; private String custome ...

  2. spark自定义分区器实现

    在spark中,框架默认使用的事hashPartitioner分区器进行对rdd分区,但是实际生产中,往往使用spark自带的分区器会产生数据倾斜等原因,这个时候就需要我们自定义分区,按照我们指定的字 ...

  3. MapReduce之自定义分区器Partitioner

    @ 目录 问题引出 默认Partitioner分区 自定义Partitioner步骤 Partition分区案例实操 分区总结 问题引出 要求将统计结果按照条件输出到不同文件中(分区). 比如:将统计 ...

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

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

  5. kafka producer partitions分区器(七)

    消息在经过拦截器.序列化后,就需要确定它发往哪个分区,如果在ProducerRecord中指定了partition字段,那么就不再需要partitioner分区器进行分区了,如果没有指定,那么会根据k ...

  6. Spark源码分析之分区器的作用

    最近因为手抖,在Spark中给自己挖了一个数据倾斜的坑.为了解决这个问题,顺便研究了下Spark分区器的原理,趁着周末加班总结一下~ 先说说数据倾斜 数据倾斜是指Spark中的RDD在计算的时候,每个 ...

  7. RDD(六)——分区器

    RDD的分区器 Spark目前支持Hash分区和Range分区,用户也可以自定义分区,Hash分区为当前的默认分区,Spark中分区器直接决定了RDD中分区的个数.RDD中每条数据经过Shuffle过 ...

  8. Kafka的接口回调 +自定义分区、拦截器

    一.接口回调+自定义分区 1.接口回调:在使用消费者的send方法时添加Callback回调 producer.send(new ProducerRecord<String, String> ...

  9. 【Kafka】自定义分区策略

    自定义分区策略 思路 Command+Option+shift+N 调出查询页面,找到producer包的Partitioner接口 Partitioner下有一个DefaultPartitioner ...

随机推荐

  1. Spring+SpringMVC+MyBatis+easyUI整合优化篇(五)结合MockMvc进行服务端的单元测试

    日常啰嗦 承接前一篇文章<Spring+SpringMVC+MyBatis+easyUI整合优化篇(四)单元测试实例>,已经讲解了dao层和service层的单元测试,还有控制器这层也不能 ...

  2. Java与面向对象之随感(1)

    大一下学期上完了c++课程,当时自我感觉很良好,认为对面向对象编程已经是身经百战了,但是上了院里HuangYu老师的Java课之后,才发现自己对于面向对象的编程风格的理解只在皮毛,着实惭愧不已. 假设 ...

  3. Broker节点

    在druid集群环境中 broker节点的作用是查询.它知道metadata 通过zookeeper发送到了集群中的哪个节点,从而能够准确的查询到.broker也把各个节点的结果汇聚到一个节点中.On ...

  4. salt-stack部署

    saltstack部署   环境准备 [root@server elasticsearch]# cat /etc/redhat-release CentOS release 6.6 (Final)[r ...

  5. CSS也需要重构

    最初接触到的CSS面向对象,是项目里的CSS超过8千行,缺乏约束和管理,在近期或不远的将来,有迫切的要求需要重构.CSS面向对象和模块化. CSS代码遇到的问题: 重用性差,看着一个CSS的名称,很难 ...

  6. Ajax 与 Comet

    Ajax技术的核心是XMLHttpRequest对象(简称XHR). XMLHttpRequest对象 在浏览器中创建XHR对象要像下面这样,使用XMLHttpRequest构造函数. var xhr ...

  7. Python全栈之路-Day32

    1 类的__slots__ #!/usr/bin/env python # __Author__: "wanyongzhen" # Date: 2017/4/25 # 只能定义__ ...

  8. 超炫的 CSS3 页面切换动画效果

    在线演示      源码下载

  9. webService基础知识--认识WebService

    之前在找工作的时候,有面试官问到WebService,当时没有接触过,正好现在做的项目中有用到WebService,所以就趁着业余时间来学习了. 一.简介 先来看看百度百科对WebService的解释 ...

  10. hadoop集群搭建--CentOS部署Hadoop服务

    在了解了Hadoop的相关知识后,接下来就是Hadoop环境的搭建,搭建Hadoop环境是正式学习大数据的开始,接下来就开始搭建环境!我们用到环境为:VMware 12+CentOS6.4 hadoo ...