RocketMQ 客户端负载均衡机制详解及最佳实践

news2025/7/31 1:36:13

延伸阅读:🔍「RocketMQ 中文社区」 持续更新源码解析/最佳实践,提供 RocketMQ 专家 AI 答疑服务

前言

本文介绍 RocketMQ 负载均衡机制,主要涉及负载均衡发生的时机、客户端负载均衡对消费的影响(消息堆积/消费毛刺等)并且给出一些最佳实践的推荐。

负载均衡意义

1.png

上图是 RocketMQ 的消息储存模型:消息是按照队列的方式分区有序储存的。RocketMQ 的队列模型使得生产者、消费者和读写队列都是多对多的映射关系,彼此之间都可以无限水平扩展。对比传统的消息队列如 RabbitMQ 是很大的优势。尤其是在流式处理场景下有天然优势,能够保证同一队列的消息被相同的消费者处理,对于批量处理、聚合处理更友好。

2.png

消费者消费某个 topic 的消息等同于消费这个 topic 上所有队列的消息(上图中 Consumer A1 消费队列 1,Consumer A2 消费队列 2、3)。

所以,要保证每个消费者的负载尽量均衡,也就是要给这些消费者分配相同数量的队列,并保证在异常情况下(如客户端宕机)队列可以在不同消费者之间迁移。

负载均衡机制解析

负载均衡时机

负载均衡是客户端与服务端互相配合的过程,我们先综合服务端和客户端的职责回答第一个问题:何时会发生负载均衡。

  • 客户端主动负载均衡 ** **

3.png

上图是 RocketMQ 客户端相关类的结构,其中 MQClientInstance 负责和服务端的交互以及底层服务的协调,这其中就包括负载均衡。

MQClientInstance 中有两个相关的方法 rebalanceImmediately 和 doRebalance,我们分析负载均衡的时机只要找到何时调用这两个方法即可:

  1. 启动时立即进行负载均衡;
  2. 定时(默认 20s)负载均衡一次。

  • 服务端通知负载均衡 ** **

服务端通知客户端进行负载均衡也是通过 MQClientInstance#rebalanceImmediately 方法实现的,我们同样在服务端代码中寻找相关调用。

4.png

分析以上几个方法可以得出结论,在如下场景服务端会主动通知客户端触发负载均衡:

  1. 客户端上下线

    • 上线
    1. 新客户端发送心跳到服务端
    • 下线
    1. 客户端发送下线请求到服务端
    2. 底层连接异常:响应 netty channel 的 IDLE/CLOSE/EXCEPTION 事件
  2. 订阅关系变化:订阅新 topic 或有旧的 topic 不再订阅

负载均衡策略

前文已经介绍了负载均衡实际是变更消费者负责处理的队列数量,这里每次需要变更的队列数量和受到影响的客户端数量是由负载均衡策略决定的。

我们来分析一下比较常见的负载均衡策略:

  • 平均分配

平均分配(AllocateMessageQueueAveragely)是默认的负载均衡策略:

如果我们有 4 个客户端,24 个队列,当第二个客户端下线时:

以默认的负载均衡策略(AllocateMessageQueueAveragely)为例,重新分配队列数量为 8。

默认的负载均衡策略能将队列尽量均衡的分配到每个客户端,但是每次负载均衡重新分配队列数量较多,尤其是在客户端数量很多的场景。

客户端队列分配变化队列数变化
Client116 -> 186 -> 8
Client27~12 -> -6 -> 0
Client31318 -> 9166 -> 8
Client41924 -> 17246 -> 8
  • 一致性哈希

基于一致性哈希算法的负载均衡策略(AllocateMessageQueueConsistentHash)每次负载均衡会重新分配尽可能少的队列数量,但是可能会出现负载不均的情况。

客户端队列分配变化队列数变化
Client116 -> 196 -> 9
Client27~12 -> -6 -> 0
Client31318 -> 10186 -> 9
Client41924 -> 19246 -> 8

负载均衡对消费的影响

我们以一个真实的线上场景来举例:

下图中绿色的线代表发送 tps,黄色的线代表消费 tps,我们很容易发现在 21:00 和 21:50 分左右存在消费毛刺。

5.png

这两个时间点在进行应用发布,根据我们上文的分析某个消费者下线后同组的其他消费者感知这一变化需要一定时间,导致有秒级的消费延迟产生。在发布结束后消费者快速处理堆积的消息,可以发现消费速度有一个明显的上涨。

这个例子展示了下线时由于负载均衡带来了短暂的消息处理延迟,新的消费者会从服务端获取消费位点继续之前的消费进度。如果消费者异常宕机或者没有调用 shutdown 优雅下线,没有上传自己的最新消费位点,会使得新分配的消费者重复消费。

