RabbitMQ Khepri元数据存储
元数据存储的作用
元数据存储是RabbitMQ记录除队列和流消息外所有信息的数据库,包括:
● 内部数据存储中的用户和权限(“内部”指代的是在RabbitMQ内部定义的用户,而非外部系统如LDAP定义的用户)
● 虚拟主机
● 拓扑结构:交换机、队列、绑定关系
● 运行时参数和策略

RabbitMQ支持两种不同的库来提供该数据库:
- Mnesia
- Khepri
每次只能使用其中之一。以下是它们的详细介绍。
Mnesia
Mnesia是最初的后端,也是RabbitMQ 3.13.x版本之前唯一使用的后端。该库是Erlang/OTP标准发行版的一部分。
它效率较高,支持事务和集群复制,提供备份和恢复的API,并且作为原生的Erlang/OTP库,能够完美集成到任何Erlang应用中。
Mnesia的弱点在于其故障恢复特性,尤其是在网络分区的情况下。其复制算法假设使用Mnesia的系统可以承受在网络分区的一侧丢弃所有数据,但这并不总是成立,也不符合许多技术运维团队的期望。
对于Mnesia,如果两个节点在一段时间内无法通信,且数据库在一侧被更新(例如声明了一个队列),则由RabbitMQ负责解决数据冲突。
为了解决这个问题,RabbitMQ引入了网络分区处理策略。但这些策略并非根本解决方案,且难以推理。
Khepri

Khepri是RabbitMQ 4.0.x开始全面支持的元数据存储。它由RabbitMQ团队开发,并大量复用了仲裁队列和流功能的工作成果。
实际上,这些组件均基于Raft共识算法。因此,在连接丢失的情况下,其行为有明确定义且更易于推理。由于所有组件和子系统使用相同的算法,其行为也保持一致。
最终目标是完全切换到Khepri并停止使用Mnesia。然而,Khepri的使用与Mnesia相比是一个重大变化(尽管它是内部组件),因为它会影响集群或网络出现问题时用户可见的多个部分行为。
提示
Khepri将在RabbitMQ 4.1.0中成为默认后端。
Mnesia仍将得到支持。现有的RabbitMQ部署在升级到4.1.x版本后将继续使用Mnesia,直到管理员显式启用Khepri。
Mnesia的支持将在未来版本(可能是4.2.0)中移除。因此,RabbitMQ团队鼓励用户使用Khepri测试其工作负载和应用,以使其真正成熟,成为RabbitMQ未来的默认(且唯一)元数据存储。
重要提示
尽管Khepri在RabbitMQ4.0.x中得到全面支持,但它没有Mnesia长达17年的广泛使用历史。我们鼓励所有RabbitMQ用户在在生产环境中采用Khepri之前对其进行全面测试。
从4.0.x升级到未来版本时,可以保持Khepri的启用状态。
特性标志子系统使用“稳定”和“实验性”来标识特性标志的成熟度。
实验性特性标志在两种情况下使用:
- 在开发早期引入变更以获取反馈。这些变更可能会被撤销,启用此类特性标志的RabbitMQ节点可能无法升级,且可能不提供支持。
- 用于RabbitMQ团队已承诺并提供支持的功能,直到其准备就绪并默认启用,可能替代旧系统。
RabbitMQ 3.13.x中的Khepri属于第一类。但请放心,RabbitMQ 4.0及更高版本中的Khepri属于第二类,因此得到全面支持。
在新节点上启用Khepri
● 使用CLI工具
- 启动新的RabbitMQ节点(方法自选)。以下示例直接执行rabbitmq-server命令:
1
rabbitmq-server
此时节点使用Mnesia作为元数据存储后端。
2. 启用khepri_db特性标志:
1 | # 启用Khepri |
使用管理UI
- 启动新的RabbitMQ节点(方法自选)。
- 启用管理插件:
1
rabbitmq-plugins enable rabbitmq_management
- 打开并登录管理UI。
- 导航至“Admin > Feature Flags”。
- 勾选“I understand the risk”并点击“Enable”按钮。

集群与Khepri
当RabbitMQ节点集群化时,它们调用元数据存储后端创建或扩展集群。这对Mnesia和Khepri均适用。
因此,基于Khepri的RabbitMQ集群的形成或扩展方式与Mnesia相同。
● 何时启用Khepri
可在集群创建前后启用Khepri。
如果集群创建后启用Khepri,第一步是将集群视图从Mnesia同步到Khepri。
● 注意事项
由于使用Raft共识算法,所有涉及元数据存储更新的操作(有时甚至查询)需要多数节点可用。
