滚动(就地)升级
滚动升级是一种流行的升级策略,其中节点一个接一个地进行升级:每个节点都被停止、升级,然后启动。升级后的节点重新加入集群,集群暂时以混合版本模式运行:一些节点运行旧版本,一些节点运行新版本。
虽然在升级期间所有节点都必须重新启动,但整个集群在整个过程中保持可用(当然,除非它只有一个节点)。
滚动升级不支持跳过版本,除了补丁版本(例如,您可以**直接**从 3.13.0 升级到 3.13.7,但您**不能**直接从 3.12.x 升级到 4.0)。此外,对于特定的升级,可能适用其他约束。请参阅版本可升级性表以获取更多信息。
升级前
调查当前版本和目标版本是否存在滚动升级路径
请参阅版本可升级性表以获取有关支持的升级路径的信息。
检查 Erlang 版本要求
请参阅Erlang 版本要求。
如果当前和目标 RabbitMQ 版本都支持相同的 Erlang 版本,您可以保留 Erlang 不变。但是,您可以考虑同时将 Erlang 升级到最新的支持版本。Erlang 和 RabbitMQ 升级都需要重启,因此同时进行两者可能会更方便。
如果目标 RabbitMQ 版本需要更新的 Erlang 版本,则需要准备与 RabbitMQ 一起升级 Erlang。
仔细阅读选定 RabbitMQ 版本之前的发行说明
该发行说明可能指示特定的其他升级步骤。始终查阅当前部署版本和目标版本之间所有版本的发行说明。
验证所有稳定特性标志是否已启用
所有稳定特性标志都应在每次升级后启用。否则,升级过程并未真正完成,因为某些更改无效。如果您遵循此建议,则在升级之前无需对特性标志进行任何操作,因为它们在上次升级后都已启用。
但是,由于尝试使用禁用的特性标志进行升级可能会导致严重问题,因此在开始升级之前检查所有稳定特性标志是否已启用是一个好习惯。您可以安全地运行rabbitmqctl enable_feature_flag all
- 如果所有标志都已启用,则它不会执行任何操作。
确保所有软件包依赖项(包括 Erlang)都可用
如果您使用的是 Debian 或 RPM 软件包,则必须确保所有依赖项都可用。特别是 Erlang 的正确版本。您可能需要设置额外的第三方软件包存储库才能实现这一点。
请阅读有关基于 Debian 的和基于 RPM 的发行版的建议,以查找适合 Erlang 的存储库。
评估集群健康状况
确保节点处于健康状态,并且没有网络分区或磁盘或内存警报生效。
RabbitMQ 管理 UI、CLI 工具或 HTTP API 可用于评估系统的健康状况。
管理 UI 中的概述页面显示有效的 RabbitMQ 和 Erlang 版本、多个集群范围的指标和速率。在此页面上,确保所有节点都在运行并且它们都是“绿色”(关于文件描述符、内存、磁盘空间等)。
我们建议记录持久队列的数量、它们包含的消息数量以及有关拓扑结构的其他相关信息。这些数据将有助于验证系统在升级后是否在合理的参数范围内运行。
使用节点健康检查来检查各个节点。
处于流状态或被阻止/阻止连接的队列可能不是问题,具体取决于您的工作负载。由您决定这是否正常情况,或者集群是否处于意外负载下,并据此决定是否可以安全地继续升级。
但是,如果存在处于未定义状态的队列(即NaN
或“幽灵”队列),则应首先了解问题所在,然后再开始升级。
确保集群具有升级容量
请参阅系统资源使用情况的变化以获取有关升级过程如何影响资源使用情况的信息。
执行升级
升级过程的主要部分是通过逐个停止、升级和启动每个节点来执行的。以下步骤应针对所有节点执行。
停止节点
停止节点的确切方法取决于节点的启动方式。
备份
可选地,当节点停止时,您可以备份其数据文件夹。
升级节点
安装新版本的 RabbitMQ 和其他必要的软件包。
确保您拥有与新 RabbitMQ 版本兼容的 Erlang 版本。
启动节点
启动节点并验证它是否加入集群。
您可以执行以下检查以确保节点已成功启动并重新加入集群
- 运行
rabbitmqctl cluster_status
并验证输出- 升级后的节点应列为正在运行
- 不应该存在网络分区或活动警报
- 检查管理 UI
- 所有节点都应列在主页上
- 资源使用量应在可接受的范围内
- 检查日志
- 不应该存在错误
升级后
验证升级是否成功
与升级前一样,验证健康状况和监控数据,以确保所有集群节点都处于良好状态并且服务已重新运行。
启用新的特性标志
一旦所有节点都已升级并且集群处于健康状态,请启用所有稳定特性标志。如果新版本没有提供任何新的特性标志,您仍然可以运行rabbitmqctl enable_feature_flag all
- 它只会什么都不做。
真实世界示例
滚动升级策略不特定于任何特定的部署工具或基础设施。许多编排工具都内置了滚动升级的概念,以及在每个节点升级之前和之后执行自定义操作的钩子。
Kubernetes 就是这样一个编排工具。它可以执行StatefulSet
的滚动更新。让我们来看一下当您想要使用集群运算符将部署到 Kubernetes 的 RabbitMQ 升级时会发生什么。假设集群有三个节点,这意味着节点被称为server-0
、server-1
和server-2
(在您的集群名称前会加上一个前缀,但这与本示例无关)。
- 确保现有集群正在运行 RabbitMQ 3.13 并已启用所有稳定特性标志
- 使用新镜像更新
RabbitmqCluster
对象(例如,从rabbitmq:3.13.7-management
更改为rabbitmq:4.0.0-management
) - 集群运算符将使用新镜像更新
StatefulSet
对象,从而触发 Kubernetes 中内置的滚动升级机制 - Kubernetes 将停止
server-2
(它总是从最高的索引到最低的索引)- Pod 将通过调用
rabbitmq-upgrade await_online_quorum_plus_one
来检查它是否可以安全地停止 - 当该命令以零状态退出时,Pod 将停止
- Pod 将通过调用
- Kubernetes 将下载并启动新的 OCI 镜像。实际上,它升级了 RabbitMQ、Erlang 和其他系统依赖项的软件包。
server-2
启动并尝试重新加入集群- 它启用了与停止前相同的特性标志(特性标志的状态存储在文件中)。
- 在 RabbitMQ 4.0 中引入或此时**未**启用的特性标志。
- 因此,升级后的节点可以加入集群。
- 节点启动后,它会同步其元数据(例如,了解在其关闭期间声明的队列),并启动仲裁队列和流成员,这些成员应该很快赶上集群的其余部分(节点关闭期间发布的任何消息都会复制到它等)。
server-2
运行后,Kubernetes 会停止server-1
,然后重复此过程。server-0
升级并运行后,所有节点都运行新版本。- 您现在可以启用新的特性标志并重新平衡集群。
虽然此过程包含许多步骤(我们跳过了一些细节),但您只需更改 image
值,等待几分钟,然后运行两个命令即可启用新的特性标志并重新平衡集群。
在没有 Kubernetes 的情况下执行滚动升级时,您需要执行相同的步骤 - 您只需手动或使用其他自动化工具执行这些步骤。使用 OCI 镜像进一步简化了流程,因为镜像已包含新的 RabbitMQ 版本以及兼容的 Erlang 版本和其他依赖项。