元数据存储
元数据存储的作用
元数据存储是 RabbitMQ 记录除队列和流消息之外的所有内容的数据库。
在集群中,元数据存储负责将这些信息复制到所有 RabbitMQ 节点。
元数据存储子系统依赖于一个后端库来提供数据库、其复制算法以及故障恢复特性。
支持的后端
RabbitMQ 支持两种不同的元数据存储:
- Khepri(较新,推荐)
- Mnesia(原始元数据存储)
在给定时间只能使用其中一种。下面将分别介绍它们。
Mnesia
Mnesia 是原始后端,也是 RabbitMQ 3.13.x 版本之前 RabbitMQ 使用的唯一后端。该库是 Erlang/OTP 标准发行版的一部分。
它效率适中,提供事务和集群复制,以及用于备份和恢复的 API。作为本地 Erlang/OTP 库,它与任何 Erlang 应用程序都完美集成。
Mnesia 的**弱点在于其故障恢复特性**,尤其是在网络分区方面。其复制算法假设使用 Mnesia 的系统可以承受丢弃网络分区一侧的所有数据,而这并不总是情况,也不符合许多技术运维团队的期望。
使用 Mnesia 时,如果两个节点在一段时间内无法通信,并且数据库在一个节点上进行了更新(例如声明了一个队列),则需要 RabbitMQ 来解决数据冲突。
为了解决这个问题,RabbitMQ 中引入了网络分区策略。然而,这绝非根本性解决方案,并且难以理解。
Khepri
Khepri 是从 RabbitMQ 4.0.x 版本开始完全支持的元数据存储。它由 RabbitMQ 团队开发,并重用了为法定数量队列和流所做的大量工作。
事实上,所有这些组件都基于Raft 共识算法。因此,在连接丢失的情况下,其行为是明确定义的,并且更容易理解。由于所有 RabbitMQ 组件和子系统都使用相同的算法,因此其行为在它们之间是一致的。
目标是最终只切换到 Khepri,停止使用 Mnesia。然而,Khepri 的使用与 Mnesia 相比是一个重大更改——尽管它是一个内部组件——因为它会影响集群或网络出现问题时用户可见的各种部分行为。
如果您想了解更多关于 Khepri 及其在 RabbitMQ 中集成的信息,在该项目的 Michael Davis 在 2023 年 Code BEAM Europe 会议上做了一个演讲。您可以在 YouTube 上观看“Khepri: Replacing Mnesia in RabbitMQ”的录制视频。
Khepri 从 RabbitMQ 4.2.0 版本开始成为默认后端。
Mnesia 仍将继续支持。现有的 RabbitMQ 部署在升级到 RabbitMQ 4.2.x 后将继续使用它,直到管理员显式启用 Khepri。
Mnesia 的支持将在未来版本中移除。这就是为什么**RabbitMQ 团队鼓励用户测试他们的工作负载和应用程序与 Khepri 的兼容性**,以使其真正成熟,成为 RabbitMQ 未来默认(也是唯一)的元数据存储。
接下来的几页将解释如何启用 Khepri,并涵盖各种日常操作中的行为变更。