原英文版地址: https://www.elastic.co/guide/en/elasticsearch/reference/7.7/rolling-upgrades.html, 原文档版权归 www.elastic.co 所有
本地英文版地址: ../en/rolling-upgrades.html

滚动升级 (Rolling upgrades)

滚动升级允许 Elasticsearch 集群一次升级一个节点,因此升级过程中服务不会中断。 不支持在升级期间在同一个集群中运行多个版本的 Elasticsearch,因为分片不能从升级的节点复制到运行旧版本的节点。

强烈建议在升级时将集群的节点分成以下两组,并按以下顺序升级这些组:

  1. 不符合主节点条件 的节点。 可以使用 GET /_nodes/_all,master:false 或通过查找使用 node.master: false 配置的所有节点来检索这些节点的列表。
  2. 符合主节点条件的节点,即剩余的节点。可以用GET /_nodes/master:true 检索这些节点的列表。

你可以按任意顺序升级每组中的节点。

以这种顺序升级节点确保了不符合主节点条件的节点总是运行至少与符合主节点条件的节点一样的新版本。 较新的节点总是可以加入具有较旧主节点的集群,但是较旧的节点不是总能加入具有较新主节点的集群。 通过最后升级符合主节点条件的节点,可以确保所有不符合主节点条件的节点都能够加入集群,无论符合主节点条件的节点是否已经升级。 如果在升级不符合主节点条件的节点之前升级任何符合主节点条件的节点,则存在旧节点将离开集群并且在升级之前无法重新加入的风险。

滚动升级支持:

  • 次要版本之间
  • 从 5.6 到 6.8
  • 从 6.8 到 7.7.1
  • 从 7.7.0 到 7.7.1 的任何版本 (from any version since 7.7.0 to 7.7.1)

从 6.7 或更低版本直接升级到 7.7.1 需要 全集群重启升级

准备升级

在开始升级之前,认真准备非常重要。 一旦开始将集群升级到版本 7.7.1,则必须完成升级。 一旦集群包含 7.7.1 版本的节点,它可能会对其内部状态进行无法撤销的更改。 如果无法完成升级,则应放弃这个已部分升级的集群,部署一个升级前的版本的空集群,并从快照恢复内容。

在开始将集群升级到 7.7.1 版之前,你应该执行以下操作:

  1. 检查 弃用日志,查看你是否正在使用任何弃用的功能,并相应地更新你的代码。
  2. 查看 重大更改,并为 7.7.1 版进行任何代码和配置必要的更改。
  3. 如果你使用了插件,请确保每个插件都有一个与 Elasticsearch 7.7.1 版兼容的版本。
  4. 升级生产集群之前,请在隔离环境中测试升级过程。
  5. 使用快照备份数据!

升级集群

