pulsar中的延迟队列使用详解

Apache Pulsar的延迟队列支持任意时间精度的延迟消息投递,适用于金融交易、定时提醒等高时效性场景。其核心设计通过堆外内存索引队列持久化分片存储实现,兼顾灵活性与可扩展性。以下从实现原理、使用方式、优化策略及挑战展开解析:


一、核心实现原理
  1. 延迟消息索引管理

    • 堆外内存优先级队列:Pulsar通过DelayedMessageTracker维护延迟消息的索引(由timestamp | LedgerID | EntryID组成),按到期时间排序,形成最小堆结构。
    • 分片存储优化(3.x+版本):引入BucketDelayedDeliveryTracker,将延迟索引按时间片(如5分钟)分桶存储。当前临近时间的桶驻留内存,远期桶持久化至BookKeeper磁盘,降低内存压力。
  2. 投递流程

    • 生产者发送:通过deliverAfter(相对时间)或deliverAt(绝对时间)指定延迟时间,客户端计算时间戳后发送至目标Topic。
    • Broker处理:Dispatcher检查消息到期状态,到期消息直接投递消费者;未到期消息存入延迟索引队列,由定时任务触发后续投递。
  3. 容灾与恢复

    • 索引重建:Broker故障或Topic迁移时,Pulsar从磁盘加载延迟索引并重建内存队列,确保消息不丢失。但大规模延迟消息(如跨月级)的重建时间可能较长。

