📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

配置项作用 #

discovery.zen.unsafe_rolling_upgrades_enabled 配置项用于控制在从 Zen1 到 Zen2 的滚动升级过程中,是否自动引导 Zen2 节点形成新的集群配置

当集群中最后一个 Zen1 节点离开时,如果启用了此功能,系统会自动配置投票(voting configuration)以确保集群继续运行。

配置项属性 #

  • 配置路径: discovery.zen.unsafe_rolling_upgrades_enabled
  • 数据类型: Boolean(布尔值)
  • 默认值: true
  • 是否可选: 是
  • 作用域: NodeScope(节点级别)
  • 弃用状态: ⚠️ 已弃用

配置项详解 #

工作机制 #

滚动升级场景

升级前(Zen1 集群):
[node1-Zen1-master] ←→ [node2-Zen1-master] ←→ [node3-Zen1-data]

滚动升级开始:
[node1-Zen2-master] ←→ [node2-Zen1-master] ←→ [node3-Zen1-data]
     │
     ↓ 混合模式运行

[node1-Zen2-master] ←→ [node2-Zen2-master] ←→ [node3-Zen1-data]
     │
     ↓

[node1-Zen2-master] ←→ [node2-Zen2-master] ←→ [node3-Zen2-data]
     │
     ↓ 全部升级完成

自动引导行为 #

unsafe_rolling_upgrades_enabled = true (默认):

最后一个 Zen1 节点离开
    │
    ↓
系统检测到只剩 Zen2 节点
    │
    ↓
自动创建新的投票配置
    │
    ↓
引导 Zen2 节点形成新集群 ✅
    │
    ↓
集群继续正常运行


unsafe_rolling_upgrades_enabled = false:

最后一个 Zen1 节点离开
    │
    ↓
系统检测到只剩 Zen2 节点
    │
    ↓
等待旧的 Zen1 节点返回
    │
    ↓
集群无法形成新的配置 ❌
    │
    ↓
需要手动干预

代码逻辑 #

// DiscoveryUpgradeService.java 中的核心逻辑

if (enableUnsafeBootstrappingOnUpgrade && lastKnownLeader.isPresent()) {
    // 启用不安全引导
    joiningRound = new JoiningRound(
        true,  // 尝试自动引导
        minimumMasterNodes,
        knownMasterNodeIds
    );
}

// 检查是否可以引导
private boolean canBootstrap(Set<DiscoveryNode> discoveryNodes) {
    return upgrading &&
           minimumMasterNodes <= discoveryNodes.stream()
               .filter(DiscoveryNode::isMasterNode)
               .count();
}

配置建议 #

⚠️ 重要提示 #

此配置项已被标记为弃用,主要用于 Zen1 到 Zen2 的版本迁移。

开发/测试环境 #

discovery.zen.unsafe_rolling_upgrades_enabled: true

建议: 保持默认值 true。简化升级测试流程。

生产环境 #

discovery.zen.unsafe_rolling_upgrades_enabled: false

建议: 设置为 false。由管理员手动控制滚动升级过程,确保集群稳定性。

手动升级控制 #

discovery.zen.unsafe_rolling_upgrades_enabled: false

建议: 在需要精确控制升级过程的场景使用。

代码示例 #

easysearch.yml 配置(已弃用) #

discovery:
  zen:
    unsafe_rolling_upgrades_enabled: true  # 默认值

生产环境推荐配置 #

discovery:
  zen:
    unsafe_rolling_upgrades_enabled: false  # 手动控制升级

配合其他升级相关配置 #

discovery:
  zen:
    minimum_master_nodes: 2
    unsafe_rolling_upgrades_enabled: false

cluster:
  upgrade:
    enabled: true

相关配置 #

配置项作用默认值
discovery.zen.unsafe_rolling_upgrades_enabled自动引导开关true
discovery.zen.minimum_master_nodes最少主节点数量-
cluster.initial_master_nodes初始主节点列表-

升级过程分析 #

Zen1 到 Zen2 滚动升级 #

步骤 1: 升级第一个节点
[node1-Zen2] ──→ 尝试加入 ──→ [node2-Zen1, node3-Zen1]
                            ↓
                       混合模式运行

步骤 2: 升级第二个节点
[node1-Zen2, node2-Zen2] ──→ 继续 ──→ [node3-Zen1]
                                    ↓
                               混合模式运行

步骤 3: 升级最后一个节点
[node1-Zen2, node2-Zen2, node3-Zen2]
    │
    ↓
最后 Zen1 节点离开
    │
    ├──────── unsafe_rolling_upgrades_enabled = true
    │                  ↓
    │            自动引导 Zen2 节点 ✅
    │                  ↓
    │            创建新的投票配置
    │
    └──────── unsafe_rolling_upgrades_enabled = false
                       ↓
                 等待人工干预 ⚠️

安全考虑 #

为什么称为"不安全"?

自动引导的问题:
1. 没有管理员确认
2. 自动改变投票配置
3. 可能导致脑裂风险
4. 可能丢失数据一致性

手动引导的优势:
1. 管理员确认集群状态
2. 显式配置投票节点
3. 确保数据一致性
4. 可控的升级过程

使用场景 #

推荐启用的场景 #

  • 开发/测试环境: 简化升级测试
  • 小型集群: 集群规模小,风险可控
  • 快速迭代: 需要快速验证升级

推荐禁用的场景 #

  • 生产环境: 需要确保数据一致性
  • 大规模集群: 集群节点多,风险高
  • 关键业务: 不能接受数据丢失
  • 合规要求: 需要人工确认关键操作

手动升级最佳实践 #

推荐的滚动升级流程

1. 准备阶段
   - 备份数据
   - 检查集群健康状态
   - 设置 unsafe_rolling_upgrades_enabled: false

2. 逐个节点升级
   for node in nodes:
       a. 禁用分片分配
       b. 等待分片迁移
       c. 停止节点
       d. 升级软件
       e. 启动节点
       f. 验证节点加入
       g. 恢复分片分配

3. 最后节点升级后
   - 手动配置投票配置
   - 验证集群状态
   - 确认所有节点正常运行

4. 清理阶段
   - 移除旧配置
   - 更新文档

注意事项 #

  1. 已弃用: 此配置已被标记为弃用,主要用于 Zen1 到 Zen2 的版本迁移。

  2. 生产环境建议: 在生产环境中,建议设置为 false,由管理员手动控制。

  3. 版本兼容性: 此配置主要用于 Easysearch 7.x 版本升级场景。

  4. 数据一致性: 自动引导可能导致数据不一致,需谨慎使用。

  5. 投票配置: 自动引导会改变集群的投票配置,影响后续的选举行为。

  6. 备份建议: 在滚动升级前,务必进行完整的数据备份。

  7. 监控建议: 升级过程中密切监控集群状态和节点健康。

  8. 回滚准备: 准备回滚方案,以防升级失败。

  9. 文档更新: 升级完成后更新相关文档和配置。

  10. 测试验证: 在生产环境升级前,先在测试环境验证升级流程。