Kafka自定义分区策略实战避坑指南

news2025/5/29 7:30:58

文章目录

    • 概要
    • 代码示例
    • 小结

概要

kafka生产者发送消息默认根据总分区数和设置的key计算哈希取余数,key不变就默认存放在一个分区,没有key则随机数分区,明显默认的是最不好用的,那kafka也提供了一个轮询分区策略,我自己使用的是一言难尽,具体我也没有深究下去,那么针对业务硬性要求消息按照升序或降序轮询分区,就需要我们自己定义分区策略了。

有多少小伙伴第一次配置自定义分区策略时,发现分区总是按照倍数分区,并没有按照指定的规则去分区呢?嘿嘿,相信没阅读过源码的都应该踩过这一个坑,原因在于生产者发送消息时,kafka会先去分区策略那里逛一圈,拿到本次分区值,再去执行下一步流程,而在真正执行发送消息之前,kafka会再次进入分区策略内拿取本次的分区值,那么轮询策略一般按照依次递增或递减,致使发送消息时都会拿到自增两次后的分区值。

好,知道了问题所在,那就简单了,修改逻辑就行了呗,这一块考虑到使用分区策略一般是应对多个消息的产生同时发送,所以就涉及到并发了,那么并发就要考虑线程安全,这里推荐使用原子自增类和原子Boolean(非必要),能不使用锁就不使用锁,具体根据各位的业务而定吧,那话不多说,上代码。

代码示例

package org.example.springkafkademo.config;

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.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

public class CustomerPartitioner implements Partitioner {
    //针对并发设计,使分区数量原子自增
    private static AtomicInteger nextPartition  = new AtomicInteger(0);
    //二次进入判断机制
    private static AtomicBoolean flag = new AtomicBoolean(false);
    @Override
    public int partition(String topic, Object key, byte[] bytes, Object o1, byte[] keyBytes, Cluster cluster) {
        List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);
        //最大自增值
        int numPartitions = partitions.size();
        if (key == null) {
            //二次判断机制为true则说明自增过一次,需要返回自增之前的值
            if (flag.get()){
                flag.set(false);
                return nextPartition.get()-1;
            }
            //原子类将旧值返回再自增
            int next = nextPartition.getAndIncrement();
            //如果自增后与大于最大值或相等则直接cas赋值0,使下一次的轮询从0开始
            if (next >= numPartitions) {
                nextPartition.compareAndSet(numPartitions, 0);
            }
            //标记已经进入过一次
            flag.set(true);
            System.out.println("分区值:" + next);
            return next;
        } else {
            // 如果key不为null,则使用默认的分区策略
            return Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;
        }
    }

    @Override
    public void close() {

    }

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

    }
}

小结

