问题:
- 延迟队列的作用
- 延迟队列数据结构
- 如何添加到延迟队列?
- 如何从延迟队列取出?
问题1延迟队列的作用
延迟队列用来解决需要延迟消费的场景,例如 电商中订单超时15分钟未支付自动关闭
特点:Pulsar的延迟队列可支持任意维度的延迟
存储:堆外内存
消息数:1G堆外内存 = 1 * 1024 * 1024 * 1024 / 24 = 44,739,242条,1G支持4400万条可满足大多数业务场景,不足就加内存。(ps: 消息是持久化到磁盘,延迟消息是从磁盘读取出来放入延迟队列中,只放消息的索引:2个long类型索引+1个long类型时间=24字节,假设broker宕机,启动后消费者读取消息会先放入延迟队列校验是否到时间,然后推送给消费者)
缺点:当延迟的时间维度差距很大(有几个月的,有几分钟的)影响磁盘删除,这时需要使用者按时间维度分topic发送(分多个层级分、时、天、周、月、季度、年),为什么呢?因为pulsar的删除最小单元是Ledger,一个Ledger可以存很多消息,其中有一条未消费,整个Ledger都不会删。导致磁盘越来越大
问题2延迟队列数据结构
延迟队列的实现是TripleLongPriorityQueue,本质是ByteBuf,一次写入24字节
public class TripleLongPriorityQueue implements AutoCloseable {
private static final int SIZE_OF_LONG = 8;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
// Each item is composed of 3 longs
private static final int ITEMS_COUNT = 3;
private static final int TUPLE_SIZE = ITEMS_COUNT * SIZE_OF_LONG;
private final ByteBuf buffer;
private int capacity;
private int size;
public TripleLongPriorityQueue() {
this(DEFAULT_INITIAL_CAPACITY);
}
public TripleLongPriorityQueue(int initialCapacity) {
capacity = initialCapacity;
buffer = PooledByteBufAllocator.DEFAULT.directBuffer(initialCapacity * ITEMS_COUNT * SIZE_OF_LONG);
size = 0;
}
...
}
问题3如何添加到延迟队列?
public class TripleLongPriorityQueue implements AutoCloseable {
public void add

本文深入解析Apache Pulsar的延迟队列功能,用于处理延迟消费场景,如订单超时。延迟队列基于堆外内存的TripleLongPriorityQueue实现,支持任意维度延迟,但当延迟时间差距大时需按时间维度分topic。添加到延迟队列涉及扩容、排序和交换操作,而从队列中取出消息则根据时间戳进行。该系统保证消息按延迟时间顺序处理,确保高效且精确的延迟消费。
最低0.47元/天 解锁文章
1061

被折叠的 条评论
为什么被折叠?



