Skip to content

RobustMQ 对标NATS:内存模式

在设计 RobustMQ 时,我们一直在思考一个问题:能否用统一的架构,服务从持久化到内存、从强一致到最终一致的所有场景?

NATS 在微服务通信、实时推送、IoT 等场景中表现出色,核心竞争力是纯内存、极低延迟、极高 QPS。但 NATS 只做内存分发,如果需要持久化,就得切换到 JetStream,这是两套系统。我们希望 RobustMQ 能在一个统一的平台上,通过简单的配置切换,就能适配从 NATS 到 Kafka 的各种场景。

内存模式就是为此设计的。

内存模式的目标场景

RobustMQ 的内存模式主要对标三类场景。

第一类是实时行情推送。股票价格、加密货币行情、外汇汇率,这些数据的特点是高频更新、延迟敏感、历史数据价值低。新的价格会覆盖旧的价格,如果系统重启丢失了几秒钟的历史数据,用户重新订阅即可,影响很小。但延迟如果从微秒级变成毫秒级,用户体验会明显变差。这种场景天然适合内存存储。

第二类是传感器数据采样。IoT 设备每秒可能产生几千次数据上报,但并不是每个数据点都需要精确保存。系统更关心的是趋势和异常,偶尔丢失几个数据点不影响整体分析。而且海量的传感器数据如果全部持久化,存储成本会很高。内存模式配合降采样,既保证了低延迟,又控制了成本。

第三类是游戏中的临时状态。玩家的实时位置、临时 buff、技能冷却状态,这些数据的生命周期很短,丢失了客户端重新同步即可。但延迟要求很高,因为直接影响游戏体验。游戏的关键数据(金币、装备、等级)会通过数据库持久化,消息队列只负责临时状态的实时同步。

这三类场景有个共同特点:允许少量数据丢失,但对延迟极其敏感。NATS 就是为这类场景设计的,而 RobustMQ 的内存模式也瞄准了同样的需求。

单副本 vs 双副本

NATS Core 是纯内存单副本,节点重启数据全丢。这对很多场景来说完全够用,但有些场景希望在低延迟和可靠性之间找个平衡点。

单副本内存的问题是节点重启或故障时,所有未消费的数据会丢失。虽然业务可以接受数据丢失,但如果能降低丢失的概率,体验会更好。比如游戏服务器重启,如果所有玩家的位置状态都丢了,需要所有客户端重新上报,会造成短暂的混乱。

双副本内存配合弱一致性(acks=1)可以解决这个问题。写入时 Leader 收到数据后立即返回成功,延迟仍然是微秒级。但 Leader 会在后台异步复制到第二个副本。这样只有两个副本同时故障才会丢数据,概率大大降低。单节点重启时,另一个副本仍然有数据,可以继续服务。

当然这仍然不是强一致性,如果 Leader 返回成功后立即崩溃,且数据还没复制到第二副本,仍会丢失。但相比单副本,可靠性已经提升很多。相比三副本持久化,延迟优势巨大(100µs vs 5ms)。这是在延迟和可靠性之间的一个务实选择。

使用方式

RobustMQ 的内存模式使用很简单。在创建 Shard 时,指定存储类型为内存,设置副本数,就启用了内存模式。不需要额外的配置,不需要部署新的组件,对用户来说几乎没有负担。

同一个集群中,可以有些 Shard 用内存模式(行情推送),有些 Shard 用持久化模式(订单消息)。用户根据业务特性灵活配置。这种统一平台的好处是运维成本低,不需要维护多套系统。

而且内存模式和持久化模式可以无缝切换。如果业务需求变化,比如某个 Topic 从"可丢失"变成"不可丢失",只需要修改配置,新的 Shard 就会用持久化模式,历史数据逐步迁移。整个过程平滑过渡。

内存容量管理

内存是有限资源,需要合理管理。RobustMQ 的策略是设置容量限制和时间限制。比如单个 Segment 最大 1GB,或者最多保留 5 分钟。达到阈值后强制封存,创建新的 Segment。如果内存满了,可以选择拒绝新写入,或者淘汰最旧的数据。

对于 Sealed 的内存 Segment,如果配置了异步持久化,可以在后台写入磁盘或 S3,然后释放内存。这样既保证了写入的极低延迟,又不会让内存无限膨胀,还能为部分数据提供持久化保障。

性能预期

内存模式的性能预期是:单副本延迟 100µs,双副本延迟 100-200µs(异步复制不影响返回),吞吐量百万级 msg/sec。这个性能水平可以对标甚至超越 NATS,同时通过双副本提供了更好的可靠性保障。

相比持久化模式的 3-5ms 延迟,内存模式快了 20-50 倍。对于实时行情、游戏状态这类场景,这个性能差异是有实际意义的。

与 NATS 的差异

NATS 是专门的内存消息系统,极致轻量,专注做好一件事。RobustMQ 的内存模式是统一平台的一部分,通过配置启用。

优势在于灵活性。同一个 RobustMQ 集群,可以同时服务持久化和内存场景。不需要部署两套系统,不需要在 NATS 和 Kafka 之间来回切换。而且如果业务需求变化,配置调整即可,无需迁移系统。

另一个优势是双副本选项。NATS Core 是单副本,JetStream 是持久化,没有中间状态。RobustMQ 提供了双副本内存这个选项,在延迟和可靠性之间提供了更多选择空间。

总结

RobustMQ 的内存模式不是为了和 NATS 竞争,而是为了在统一平台上提供类似 NATS 的能力。通过在 Shard 级别配置存储类型和副本数,用户可以灵活选择。实时行情用单副本内存追求极致延迟,游戏状态用双副本内存平衡可靠性,订单数据用持久化保证不丢失。

一个平台,多种模式,按需配置。这是 RobustMQ 存储层灵活性的体现。


关于 RobustMQ

RobustMQ 是一个用 Rust 编写的高性能消息队列,采用存算分离架构,支持从内存到持久化的多种存储模式。欢迎关注我们的 GitHub,参与技术讨论。