业务场景参考
在IOT领域,传感器设备的数据向服务器发送数据,预想一个类型的数据放一个topic里,但是根据实际情况。
kaka的topic数越多,吞吐量性能下降厉害。
所以想象将分区做个自定义,然后消费者组的消费者消费指定分区,达到这一目的。
一 自定义kafka分区
public class SimplePartitioner implements Partitioner {
private final AtomicInteger atomicInteger = new AtomicInteger(0);
@Override
public void configure(Map<String, ?> configs) {
// TODO Auto-generated method stub
}
@Override
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
// 从集群中获取所有分区信息,对key值进行分区
List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
//根据key进行分区 xx_01在01分区,xx_02在02分区
int numPartitions = partitions.size();
// key为null或空时使用轮训分区做负载均衡, 注意可以一定不能为null
if (null == keyBytes || keyBytes.length < 1) {
return atomicInteger.getAndIncrement() % numPartitions;
}
// 借用String的字符串计算方法,返回在哪个分区
String strKey = key.toString();
System.out.println(Integer.parseInt(strKey.split("_")[1]));
return Integer.parseInt(strKey.split("_")[1]);
}
@Override
public void close() {
// TODO Auto-generated method stub
}
}
二 生产者生产数据放到指定分区
public class TestPartitionProducer implements Serializable {
private KafkaProducer kafkaProducer;
public final static String TOPIC_SPARKSTREAMING="TOPIC_SPARKSTREAMING_part1";
/**
* 初始化
*/
{
//1. 创建配置对象 指定Producer的信息
Properties properties = new Properties();
properties.put("acks", "1");
//配置默认的分区方式 ☆☆☆这里指定我们自定义的分区
properties.put("partitioner.class", "com.dahai.kafka.producer.SimplePartitioner");
//配置topic的序列化类
properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
//配置value的序列化类
properties