要执行到 7.7.1 的滚动升级:

  1. 禁用分片分配

    当你关闭一个节点时,分配进程会等待 index.unassigned.node_left.delayed_timeout (默认值为 1 分钟),然后开始将该节点上的分片复制到集群中的其他节点,这可能会涉及大量 I/O。 由于该节点将很快重新启动,因此不需要此 I/O。 通过在关闭节点之前 禁用副本分配,可以避免与时间赛跑:

    PUT _cluster/settings
    {
      "persistent": {
        "cluster.routing.allocation.enable": "primaries"
      }
    }
  2. 停止不必要的索引并执行 同步刷新(synced flush)。 (可选)

    虽然你可以在升级期间继续索引,但如果你暂时停止不必要的索引并执行同步刷新(synced-flush),分片恢复会快得多。

    POST _flush/synced

    执行同步刷新时,检查响应以确保没有失败。 由于挂起的索引操作导致失败了的同步刷新操作会在响应正文中列出,尽管请求本身仍会返回 200 OK 状态。 如果失败,重新发出请求。

    请注意,同步刷新已过时,将在8.0中删除。 Elasticsearch 7.6 或更高版本上的 刷新(flush) 与 同步刷新(synced flush) 效果相同。

  3. 暂时停止与主动机器学习工作和数据馈送(datafeed)相关的任务。 (可选)

    如果你的机器学习索引是在 6.x 之前创建的,你必须 重新索引这些索引

    如果你的机器学习索引是在 6.x 中创建的,你可以:

    • 在升级过程中让机器学习作业继续运行。 当你关闭机器学习节点时,它的作业会自动移动到另一个节点,并恢复模型状态。 此选项使作业能够在关闭期间继续运行,但这会增加集群的负载。
    • 使用 设置升级模式(set upgrade mode) API 暂时停止与机器学习作业和数据馈送(datafeed)相关联的任务,并阻止新作业打开:

      POST _ml/set_upgrade_mode?enabled=true

      当禁用升级模式时,作业将继续使用自动保存的最后一个模型状态。 此选项避免了升级期间管理活动作业的开销,并且比显式停止数据馈送和关闭作业更快。

    • 停止所有数据馈送(datafeed)并关闭所有作业。 此选项保存关闭时的模型状态。 升级完成后重新打开作业时,它们使用完全相同的模型。 但是,保存最新的模型状态比使用升级模式花费的时间更长,尤其是当你有许多作业或作业具有较大的模型状态时。
  4. 关闭单个节点

    • 如果你是使用 systemd 运行的 Elasticsearch:

      sudo systemctl stop elasticsearch.service
    • 如果你是使用 SysV init 运行的 Elasticsearch:

      sudo -i service elasticsearch stop
    • 如果你是以守护进程方式运行的 Elasticsearch:

      kill $(cat pid)
  5. 升级刚才关闭的那个节点。

    要使用 DebianRPM 包升级:

    • 使用 rpmdpkg 来安装新的软件包。 所有文件都安装在操作系统的适当位置,并且不会覆盖 Elasticsearch 配置文件。

    要使用 zip 或压缩的 tarball 进行升级:

    1. 将 zip 或 tarball 解压缩到一个目录。 如果不使用外部 configdata 目录,这一点非常重要。
    2. 设置 ES_PATH_CONF 环境变量,以指定外部 config 目录和 jvm.options 文件的位置。 如果没有使用外部 config 目录,请将旧的配置复制到新的安装目录中。
    3. config/elasticsearch.yml 中的 path.data 设置为你的外部 data 目录。 如果没有使用外部 data 目录,请将旧的数据目录复制到新的安装目录中。

      如果使用了监控功能,请在升级 Elasticsearch 时重复使用数据目录。 监控通过使用存储在数据目录中的持久 UUID 来识别唯一的 Elasticsearch 节点。

    4. config/elasticsearch.yml 中的 path.logs 设置为存储日志的位置。 如果不指定此设置,日志将存储在归档文件解压缩到的目录中。

    当你提取 zip 或 tarball 包时, elasticsearch-n.n.n 目录包含 Elasticsearch configdatalogs目录。

    建议将这些目录移出 Elasticsearch 目录,这样在升级 Elasticsearch 时就没有机会删除它们。 要指定新位置,请使用 ES_PATH_CONF 环境变量以及 path.datapath.logs 设置。 更多信息请参考 Elasticsearch的重要的配置.

    DebianRPM 包将这些目录放在每个操作系统的适当位置。 在生产环境中,我们建议使用 deb 或 rpm 包进行安装。

    在执行滚动升级时,应该保持 cluster.initial_master_nodes 未设置。 每个升级后的节点都将加入现有集群,因此不需要 集群引导。 必须在所有节点上配置 discovery.seed_hostsdiscovery.seed_providers (二选一)

  6. 升级插件。

    使用 elasticsearch-plugin 脚本安装每个已安装的 Elasticsearch 插件的升级版本。 升级节点时,必须升级所有插件。

  7. 如果你使用了 Elasticsearch 安全功能来定义 领域(realm),请验证你的领域设置是最新的。 在 7.0 版中,领域设置的格式发生了变化,尤其是领域类型的位置发生了变化。 参考领域设置
  8. 启动升级后的节点。

    启动刚升级的节点,并通过检查日志文件或提交一个 _cat/nodes 请求来确认它已加入集群:

    GET _cat/nodes
  9. 重新启用分片分配。

    节点加入集群后,删除 cluster.routing.allocation.enable 设置以启用分片分配并开始使用节点:

    PUT _cluster/settings
    {
      "persistent": {
        "cluster.routing.allocation.enable": null
      }
    }
  10. 等待节点恢复。

    在升级下一个节点之前,请等待集群完成分片分配。 可以通过提交一个 _cat/health 请求来检查进度:

    GET _cat/health?v

    等待 status 列变成 green。 一旦节点变成 green,所有主分片和副本分片都已分配。

    在滚动升级期间,分配给运行新版本的节点的主分片不能将其副本分配给运行旧版本的节点。 新版本可能具有旧版本不理解的不同的数据格式。

    如果无法将副本分片分配给另一个节点(集群中只有一个升级后的节点),副本分片将保持未分配状态,状态保持 yellow

    在这种情况下,一旦没有初始化或重定位中的分片,就可以继续了(检查 initrelo列)。

    一旦另一个节点升级完成,就可以分配副本,并且状态将变为 green

    同步刷新(sync-flushed) 的分片可能需要更长时间才能恢复。 可以通过提交一个 _cat/recovery 请求来监控单个分片的恢复状态:

    GET _cat/recovery

    如果升级前停止了索引,恢复完成后立即恢复索引是安全的。

  11. 重复操作

    当节点恢复且集群稳定后,对每个需要更新的节点重复这些步骤。 可以使用 _cat/health 请求来监视集群的运行状况:

    GET /_cat/health?v

    可以使用 _cat/nodes 请求检查哪些节点已经升级:

    GET /_cat/nodes?h=ip,name,version&v
  12. 重新启动机器学习作业。

    如果你暂时停止了与机器学习作业相关联的任务,请使用 设置升级模式(set upgrade mode) API 将它们恢复到活动状态:

    POST _ml/set_upgrade_mode?enabled=false

    如果在升级前关闭了所有机器学习作业,请打开作业并从 Kibana 启动数据馈送,或者使用 open jobsstart datafeed API。

在滚动升级期间,集群继续正常运行。 但是,在集群中的所有节点都完成升级之前,任何新功能都将被禁用或以向后兼容的模式运行。 升级完成且所有节点都运行新版本后,新功能便可投入使用。 一旦发生这种情况,就没有办法回到向后兼容的模式。 不允许运行以前主要版本的节点加入完全更新的集群。

如果在升级过程中出现网络故障,将所有剩余的旧节点与集群隔离,必须使旧节点脱机并升级,以使它们能够重新加入集群。

如果在升级过程中一次停止一半或更多符合主节点条件的节点,则集群将变得不可用,这意味着此次升级不再是滚动升级。 如果发生这种情况,你应该升级并重新启动所有停止的符合主节点条件的节点,以允许集群重新形成,就像执行 全集群重启升级 一样。 可能还需要升级所有剩余的旧节点,然后它们才能在集群重组后加入集群。