本文分享kafka实现自定义轮询策略,在应对需要将大量的消息轮询发送给分区的场景时,可以采纳本文的代码逻辑,但是并不是适配所有分区轮询,毕竟业务逻辑不是定死的,各位小伙伴一定要结合实际业务逻辑,针对性的对代码进行修改扩展。
有哪里不懂得小伙伴可留言或私信,如与本文章有不同观点欢迎讨论留言,大家一起进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2387196.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[免费]微信小程序宠物医院管理系统(uni-app+SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序宠物医院管理系统(uni-appSpringBoot后端Vue管理端)&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序宠物医院管理系统(uni-appSpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibi…

ETL 工具与数据中台的关系与区别

ETL 工具和数据中台作为数据处理领域的关键概念&#xff0c;虽然存在一定的关联&#xff0c;但二者有着明显的区别。本文将深入剖析 ETL 工具与数据中台之不同。 一、ETL 工具概述 ETL 是数据仓库技术中的核心技术之一&#xff0c;其全称为 Extract&#xff08;抽取&#xff…

SQLMesh Typed Macros:让SQL宏更强大、更安全、更易维护

在SQL开发中&#xff0c;宏&#xff08;Macros&#xff09;是一种强大的工具&#xff0c;可以封装重复逻辑&#xff0c;提高代码复用性。然而&#xff0c;传统的SQL宏往往缺乏类型安全&#xff0c;容易导致运行时错误&#xff0c;且难以维护。SQLMesh 引入了 Typed Macros&…

Docker 使用镜像[SpringBoot之Docker实战系列] - 第537篇

历史文章&#xff08;文章累计530&#xff09; 《国内最全的Spring Boot系列之一》 《国内最全的Spring Boot系列之二》 《国内最全的Spring Boot系列之三》 《国内最全的Spring Boot系列之四》 《国内最全的Spring Boot系列之五》 《国内最全的Spring Boot系列之六》 《…

解锁MCP:AI大模型的万能工具箱

摘要&#xff1a;MCP&#xff08;Model Context Protocol&#xff0c;模型上下文协议&#xff09;是由Anthropic开源发布的一项技术&#xff0c;旨在作为AI大模型与外部数据和工具之间沟通的“通用语言”。它通过标准化协议&#xff0c;让大模型能够自动调用外部工具完成任务&a…

Error in beforeDestroy hook: “Error: [ElementForm]unpected width “

使用 element 的 form 时候报错&#xff1a; vue.runtime.esm.js:3065 Error: [ElementForm]unpected width at VueComponent.getLabelWidthIndex (element-ui.common.js:23268:1) at VueComponent.deregisterLabelWidth (element-ui.common.js:23281:1) at Vue…

私有知识库 Coco AI 实战(七):摄入本地 PDF 文件

是否有些本地文件要检索&#xff1f;没问题。我们先对 PDF 类的文件进行处理&#xff0c;其他的文件往后稍。 Coco Server Token 创建一个 token 备用。 PDF_Reader 直接写个 python 程序解析 PDF 内容&#xff0c;上传到 Coco Server 就行了。还记得以前都是直接写入 Coco …

【Unity3D】将自动生成的脚本包含到C#工程文件中

我们知道&#xff0c;在用C#开发中&#xff0c;通过vs编辑器新建的脚本&#xff0c;会自动包含到vs工程中&#xff0c;而通过外部创建&#xff0c;比如复制别的工程或代码创建的C#脚本不会包含到vs工程。 在我们的日常开发中&#xff0c;通常会自动创建C#脚本&#xff0c;特别…

【Python 深度学习】1D~3D iou计算

一维iou 二维 import numpy as npdef iou_1d(set_a, set_b):# 获得集合A和B的边界 x1, x2 set_ay1, y2 set_b# 计算交集的上下界low max(x1,y1)high - min(x2, y2)# 计算交集if high - low < 0:inter 0else:inter high - low# 计算并集union (x2 -x1) (y2 - y1) - in…

java23

1.美化界面 添加背景图片 所以我们添加背景图片要放在后面添加 添加图片边框 绝对路径&#xff1a; 相对(模块)路径&#xff1a; 第一个是绝对路径&#xff0c;第二个是相对路径&#xff0c;但是斜杠的方向不对 总结&#xff1a; 2.图片移动 先实现KeyListener接口&#xf…

LitCTF2025 WEB

星愿信箱 使用的是python&#xff0c;那么大概率是ssti注入 测试{{5*5}} 发现需要包含文字&#xff0c;那么添加文字 可以看到被waf过滤了&#xff0c;直接抓包查看参数上fenjing 可以看到这里是json格式&#xff0c;其实fenjing也是支持json格式的 https://github.com/Marv…

Linux 下VS Code 的使用

这里以创建helloworld 为例。 Step 0:准备工作&#xff1a; Install Visual Studio Code. Install the C extension for VS Code. You can install the C/C extension by searching for c in the Extensions view (CtrlShiftX). Step 1: 创建工作目录 helloworld&#xff0…

Qt 布局管理器的层级关系

1、HomeWidget.h头文件&#xff1a; #ifndef HOMEWIDGET_H #define HOMEWIDGET_H#include <QWidget> #include <QPushButton> #include <QVBoxLayout> #include <QHBoxLayout>class HomeWidget : public QWidget {Q_OBJECTpublic:HomeWidget(QWidget …

maven模块化开发

使用方法 将项目安装到本地仓库 mvn install 的作用 运行 mvn install 时&#xff0c;Maven 会执行项目的整个构建生命周期&#xff08;包括 compile、test、package 等阶段&#xff09;&#xff0c;最终将构建的 artifact 安装到本地仓库&#xff08;默认路径为 ~/.m2/repos…

云原生安全之网络IP协议:从基础到实践指南

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 IP协议&#xff08;Internet Protocol&#xff09;是互联网通信的核心协议族之一&#xff0c;负责在设备间传递数据包。其核心特性包括&…

C++——QT 文件操作类

QFile 概述 QFile是Qt框架中用于文件操作的类&#xff08;位于QtCore模块&#xff09;&#xff0c;继承自 QIODevice&#xff0c;提供文件的读写、状态查询和路径管理功能。它与 QTextStream、QDataStream 配合使用&#xff0c;可简化文本和二进制数据的处理&#xff0c;并具备…

[spring] spring 框架、IOC和AOP思想

目录 传统Javaweb开发的困惑 loC、DI和AOP思想提出 Spring框架的诞生 传统Javaweb开发的困惑 问题一&#xff1a;层与层之间紧密耦合在了一起&#xff0c;接口与具体实现紧密耦合在了一起 解决思路&#xff1a;程序代码中不要手动new对象&#xff0c;第三方根据要求为程序提…

尚硅谷redis7 37-39 redis持久化之AOF简介

37 redis持久化之AOF简介 AOF 以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工…

GitLab 备份所有仓库(自动克隆)

一、准备工作 1. 环境要求 已安装 Git&#xff08;版本 2.10&#xff09;本地磁盘空间充足&#xff08;根据仓库总大小预估&#xff09;已配置 SSH 密钥到 GitLab&#xff08;推荐方式&#xff09; 2. 获取 GitLab API 访问权限 登录 GitLab&#xff0c;点击右上角头像 → …

[浏览器]缓存策略机制详解

在做页面性能优化的时候&#xff0c;有一个点容易被忽略&#xff0c;那就是资源缓存优化。 浏览器里缓存策略分为强缓存&#xff0c;协商缓存以及不缓存&#xff0c;每个缓存策略都有其适用的优化场景。 下面为大家详解何为强缓存&#xff0c;协商缓存 先说结论强缓>协商&g…