这里我们总结下负载均衡对消费的影响,当某个客户端触发负载均衡时:

  1. 对于新分配的队列可能会重复消费,这也是官方要求消费要做好幂等的原因;
  2. 对于不再负责的队列会短时间消费停止,如果原本的消费 TPS 很高或者正好出现生产高峰就会造成消费毛刺。

最佳实践

避免频繁上下线

为了避免负载均衡的影响应该尽量减少客户端的上下线,同时做好消费幂等。

同时在有应用重启或下线前要调用 shutdown 方法,这样服务端在收到客户端的下线请求后会通知客户端及时触发负载均衡,减少消费延迟。

选择合适的负载均衡策略

需要根据业务需要灵活选择负载均衡策略:

  • 需要保证客户端的负载尽可能的均衡:选择默认的平均分配策略;
  • 需要降低应用重启带来的消费延迟:选择一致性哈希的分配策略。

当然还有其他负载均衡策略由于时间关系不一一介绍了,留给读者自行探索。

保证客户端订阅一致

RocketMQ 的负载均衡是每个客户端独立进行计算,所以务必要保证每个客户端的负载均衡算法和订阅语句一致。

  • 负载均衡策略不一致会导致多个客户端分配到相同队列或有客户端分不到队列;
  • 订阅语句不一致会导致有消息未能消费。

RocketMQ 5.0 消息级别负载均衡

为了彻底解决客户端负载均衡导致的重复消费和消费延迟问题,RocketMQ 5.0 提出了消息级别的负载均衡机制。

同一个队列的消息可以由多个消费者消费,服务端会确保消息不重不漏的被客户端消费到:

6.png

消息粒度的负载均衡机制,是基于内部的单条消息确认语义实现的。消费者获取某条消息后,服务端会将该消息加锁,保证这条消息对其他消费者不可见,直到该消息消费成功或消费超时。因此,即使多个消费者同时消费同一队列的消息,服务端也可保证消息不会被多个消费者重复消费。

在 4.x 的客户端中,顺序消费的实现强依赖于队列的分配。RocketMQ 5.0 在消息维度的负载均衡的基础上也实现了顺序消费的语意:不同消费者处理同一个消息组内的消息时,会严格按照先后顺序锁定消息状态,确保同一消息组的消息串行消费。

7.png

如上图所述,队列 Queue1 中有 4 条顺序消息,这 4 条消息属于同一消息组 G1,存储顺序由 M1 到 M4。在消费过程中,前面的消息 M1、M2 被 消费者Consumer A1 处理时,只要消费状态没有提交,消费者 A2 是无法并行消费后续的 M3、M4 消息的,必须等前面的消息提交消费状态后才能消费后面的消息。

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

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

相关文章

【SSM】SpringMVC学习笔记7:前后端数据传输协议和异常处理

这篇学习笔记是Spring系列笔记的第7篇,该笔记是笔者在学习黑马程序员SSM框架教程课程期间的笔记,供自己和他人参考。 Spring学习笔记目录 笔记1:【SSM】Spring基础: IoC配置学习笔记-CSDN博客 对应黑马课程P1~P20的内容。 笔记2…

C++课设:实现本地留言板系统(支持留言、搜索、标签、加密等)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、项目功能概览与亮点分析1. 核心功能…

【见合八方平面波导外腔激光器专题系列】用于干涉光纤传感的低噪声平面波导外腔激光器2

----翻译自Mazin Alalus等人的文章 摘要 1550 nm DWDM 平面波导外腔激光器具有低相位/频率噪声、窄线宽和低 RIN 等特点。该腔体包括一个半导体增益芯片和一个带布拉格光栅的平面光波电路波导,采用 14 引脚蝶形封装。这种平面波导外腔激光器设计用于在振动和恶劣的…

Xcode 16.2 版本 pod init 报错

Xcode 版本升级到 16.2 后,项目执行 pod init 报错; ### Error RuntimeError - PBXGroup attempted to initialize an object with unknown ISA PBXFileSystemSynchronizedRootGroup from attributes: {"isa">"PBXFileSystemSynchron…

timestamp时间戳转换工具

作为一名程序员,一款高效的 在线转换工具 (在线时间戳转换 计算器 字节单位转换 json格式化)必不可少!https://jsons.top 排查问题时非常痛的点: 经常在秒级、毫秒级、字符串格式的时间单位来回转换,于是决定手撸一个…

数据库管理与高可用-MySQL故障排查与生产环境优化

目录 #1.1MySQL单案例故障排查 1.1.1MySQL常见的故障排查 1.1.2MySQL主从故障排查 #2.1MySQL优化 2.1.1硬件方面的优化 2.1.2进程方面的优化 #3.1MySQL存储引擎 3.1.1 MyISAM存储引擎 3.1.2 InnoDB存储引擎 1.1MySQL单案例故障排查 1.1.1MySQL常见的故障排查 (1&…

LangChain + LangSmith + DeepSeek 入门实战:构建代码生成助手