二、使用方式与代码示例
  1. 生产者发送延迟消息

    // 相对时间延迟
    producer.newMessage().value("订单已创建".getBytes()).deliverAfter(30, TimeUnit.MINUTES)  // 30分钟后投递.send();// 绝对时间延迟
    long deliverAt = System.currentTimeMillis() + 3600_000;  // 1小时后
    producer.newMessage().value("会议提醒".getBytes()).deliverAt(deliverAt).send();
    
  2. 消费者监听

    @Override
    public void received(Consumer<String> consumer, Message<String> msg) {if (msg.getPublishTime() + msg.getDelayTime() <= System.currentTimeMillis()) {// 处理到期消息(如关闭超时订单)consumer.acknowledge(msg);} else {consumer.negativeAcknowledge(msg);  // 重新入队等待下次检查}
    }
    

三、性能优化与挑战
  1. 内存与存储优化

    • 分片策略:按时间粒度(如5分钟)划分延迟索引桶,仅加载近期桶到内存,远期桶持久化磁盘,减少内存占用。
    • 批量写入:延迟索引积累至阈值(默认5万条)后批量写入磁盘,降低I/O开销。
  2. 大规模延迟消息挑战

    • 内存限制:旧版(3.x前)堆外内存索引队列在订阅组多或延迟跨度大时易耗尽内存。
    • 重建时间:跨月级延迟消息重建索引需数小时,可通过增加Topic分区提升并发度缓解。
  3. 最佳实践

    • 控制延迟跨度:业务设计时尽量限制延迟时间(如≤7天),避免远期消息导致存储膨胀。
    • 独立Topic隔离:将延迟消息与实时消息分离,减少对正常消费的影响。

四、应用场景
  1. 金融交易超时:支付订单15分钟内未确认则自动取消,释放资源。
  2. 预约提醒:医疗挂号前1小时推送短信通知,降低爽约率。
  3. 异步重试:接口调用失败后延迟5分钟重试,避开高峰期。

五、未来演进

Pulsar社区计划通过时间分区索引分层存储进一步提升大规模延迟消息处理能力:

  • 动态加载时间片:仅将临近时间片的索引加载到内存,其余持久化至冷存储(如S3)。
  • 延迟消息专用存储层:分离延迟消息与常规消息的存储路径,优化资源回收机制。

六、总结

Pulsar的延迟队列通过时间分片索引混合存储策略实现高精度、大规模的延迟消息投递,尤其适合金融、电商等时效敏感场景。开发者需注意版本差异(3.x+推荐使用分片存储),并通过合理设计延迟跨度和Topic分区规避性能瓶颈。未来随着分层存储的完善,Pulsar在处理超大规模延迟消息时将更具优势。


在这里插入图片描述

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

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

相关文章

单链表的实现 | 附学生信息管理系统的实现

目录 1.前言&#xff1a; 2.单链表的相关概念&#xff1a; 2.1定义&#xff1a; 2.2形式&#xff1a; 2.3特点&#xff1a; 3.常见功能及代码 &#xff1a; 3.1创建节点&#xff1a; 3.2头插&#xff1a; 3.3尾插&#xff1a; 3.4头删&#xff1a; 3.5尾删&#xff1a; 3.6插入…

java实用工具类Localstorage

public class LocalStorageUtil {//提供ThreadLocal对象,private static ThreadLocal threadLocalnew ThreadLocal();public static Object get(){return threadLocal.get();}public static void set(Object o){threadLocal.set(o);}public static void remove(){threadLocal.r…

LLM-大语言模型浅谈

目录 核心定义 典型代表 核心原理 用途 优势与局限 未来发展方向 LLM&#xff08;Large Language Model&#xff09;大语言模型&#xff0c;指通过海量文本数据训练 能够理解和生成人类语言的深度学习模型。 核心定义 一种基于深度神经网络&#xff08;如Transformer架…

【小兔鲜】day03 Home模块与一级分类

【小兔鲜】day03 Home模块与一级分类 1. Home-整体结构搭建和分类实现1.1 页面结构 2. Home-banner轮播图功能实现 1. Home-整体结构搭建和分类实现 1.1 页面结构 分类实现 2. Home-banner轮播图功能实现 轮播图实现 在HomeBanner.vue中写出轮播图的结构 在apis目录下新建h…

C++中的多态和模板

#include <iostream> #include <cstdlib> #include <ctime> #include <string>using namespace std;// 武器基类 class Weapon { public:virtual ~Weapon() {}virtual string getName() const 0; // 获取武器名称virtual int getAtk() const 0; …

Spring 概念

Spring 是一个功能强大、灵活且广泛使用的 Java 企业级开发框架&#xff0c;它诞生于 2003 年&#xff0c;由 Rod Johnson 创建&#xff0c;初衷是简化 Java EE 的开发过程。 一、Spring 是什么&#xff1f; 简单来说&#xff1a; Spring 是一个轻量级的 Java 开发框架&#…

神经网络之损失函数

引言&#xff1a;损失函数 &#xff08;Loss Function&#xff09;是机器学习和深度学习中非常重要的一个概念。用于衡量模型的预测值与真实值之间的差异&#xff0c;从而指导模型优化其参数以最小化这种差异。 一、损失函数作用 量化误差&#xff1a;损失函数是将预测值和真实…

Java 基础-32-枚举-枚举的应用场景

在Java编程中&#xff0c;枚举&#xff08;Enum&#xff09;提供了一种强大的方式来定义一组固定的常量。它们不仅限于简单的用途&#xff0c;还可以包含构造函数、方法和字段等高级功能&#xff0c;使其适用于多种不同的应用场景。本文将探讨几种常见的使用枚举的场景&#xf…

【网络安全】安全的网络设计

网络设计是网络安全的基础&#xff0c;一个好的网络设计可以有效的防止攻击者的入侵。在本篇文章中&#xff0c;我们将详细介绍如何设计一个安全的网络&#xff0c;包括网络架构&#xff0c;网络设备&#xff0c;网络策略&#xff0c;以及如何处理网络安全事件。 一、网络架构…

网络安全-等级保护(等保) 0. 前言

各位伙伴好&#xff1a; 招投标总结已过去一年了&#xff0c;时间飞逝&#xff0c;一直忙于工作&#xff0c;等保相关的内容断断续续整理了近半年的时间&#xff0c;但一直无暇完成博客内容。 等保已经是一个成熟的体系&#xff0c;现在已进入等保2.0时代&#xff0c;相关政策…

TLS协议详解

TLS协议 一&#xff0c;TLS协议的组成 TLS协议架构模块分为两层&#xff1a;TLS记录协议&#xff0c;TLS握手协议 ① TLS记录协议&#xff1a; 是所有子协议的基层&#xff0c;规定了TLS收发数据的基本单位。所有子协议都需要通过记录协议发出&#xff0c;多个记录数据可以在…

ollama更新升级及警告解决

1. 概述 在大模型业务处理中&#xff0c;需要用到gemma3 和 qwen2.5-VL&#xff0c;当前服务器的ollama版本 0.3.11&#xff0c;无法满足要求&#xff0c;需要更新升级。 2. 实施过程 参考官网升级要求&#xff1a; curl -fsSL https://ollama.com/install.sh | sh 不知道…

ubuntu 配置固定ip

在装服务器系统的时候&#xff0c;DHCP自动获取ip时&#xff0c;路由可能会重新分配ip&#xff0c;为避免产生影响&#xff0c;可以关闭DHCP将主机设置为静态ip。 系统环境 Ubuntu 22.04-Desktop 配置方式 一、如果是装的Ubuntu图形化&#xff08;就是可以用鼠标操作点击应用…

套接字编程函数recv和send ,以及设置reuseaddress

recv就是去套接字读缓冲区读数据 阻塞模式下&#xff1a;读缓冲区没数据那就阻塞等待&#xff0c;若等待被打断返回-1设置errno为EINTR 非阻塞模式下&#xff1a;读缓冲区没数据那就返回-1&#xff0c;设置errno为EAGAIN或EWOULDBLOCK。 若连接断开返回0&#xff0c;读取成功…

《C++后端开发最全面试题-从入门到Offer》目录

当今科技行业对C++开发者的需求持续高涨,从金融科技到游戏开发,从嵌入式系统到高性能计算,C++凭借其卓越的性能和灵活性始终占据着关键地位。然而,成为一名优秀的C++工程师并非易事,不仅需要扎实的语言基础,还要掌握现代C++特性、设计模式、性能优化技巧以及各种工业级开…

设计模式简述(十)责任链模式

责任链模式 描述基本使用使用 描述 如果一个请求要经过多个类似或相关处理器的处理。 可以考虑将这些处理器添加到一个链上&#xff0c;让请求逐个经过这些处理器进行处理。 通常&#xff0c;在一个业务场景下会对整个责任链进行初始化&#xff0c;确定这个链上有哪些Handler…

初识数据结构——Java集合框架解析:List与ArrayList的完美结合

&#x1f4da; Java集合框架解析&#xff1a;List与ArrayList的完美结合 &#x1f31f; 前言&#xff1a;为什么我们需要List和ArrayList&#xff1f; 在日常开发中&#xff0c;我们经常需要处理一组数据。想象一下&#xff0c;如果你要管理一个班级的学生名单&#xff0c;或…

ReFormX:现代化的 React 表单解决方案 - 深度解析与最佳实践

ReFormX文档 表单开发一直是前端工作中最繁琐却又最常见的任务之一。从简单的登录表单到复杂的多步骤配置页面&#xff0c;开发者往往需要编写大量重复代码&#xff0c;处理繁琐的状态管理、数据验证和联动逻辑。ReFormX 应运而生&#xff0c;它不仅是一个表单组件库&#xff…

WinForm真入门(9)——RichTextBox控件详解

WinForm中RichTextBox控件详解&#xff1a;从基础到高级应用 上一文中笔者重点介绍了TextBox控件的详细用法&#xff0c;忘记的 请点击WinForm真入门(8)——TextBox控件详解&#xff0c;那么本文中的RichTextBox与TextBox有什么区别吗&#xff0c;光看名字的话&#xff0c;多了…

Draw.io 全面解析与竞品分析:图表绘制工具的深度对比

目录 一、Draw.io 全面介绍 1. 产品概述 2. 核心功能特点 3. 用户体验 4. 商业模式 二、市场竞品分析 1. 主要竞品概览 2. 深度功能对比 3. 价格策略对比 4. 技术架构对比 三、用户场景与选择建议 1. 不同场景下的工具推荐 2. 未来发展趋势 四、结论 diagrams.net…