基于对象大小的队列

基于对象大小的队列(Size-based BlockingQueue)

  • ✅ 控制内存缓存(Map、List、Queue)的字节大小;
  • ❌ 不再基于“个数”控制;
  • ✅ 防止 OOM;
  • ✅ 支持生产者-消费者模型;
  • ✅ 可扩展支持 Map 缓存结构;
  • ✅ 提供完整的概要设计 + 详细设计 + 示例代码 + 流程图。

🧱 一、需求背景

数据库迁移场景描述:

  • 源端:MySQL / Oracle / PostgreSQL
  • 目标端:MySQL / Hive / Kafka / ES 等
  • 迁移方式:全量 + 增量
  • 中间缓存结构:
    • BlockingQueue<Row> 存放待处理数据;
    • Map<String, Object> 存放缓存元数据或进度信息;
  • 问题:使用传统基于“个数”的队列无法有效控制内存占用,容易造成 OOM。

📦 二、整体架构设计

+---------------------+
|      Producer       |
| (源端读取模块)     |
+----------+----------+
           |
           v
+---------------------+
| SizeBasedBlockingQueue |
| - 基于字节大小控制   |
| - 支持 put() / take()|
+----------+----------+
           |
           v
+---------------------+
|      Consumer       |
| (目标端写入模块)   |
+---------------------+

✅ 功能目标

功能 描述
✅ 基于字节大小控制 控制队列中对象的总字节数不超过设定值
✅ 支持阻塞操作 生产者满时阻塞,消费者空时等待
✅ 对业务透明 接口兼容 BlockingQueue,无缝替换
✅ 支持异步报警 当接近阈值时可触发预警
✅ 支持自定义序列化 可配置对象大小估算方式

📈 三、概要设计方案

1️⃣ 核心思路

  • 使用装饰器模式封装 BlockingQueue
  • 维护一个 AtomicLong currentSize 表示当前队列中的总字节数;
  • 在每次 put()take() 时更新字节数;
  • 当超过 maxByteSize 时阻塞生产者线程;

2️⃣ 技术选型建议

技术点 实现方式
字节估算 使用 jol-coreInstrumentation.getObjectSize()
序列化 可插拔接口,如 Object -> byte[]
队列实现 基于 ArrayBlockingQueueLinkedBlockingQueue 封装
异常处理 超时机制、中断机制兼容原生 API
可视化监控 可集成 Prometheus Exporter

🖼️ 四、流程图

+---------------------+
| 用户调用 put(object) |
+----------+----------+
           |
           v
   +-------+--------+
   | 计算 object 字节大小 |
   +------------------+

           |
           v
   +---------------------+
   | 是否 currentSize + size > maxByteSize? |
   | 是 → awaitNotFull() 阻塞 |
   +---------------------+

           |
           v
   +---------------------+
   | 加锁(ReentrantLock) |
   +---------------------+

           |
           v
   +---------------------+
   | 入队 + 更新 currentSize |
   +---------------------+

           |
           v
   +---------------------+
   | 唤醒 notEmpty 条件    |
   +---------------------+

           |
           v
   +---------------------+
| 用户调用 take()        |
| 获取对象并减去字节数     |
+---------------------+

🧪 五、核心类设计与代码实现

✅ 1. SizeBasedBlockingQueue.java(主控类)

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class SizeBasedBlockingQueue<T> {
   
    private final BlockingQueue<T> delegate; // 底层队列
    private final long maxByteSize;          // 最大允许字节数
    private final ObjectSizer<T> sizer;       // 对象大小估算器
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();

    private volatile long currentByteSize = 0;

    public SizeBasedBlockingQueue(long maxByteSize, int capacity, ObjectSizer<T> sizer) {
   
        this.delegate = new LinkedBlockingQueue<>(capacity);
        this.maxByteSize = maxByteSize;
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DataLu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值