kafka中的自定义分区器使用详解

本文详细介绍了Kafka中自定义分区器的使用,通过实现Partitioner接口,根据业务规则设置消息的分区存储,确保数据均匀分布,提高系统性能。文中通过一个实例展示了如何创建自定义分区器,并在生产者和消费者中应用,测试结果表明key666和key888的消息都被正确地分配到‘2’号分区。
摘要由CSDN通过智能技术生成

综述

在Kafka中,topic是逻辑上的概念,而partition是物理上的概念。不用担心,这些对用户来说是透明的。 生产者(producer)只关心自己将消息发布到哪个topic,而消费者(consumer)只关心自己订阅了哪个topic上的消息,至少topic上的消息分布在哪些partition节点上,它本身并不关心。

设想一下,如果在Kafka中没有分区的话,那么topic的消息集合将集中于某一台服务器上,单节点的存储性能将马上成为瓶颈,当访问该topic存取数据时,吞吐也将成为瓶颈。
介于此,kafka的设计方案是,生产者在生产数据的时候,可以为每条消息人为地指定key,这样消息被发送到broker时,会根据分区规则选择消息将被存储到哪一个分区中。如果分区规则设置合理,那么所有的消息将会被均匀/线性的分布到不同的分区中,这样就实现了负载均衡和水平扩展。
另外,在消费者端,同一个消费组可以多线程并发的从多个分区中同时消费数据。

上述分区规则,实际上是实现了 org.apache.kafka.clients.producer.Partitioner 接口,这个实现类可以根据自己的业务规则进行自定义制定分区,如根据hash算法指定分区的分布规则。
比如在以下的案例类中,我们先获取key的hashcode值,再跟分区数量partitionsNum-1做模运算,结果值作为分区存储位置,这样可以实现数据均匀线性的分布。

下面我们以一个小的案例来介绍Kafka自定义分区器的使用。

1、 创建Maven工程,导入以下依赖:

		<dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka-clients</artifactId>
            <version>0.9.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.kafka</groupId>
            <artifactId>kafka_2.11</artifactId>
            <version>0.9.0.0</version>
        </dependency>

2、 编写自定义分区器类,实现Partitioner接口

package com.xsluo;

import org.apache.kafka.clients.producer.Partitioner;
import org.apache.kafka.common.Cluster;
import org.apache.kafka.common.PartitionInfo;
import java.util.List;
import java.util.Map;

/**
 * @author:xsluo
 * @date:2020/7/10
 * @aim:自定义分区器
 */
public class MyPartitioner implements Partitioner {
   
    /**
     * 自定义kafka分区主要解决用户分区数据倾斜问题 提高并发效率(假设 3 分区)
     * @param topic 消息队列名
     * @param key   用户传入key
     * @param keyBytes  key字节数组
     * @param value 用户传入value
     * @param valueBytes    value字节数组
     * @param cluster   当前kafka节点数
     * @return  如果3个分区,返回 0 1 2
     */
    public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
   
        //获取topic的partitions信息
        List<PartitionInfo> partitionInfos = cluster.partitionsForTopic(topic);
        int partitionsNum = partitionInfos.size();
        //为特定的key自定义分区规则
 
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值