Opsqueue:为重负载而生的轻量级批处理队列,已开源!

大家好,这里是架构资源栈 !点击上方关注,添加"星标",一起学习大厂前沿架构!

关注、发送C1即可获取JetBrains全家桶激活工具和码!

最近,Channable 团队发布了一个新的开源项目 ------ Opsqueue。这是为了解决"重批处理"需求所设计的一套轻量级队列系统,现在终于公开了!

说白了,Opsqueue 是为那些动辄几百万操作、强调吞吐量、注重处理顺序、又不想部署一整套 Kafka 或 Celery 的团队准备的。

为什么需要另造一个轮子?

有几个明确的需求:

  • 轻量简洁:用 Rust 写的小巧代码库,依赖少,部署容易。
  • 批处理优先:强调吞吐量,而非实时性,适合"今天生成,明天处理"的模式。
  • 弹性可扩展:支持水平扩展,能够处理十亿级别的操作量。
  • 技术栈扎实:SQLite + 对象存储(S3、GCS 等)+ Rust,稳定、可靠、性能高。
  • 部署简单:单个二进制,嵌入式数据库,最小配置即可上手。

Channable 团队之前试过各种方案,从 Redis 列表到 PostgreSQL 表格队列,还有数据库元数据 + 对象存储混合方案......但总归不是特别理想:不是易错就是扩展性差。于是我们决定,"干脆造一个真正通用的队列系统"!

设计核心:"生成 - 执行" 模式

在很多服务中都看到类似的流程:

  1. A 服务生成数百万个操作(例如一堆图像处理任务、API 调用、LLM 推理等);
  2. 把这些操作扔进"输入队列";
  3. B 服务(或多台服务)并行执行这些任务;
  4. 然后把结果写回"输出队列";
  5. A 服务再根据结果做下一步处理(例如拼装成结果、触发后续逻辑等)。

我们把这个流程称为 "generate-execute" 模式,它是 Producer-Consumer 的一个进阶变种 ------ 类似于 MapReduce,但没有 reduce,也可以看作是并行 Map 操作的分布式实现。

我们希望的是:生产者(Producer)只管提交任务,消费者(Consumer)按需并行处理,并且结果可以有序地回传给生产者。这个闭环非常重要。

为什么不选现有的队列系统?

先看简单对比:

特性 Kafka RabbitMQ Redis List Opsqueue
有序性保障 分区级顺序 仅支持 FIFO 队列 无强一致顺序保障 完整任务有序性
部署复杂度 中等偏上 极低(单文件即可运行)
消费端灵活度 高(需自实现) 高,支持动态调度策略
数据持久性 高(结合对象存储)
支持大批量 适合但偏实时 支持但繁琐 不适合 极其适合批处理
使用门槛 较高 中等 极低 低(Rust 单二进制部署)
  • Kafka 是高吞吐利器,但维护 ZooKeeper、Broker、Schema Registry 不易;

  • RabbitMQ 虽然灵活但 AMQP 配置繁琐;

  • Redis List 容易入门但扩展性差,且不具备任务元信息能力。

而 Opsqueue 以 Rust 编写、只依赖 SQLite 和对象存储,初始部署成本几乎为零,却在批处理吞吐、数据一致性、任务调度灵活性上做到了高度平衡。

虽然像 RabbitMQ、Kafka、SQS 等已经非常成熟,但对我们来说,它们存在如下几个痛点:

  1. 无法保证有序性:我们需要任务提交和返回能对齐。
  2. 提交要么全成要么全失败:不能部分成功,这样处理逻辑才干净。
  3. 要抗网络问题,还要保持一致性:我们偏向一致性而不是可用性。
  4. 队列不能饿死某些用户:要确保使用公平。
  5. 操作必须是任意格式:支持任何语言,任何数据类型。
  6. 优先级要由消费者决定:因为执行方才最清楚什么该先做(比如 GPU 使用率、API 限流等)。

