跳过主内容
版本:5.0

消息存储与清理

本文档描述了 Apache RocketMQ 如何存储消息,包括存储粒度、判断标准和处理策略。

背景信息

基于 Apache RocketMQ 中 MessageQueue 的定义,消息以 Broker 接收消息的顺序存储在队列中。理论上,一个队列可以存储的消息数量是无限的。

在实际部署场景中,消息无法永久存储,因为 Broker 的物理存储空间有限。因此,在部署消息时,您需要回答三个问题:使用什么标准来确定如何在 Broker 上存储消息?使用什么粒度来管理存储的消息?当消息存储使用量超出限制时,必须采取哪些措施?Apache RocketMQ 的消息存储和清理机制为上述问题提供了答案。

您可以从以下几个方面,通过消息存储和清理机制更好地进行运维工作

  • 存储 SLA:存储时长是指用户可以获取消息的时间段。此功能适用于需要较长消费周期、消息累积和故障恢复的场景。

  • 存储成本评估与控制:Apache RocketMQ 将消息存储在磁盘上。您可以提前评估存储空间并预留存储资源。

消息存储机制

工作机制

Apache RocketMQ 的每个节点都会存储消息一段特定的时间。这段时间称为存储时长,用于确定消息的存储时间。在存储时长内的消息会被保留,而超出时长限制的消息则会被清理,无论它们是否已被消费。

以下部分描述了与消息存储机制相关的项目

  • 管理粒度:Apache RocketMQ 根据节点管理消息存储时长。

  • 判断标准:消息存储时长用作判断标准。与消息数量或大小相比,存储时长可以帮助您更有效地评估消息的价值。

  • 消息存储与消费状态无关:Apache RocketMQ 中的消息存储时长从消息生产的时间点开始计算,与消费状态无关。您可以通过统一的计算策略简化消息存储机制。

下图展示了消息在队列中的存储方式。消息存储

注意

管理粒度

Apache RocketMQ 基于 Broker 节点管理存储时长,原因如下

  • 消息存储的优势:Apache RocketMQ 使用统一的两级组织方式管理物理数据,该方式由物理日志队列和轻量级逻辑队列组成。这种方法提供了有序读写操作、高吞吐量和高性能的优势。然而,通过这种方法,您无法根据主题或队列管理消息存储。

  • 容量保证和数据安全:尽管 Apache RocketMQ 根据主题或队列生成独立的存储文件,但这些文件共享相同的底层存储介质。您可以灵活地根据主题或队列管理存储时长。如果集群的存储容量不足,可能无法满足存储 SLA。如果您希望以安全的方式管理消息,最好的方法是在不同的集群中使用不同的存储时长来存储消息。

消息存储与消费状态的关系

Apache RocketMQ 以集中式方式管理消息存储时长,无论消息是否已被消费。

由于消费者不活跃或消费异常,消息可能会在队列中累积。目前,对于这个问题还没有有效的解决方案。如果所有未消费的消息都被保留,存储空间将迅速耗尽。这将影响新消息的读写速度。

消费者可以根据存储时长管理消息,以确定每条消息的生命周期。消费者可以在存储时长内的任何时间消费消息,或者通过 重置消费进度 功能多次消费消息。

消息存储文件结构 Apache RocketMQ 消息默认存储在本地磁盘文件中,存储文件的根目录由配置参数 storePathRootDir 决定。存储结构如下图所示,其中 commitlog 文件夹存储物理消息文件,consumeCQueue 文件夹存储逻辑队列索引。MessageStore

消息清理机制

在 Apache RocketMQ 中,消息的存储时长与实际存储时长不同。这是因为消息存储在本地磁盘中。当本地磁盘空间不足时,系统会强制删除消息以确保服务稳定性。因此,实际存储时长会短于指定的存储时长。

Apache RocketMQ 存储系统是基于阿里云的云原生技术开发的。这使得所有实例都可以使用存储空间,而不会对存储容量施加限制。所有消息都根据其指定的存储时长进行存储。您无需担心因存储空间不足而导致消息被删除。

使用说明

根据业务需求增加存储时长

Apache RocketMQ 根据存储时长控制是否保留消息。我们建议您根据业务需求指定更长的存储时长。更长的存储时长为您提供了更多的操作空间,用于紧急故障恢复、紧急问题排查和消息回溯。