如何启用 Khepri
从 RabbitMQ 4.2.0 开始,Khepri 已成为所有新部署的默认元数据存储后端。对于最初使用 RabbitMQ 4.1.x 或更早版本的现有部署,必须使用 khepri_db 功能标志显式启用 Khepri。
本文档演示了如何在各种情况下启用 Khepri 以及用户应注意的事项。
在全新的 RabbitMQ 节点上
使用 CLI
-
使用您选择的方法启动新的 RabbitMQ 节点。下面的示例直接执行
rabbitmq-server(8)命令- bash
- PowerShell
rabbitmq-serverrabbitmq-server.bat此时,该节点使用 Mnesia 作为元数据存储后端。
-
启用
khepri_db功能标志- bash
- PowerShell
# Opt-in to enable Khepri.
rabbitmqctl enable_feature_flag khepri_db# Opt-in to enable Khepri.
rabbitmqctl.bat enable_feature_flag khepri_db
请参阅下一页,了解有关 Mnesia 节点和 Khepri 节点一起集群时会发生什么的更多信息。
使用管理 UI
-
使用您选择的方法启动新的 RabbitMQ 节点。请参阅 上面的示例。
此时,该节点使用 Mnesia 作为元数据存储后端。
-
启用 管理插件
- bash
- PowerShell
rabbitmq-plugins enable rabbitmq_managementrabbitmq-plugins.bat enable rabbitmq_management -
打开并登录 管理 UI。
-
导航到“管理 > 功能标志”。
-
启用
khepri_db。
使用环境变量
$RABBITMQ_FEATURE_FLAGS 环境变量可以设置为在新节点启动时启用的功能标志的绝对列表,或与默认启用的功能标志相比的相对列表。此变量仅在首次启动时考虑;之后将被忽略。
使用您选择的方法启动新的 RabbitMQ 节点,同时设置 $RABBITMQ_FEATURE_FLAGS 变量。下面的示例直接执行 rabbitmq-server(8) 命令
- bash
- PowerShell
env RABBITMQ_FEATURE_FLAGS="+khepri_db" rabbitmq-server
$Env:RABBITMQ_FEATURE_FLAGS = '+khepri_db'
rabbitmq-server.bat
RabbitMQ 节点将从一开始就使用 Khepri。
在现有的独立节点或集群上
Khepri 可以在所有集群节点在线且集群处于健康状态时启用,就像任何其他功能标志一样。Khepri 无法在节点或整个集群停止时启用。
要启用 Khepri,请使用上面描述的 CLI 命令或 管理 UI 方法。
现有数据从 Mnesia 到 Khepri 的迁移与 RabbitMQ 的常规活动并行进行。然而,这次迁移需要资源,并且在过程结束时会短暂暂停其他活动。因此,请在非高峰时段执行此迁移。
启用 Khepri 后会发生什么?
从 Mnesia 到 Khepri 的迁移由 khepri_mnesia_migration 库负责。
该库分两个阶段执行迁移
- 它将集群成员身份从 Mnesia 同步到 Khepri。
- 它将记录从 Mnesia 表复制到 Khepri 存储。
第 1 步:集群成员身份同步
常见情况是 Khepri 在基于 Mnesia 的集群中启用,因此从 Khepri 的角度来看,所有涉及的节点都是独立的单个节点。
为了更加安全并避免数据丢失(如果某些节点已经在 Khepri 级别进行了集群),khepri_mnesia_migration 使用多个条件来确保 Khepri 集群是确定性的。为此,它会执行以下步骤
-
它查询 Mnesia 集群的成员列表。这是我们希望在 Khepri 中进行集群的基线节点列表。
-
它查询每个节点以获取 Khepri 集群的成员。通常,Khepri 尚未集群,因此每个节点仅返回自身。
-
它根据以下标准对 Khepri“集群”列表进行排序
- 集群大小(即成员数量)
- Khepri 存储中的记录数量
- 节点正常运行时间
- 节点名称
因此,如果某些节点已经在 Khepri 级别进行了集群,则 Khepri 集群将按最大的集群(节点集)进行排序。
但通常,节点未集群,因此按节点正常运行时间和名称排序。
-
它根据上述标准选择最大的 Khepri“集群”并将所有其他节点添加到该最大的集群中
-
如果某些节点已在 Khepri 级别集群但不在 Mnesia 中,则它们将从 Khepri 中删除
第 2 步:模式记录复制
一旦集群成员身份视图在 Mnesia 和 Khepri 之间相同,khepri_mnesia_migration 就可以继续进行实际的数据迁移。它在允许 Mnesia 写入直到最后一刻的同时执行复制。
复制依赖于 RabbitMQ 提供的回调模块。这些回调模块负责告知 khepri_mnesia_migration 表 $table 中的记录 $record 进入 Khepri 路径 $path,可能还需要进行一些记录转换。
以下是数据复制算法的步骤
-
khepri_mnesia_migration将迁移标记为 Khepri 中的进度值。 -
它订阅所有 Mnesia 更新。
-
它使用 Mnesia 备份和还原 API 从 Mnesia 执行首次复制到 Khepri。这是基于 Mnesia 中的某个时间点检查点,因此视图是一致的。
-
它将所有 Mnesia 表标记为只读。此时 RabbitMQ 的活动将暂停。客户端操作可能会因此超时。
-
在第 2 步中通过 Mnesia 订阅接收到的所有更新现在将被消耗并写入 Khepri。因为表是只读的,所以可以确定更新流有一个终点。
-
它将迁移标记为完成。RabbitMQ 可以恢复活动:从现在开始将使用 Khepri。
-
它继续进行清理:删除表。
错误回滚
如果在此过程中发生错误,所有操作都将回滚,RabbitMQ 将像以前一样使用 Mnesia 继续活动。