市面上的系统几乎没有同时满足这些点的。

技术选型:Rust + SQLite + 对象存储

Opsqueue的目标是 部署简单,维护轻松,开发友好。所以Opsqueue选择:

  • Rust 实现,编译成单个可执行文件;
  • SQLite 存储操作元数据(轻量 + 嵌入式);
  • S3/GCS 等对象存储保存真正的任务数据;
  • 支持 Litestream 实时备份数据库;
  • 所有网络交互尽量保持在亚毫秒级。

这种设计让Opsqueue可以轻松运行数百个独立队列,测试也非常容易 ------ 每个测试用例起一个 Opsqueue 实例毫秒级完成。

技术架构亮点

  • 任务分片(chunking)设计:一次性提交几十万个操作分成多个 chunk,每个 chunk 几秒完成,提升并发度与容错能力;
  • 元数据存 SQLite,任务体存对象存储(如 S3/GCS):减轻数据库压力,提高 I/O 性能;
  • 消费者优先调度机制:任务优先级可由消费者决策,例如根据 GPU 利用率、用户 ID、API 调用限额等;
  • Litestream 支持:通过持续同步 SQLite 数据库至远端对象存储实现高可用备份;
  • 可视化性能分析:内置 OpenTelemetry,便于链路追踪和延迟分析。

消费者优先策略:我们最大的杀手锏

传统队列系统通常由 生产者来决定任务优先级 ,而 Opsqueue 反其道而行之:让消费者决定优先顺序

为啥?因为消费者最清楚实际资源情况 ------ 哪台机器空闲?哪个用户快被限流了?哪个数据中心比较空?

Opsqueue支持生产者附带元数据(比如用户 ID、优先级数字),但最终决策权归消费者所有。这种机制非常灵活,可以支持更复杂的调度策略,比如:

  • 某类任务只能在指定区域执行;
  • 保障用户公平;
  • 优先执行短任务提高吞吐;
  • GPU 资源有限时自动排队;
  • 跨业务统一调度等。

性能与扩展性:小而美,也能顶得住大风浪

为了支持十亿级别操作,Opsqueue采取了一些设计策略:

  • 任务按"chunk"提交:每个 chunk 处理时间控制在几秒内,降低协调成本;
  • 数据存对象存储,SQLite 仅存元数据:存储压力低,查询快;
  • chunk 大小可调节:更好地平衡并发度与通信开销;
  • 支持分片(sharding):当规模再上去时,轻松横向扩展;
  • 内置 OpenTelemetry tracing:性能指标一目了然。

来看一张调试图,展示两个消费者同时连接队列时的 tracing 数据,注意 ------ 队列通信开销仅仅是亚毫秒级!

Rust:不是炫技,而是效率保障

Opsqueue不仅用 Rust 实现主程序,还通过 FFI 接口暴露给 Python 用作客户端。逻辑全在 Rust 中统一实现,避免多语言重复造轮子,也大大降低了 bug 风险。

目前Opsqueue已支持 Python 的客户端开发,入门示例点这里。未来要加 Java、Go、Node.js?可能一个下午就能搞定!

在生产环境的表现如何?

Opsqueue 已经在Channable 团队生产环境里跑了快半年。一条生产队列:

  • 完成了 10 万次提交;
  • 处理速率稳定在每小时 100 万操作;
  • 通信延迟始终维持在毫秒级以内;
  • 整体表现令人满意!

当然,Channable 团队不会强制重写已有的其他系统(毕竟重写是个大坑),但凡是要维护、扩展、或踩了老系统性能瓶颈的项目,Opsqueue 是可以考虑的替代方案

写在最后

我相信:你可能也遇到过类似的需求。希望 Opsqueue 这个项目能帮上忙,或者激发你构建更好的队列系统!

GitHub 仓库

祝你的任务队列永不卡顿,批处理永不爆炸!


喜欢就奖励一个"👍"和"在看"呗~