本文基于 Jupyter Notebook 实践代码,结合 LangChain、LangSmith 和 DeepSeek 大模型,手把手演示如何构建一个代码生成助手,并实现全流程追踪与优化。 一、环境准备与配置 1. 安装依赖 pip install langchain langchain_openai2. 设置环境变…

【Elasticsearch基础】Elasticsearch批量操作(Bulk API)深度解析与实践指南

目录 1 Bulk API概述 1.1 什么是批量操作 1.2 Bulk API的优势 2 Bulk API的工作原理 2.1 请求处理流程 2.2 底层机制 3 Bulk API的使用方法 3.1 基本请求格式 3.2 操作类型示例 3.3 响应格式 4 Bulk API的最佳实践 4.1 批量大小优化 4.2 错误处理策略 4.3 性能调…

MySQL 数据库深度剖析:事务、SQL 优化、索引与 Buffer Pool

在当今数据驱动的时代,数据库作为数据存储与管理的核心,其性能与可靠性至关重要。MySQL 作为一款广泛使用的开源数据库,在众多应用场景中发挥着关键作用。在这篇博客中,我将围绕 MySQL 数据库的核心知识展开,涵盖事务及…

MAZANOKE结合内网穿透技术实现跨地域图像优化服务的远程访问过程

文章目录 前言1. 关于MAZANOKE2. Docker部署3. 简单使用MAZANOKE4. 安装cpolar内网穿透5. 配置公网地址6. 配置固定公网地址总结 前言 在数字世界高速发展的今天,您是否察觉到那些静默增长的视觉数据正在悄然蚕食存储空间?随着影像记录成为日常习惯&…

World-writable config file /etc/mysql/mysql.conf.d/my.cnf is ignored

https://stackoverflow.com/questions/53741107/mysql-in-docker-on-ubuntu-warning-world-writable-config-file-is-ignored 修改权限 -> 重启mysql # 检查字符集配置 SHOW VARIABLES WHERE Variable_name IN (character_set_server, character_set_database ); --------…

信息收集:从图像元数据(隐藏信息收集)到用户身份的揭秘 --- 7000

目录 🌐 访问Web服务 💻 分析源代码 ⬇️ 下载图片并保留元数据 🔍 提取元数据(重点) 👤 生成用户名列表 🛠️ 技术原理 图片元数据(EXIF 数据) Username-Anarch…

如何优雅地绕过限制调用海外AI-API?反向代理与API中转技术详解​

阅读时长​​ | 8分钟 ​​适用读者​​ | 需要跨境调用OpenAI等AI服务的开发者/企业 ​​一、问题背景:为什么需要代理?​​ 最近在技术社区看到这样的求助: "公司服务器在国内,但业务需要调用OpenAI接口,直接访…

【自然语言处理】大模型时代的数据标注(主动学习)

文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构D 实验设计E 个人总结 A 论文出处 论文题目:FreeAL: Towards Human-Free Active Learning in the Era of Large Language Models发表情况:2023-EMNLP作者单位:浙江大…

React与原生事件:核心差异与性能对比解析

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…

暴雨新专利解决服务器噪音与性能悖论

6月1日,我国首部数据中心绿色化评价方面国家标准《绿色数据中心评价》正式实施,为我国数据中心的绿色低碳建设提供了明确指引。《评价》首次将噪音控制纳入国家级绿色评价体系,要求从设计隔声结构到运维定期监测实现闭环管控,加速…

Go 语言中的内置运算符

1. 算术运算符 注意: (自增)和--(自减)在 Go 语言中是单独的语句,并不是运算符。 package mainimport "fmt"func main() {fmt.Println("103", 103) // 13fmt.Println("10-3…

JS面试常见问题——数据类型篇

这几周在进行系统的复习,这一篇来说一下自己复习的JS数据结构的常见面试题中比较重要的一部分 文章目录 一、JavaScript有哪些数据类型二、数据类型检测的方法1. typeof2. instanceof3. constructor4. Object.prototype.toString.call()5. type null会被判断为Obje…

【靶场】XXE-Lab xxe漏洞

前言 学习xxe漏洞,搭了个XXE-Lab的靶场 一、搭建靶场 现在需要登录,不知道用户名密码,先随便试试抓包 二、判断是否存在xxe漏洞 1.首先登录抓包 看到xml数据解析,由此判断和xxe漏洞有关,但还不确定xxe漏洞是否存在。 2.尝试xxe 漏洞 判断是否存在xxe漏洞 A.send to …

开源项目实战学习之YOLO11:12.6 ultralytics-models-tiny_encoder.py

👉 欢迎关注,了解更多精彩内容 👉 欢迎关注,了解更多精彩内容 👉 欢迎关注,了解更多精彩内容 ultralytics-models-sam 1.sam-modules-tiny_encoder.py2.数据处理流程3.代码架构图(类层次与依赖)blocks.py: 定义模型中的各种模块结构 ,如卷积块、残差块等基础构建…