滚动升级

本文档是 Neo4j 操作手册条目 升级 Causal Cluster 的补充,提供了有关 Kubernetes 中滚动升级方法的更多信息。

开始之前

  1. 在尝试滚动升级之前,请阅读所有相关文档。本文档不会描述所有相关概念。默认您已熟悉其他页面。

  2. 在类似生产的环境中执行测试升级,以了解可能需要的停机时间(如果有)的持续时间。

何时需要?

  • 当您拥有 Neo4j Causal Cluster 时(独立部署不适用)

  • 当您需要升级到新的 Neo4j 次要版本或补丁版本时

  • 当您在升级过程中必须保持集群在线并具备读写能力时。

本方法不涵盖的内容

在 Neo4j 主要版本之间迁移(例如,3.5 和 4.0)。由于以下因素,这需要更多规划:

  • 3.5 和 4.0 版本之间在 pods 上所需的重大配置更改

  • 产品功能的重大变化,这些变化会影响客户端可以依赖的内容。

  • 所使用 helm charts 及其结构的更改;如果您使用的是旧的 3.5 helm chart,则您正在使用的版本与此 repo 之间的差异可能很大。

  • 需要进行存储升级操作来更改磁盘上 Neo4j 数据格式

Neo4j 4.0 与 3.5 不向后兼容。建议进行额外的规划和离线升级。

如果您正处于从 Neo4j 3.5 → 4.0 的迁移情况,请查阅 Neo4j 迁移指南

如果此方法不适用于您的限制,请查看本文档最底部的“滚动升级的替代方案”。

高级方法

  1. 进行备份

  2. 扩展核心 StatefulSet,以维持高可用性。

  3. 选择并应用您的 UpdateStrategy。

  4. 修补 StatefulSet 以应用新的 Neo4j 版本

  5. 监控过程

  6. (可选/如适用)将上述过程也应用于读副本 StatefulSet。

  7. 成功后缩减回原始大小。

现在我们将描述每个步骤、如何执行以及原因。

进行备份

在进行任何重大的系统维护操作之前,拥有最新的备份至关重要,以确保在出现问题时可以恢复到数据库的某个时间点状态。

此外,在对关键应用程序系统进行操作之前,所有操作都应在预生产环境或类似生产的环境中进行“演练”测试。本仓库的用户指南中包含了执行备份的内容。

扩展核心 StatefulSet

如果您的 StatefulSet 通常有 3 个核心成员,它们正在提供有价值的高可用性目的和仲裁

在滚动升级操作中,我们将依次使每个服务器下线。当一个服务器停止/重启时,我们会(暂时)损害集群的 HA 特性,降低其服务查询的能力。为了缓解这个问题,在进行滚动升级之前,我们将集群扩容,例如从 3 个核心扩展到 5 个。然后我们将滚动应用更改 - 在任何给定时刻,我们将有 5 个核心中的 4 个可用。

对于名为 "mygraph" 的集群部署,您可以按如下方式将其扩展到 5 个核心

kubectl scale statefulsets mygraph-neo4j-core --replicas=5

这应立即调度 2 个具有相同配置(和 Neo4j 版本)的新 pods 启动并加入集群。建议您扩展 2 个而不是 1 个,以确保集群中的核心数量始终是奇数。

请记住,当新成员加入集群时,在集群稳定之前,它们需要拉取当前的事务状态。强烈建议先让成员从最近的备份中恢复,以最小化追赶过程的负载。

如果您不在每个 pod 上从备份恢复,它仍然可以工作,但集群可能需要很长时间让新成员追赶上来,特别是如果您的数据量或事务历史很多的话。

有关更多信息,请查阅 kubernetes 文档中的扩展 StatefulSet

选择并应用您的 UpdateStrategy

有关更多详细信息,请查阅 Kubernetes StatefulSet 更新策略

在接下来的步骤中,我们将告知 StatefulSet 更改其正在运行的 Neo4j 版本。在此之前,我们需要为其指定滚动升级的策略。您基本有两种主要选择:RollingUpdateOnDelete。本文档假定使用 RollingUpdate 策略。在这种情况下,Kubernetes 执行以下操作:

  • 从末尾(核心编号最高)开始,它会关闭一个 pod 并重启。因为我们将修补版本,所以当该 pod 重启时,它将启动新版本。

  • Kubernetes 会等待 pod 进入 Ready 状态。

  • 滚动更新会继续到下一个最低索引。

Readiness / Liveness Checks 的重要性

Kubernetes 对 Neo4j 知之甚少。需要为其提供 Neo4j 处于“准备就绪 (ready)”状态的定义。如果在下一个 pod 滚动之前新 pod 未准备就绪,可能会导致集群在失去更多成员之前没有时间稳定下来。

用户手册中描述的 readiness checks 用于此目的。在执行滚动升级之前,请审查它们对您部署的充分性和适用性,并进行必要的修改。

修补 StatefulSet

到目前为止,我们所做的一切都只是准备工作,但这一步实际上会产生变化。如果您运行此操作,根据您上面指定的 UpdateStrategy,Kubernetes 将开始终止并重启 pods。

NEW_VERSION=neo4j:4.1.0-enterprise
kubectl patch statefulset mygraph-neo4j-core --type='json' \
    -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"'$NEW_VERSION'"}]'

监控过程

我们正在寻找的: * 一次只有一个 pod 停止/重启 * 在整个过程中,能持续保持与集群的连接,具备读写能力。* 监控 debug.log 文件和容器输出,确保过程正确进行

(可选)将过程应用于读副本

读副本在第二个 StatefulSet 中处理。但应用更新策略、修补 StatefulSet 和监控的过程是相同的。

推荐:在处理读副本之前,请确保您拥有完全迁移且运行良好的核心集群成员集。不要同时滚动两个集合。

缩减

如果一切正确完成,您将得到一个运行新版本的 5 成员集群,100% 在线。成功后,不再需要额外的成员,您可以缩减回集群的原始大小。

kubectl scale statefulsets mygraph-neo4j-core --replicas=3

滚动升级的替代方案

如果您可以容忍一段时间的写不可用性同时保持完全的读可用性,Kubernetes 提供了一种滚动升级的备选方案。本文档将重点介绍如何进行滚动升级,但作为主要替代方案的概述:

  1. 将您当前的集群配置为由单个 DNS 记录支持 (mycluster.company.com)

  2. 备份您当前的集群。

  3. 启动运行新版本 Neo4j 的第二个集群 (mycluster-updated)。从 mycluster 的最后一次备份恢复此集群。

  4. 热切换 DNS 记录指向第二个集群 (mycluster-updated)

  5. 关闭原始集群 (mycluster)

如果您采用此方法,则需要一个维护窗口,在此期间您不接受写入操作,从备份点开始计算。写不可用的时期应在步骤 2 和步骤 4 中 DNS 准备就绪之间。如果在此期间向原始集群写入数据,则这些数据将不会出现在更新后的集群中。

此方法应在整个过程中保持读可用性,并且是相对安全的;即,如果新集群未能正确迁移或存在数据问题,这不会影响正在运行的生产系统的可用性。

© . All rights reserved.