Es之脑裂

"两个 Master 同时发号施令 ------ 比宕机可怕一万倍,因为系统'活着但疯了'。"

脑裂(Split Brain)------ 数据永久错乱

不是"查不到",是"查出鬼":瑟瑟发抖

场景 1 :同一个 doc_id=1,两次查询返回不同内容:这放到sql上叫什么?大声说出来!

复制代码
// 第一次
{ "_id": "1", "_version": 3, "name": "Alice" }
// 第二次(刷新后)
{ "_id": "1", "_version": 2, "name": "Bob" }  // ← 版本号倒退!

场景 2:索引元数据冲突

  • 节点 A 认为索引有 5 个分片
  • 节点 B 认为索引有 3 个分片
  • GET _cluster/state 返回混乱结构

场景 3:写入成功但数据丢失

  • 客户端收到 201 Created
  • 但稍后查询发现文档不存在

根因:Master 选举失控(6.x 及以下)

分布式共识基础
  • ES 集群必须有且仅有一个 Master 节点(负责元数据变更:创建索引、分配分片等)
  • 选举规则(6.x):多数派(quorum)同意即可当选
脑裂触发条件
  1. 集群有 3 个 master-eligible 节点:M1, M2, M3
  2. 网络分区:M1M2,M3 断连
  3. 未设置 discovery.zen.minimum_master_nodes
    • M1 认为自己是唯一节点 → 自选为 Master
    • M2,M3 形成多数派 → 选 M2 为 Master
为什么数据会错乱?
  • M1 接受写入 → 更新分片 A
  • M2 接受写入 → 更新分片 B
  • 网络恢复后,ES 不会合并数据,而是随机保留一个状态
  • 丢失的数据永远找不回来

🔥 关键点脑裂期间的写入 = 数据黑洞

🛠️ 解决方案:两代防御体系

方案 1:升级到 7.x+(推荐!)其实8+更好
  • 7.0+ 移除了 minimum_master_nodes
  • 引入 基于 Raft 的新协调层(Coordination Module)
  • 自动防脑裂 :要求 法定人数(quorum)写入日志成功才提交
  • 即使网络分区,最多只有一个 Master 能接受写入
方案 2:6.x 必须手动配置(如无法升级)
复制代码
# elasticsearch.yml(所有 master-eligible 节点必须一致!)
node.master: true
node.data: false

# ⚠️ 关键配置:法定人数 = N/2 + 1
discovery.zen.minimum_master_nodes: 2   # 3 节点集群
# discovery.zen.minimum_master_nodes: 3 # 5 节点集群

错误配置示例

  • 3 节点设 minimum_master_nodes: 1 → 等于没设!
  • 节点配置不一致 → 选举失败

🔍 如何检测是否已脑裂?

方法 1:检查 Master 节点数量
复制代码
# 正常:只返回 1 个
GET _cat/nodes?h=name,master&v | grep "*"

# 脑裂:返回多个带 "*" 的节点
方法 2:检查集群状态
复制代码
GET _cluster/health
{
  "status": "red",
  "number_of_nodes": 5,
  "number_of_data_nodes": 3,
  "active_primary_shards": 10,
  "relocating_shards": 0,
  "initializing_shards": 5,   // ← 异常初始化
  "unassigned_shards": 10     // ← 大量未分配
}
方法 3:监控日志关键词
  • master_left
  • zen-disco-elected-as-master(短时间内多次出现)
  • failed to send join request to master

脑裂后如何恢复?(痛苦但必要)

⚠️ 警告:无完美方案!数据可能永久丢失。

步骤 1:立即停止所有写入
  • 防止进一步污染数据
步骤 2:确定"权威"子集群
  • 选择包含 更多数据节点最新数据 的分区
  • 通过 GET /_all/_search?size=1&sort=@timestamp:desc 对比
步骤 3:强制重启非权威集群
  • 停掉"错误"的 Master 节点
  • 清空其数据目录(path.data
  • 重新加入集群(作为新节点)
步骤 4:重建索引(最安全)
  • 从备份恢复
  • 或从源系统重放数据

现实脑裂后的集群不应信任,建议重建。

防脑裂配置模板6.x

复制代码
# ========================
# 集群基础信息
# ========================
cluster.name: prod-es-cluster          # 所有节点必须一致

# ========================
# 节点角色(Master 专用)
# ========================
node.name: es-master-01                # 每个节点唯一
node.master: true                      # 可参与 Master 选举
node.data: false                       # 不存数据(专用 Master)
node.ingest: false                     # 不做预处理

# ========================
# 网络绑定
# ========================
network.host: 0.0.0.0                  # 绑定所有接口(生产建议指定内网IP)
http.port: 9200
transport.port: 9300                   # 节点间通信端口

# ========================
# 脑裂防护核心配置(Zen Discovery)
# ========================
# 初始 Master 候选列表(所有 Master 节点 IP 或主机名)
discovery.zen.ping.unicast.hosts:
  - "10.0.1.10:9300"   # es-master-01
  - "10.0.1.11:9300"   # es-master-02
  - "10.0.1.12:9300"   # es-master-03

# 法定人数 = N/2 + 1 → 3 节点必须设为 2
# 作用:选举时至少 2 个节点同意才能选出 Master
discovery.zen.minimum_master_nodes: 2

# 超时设置(避免因短暂网络抖动误判)
discovery.zen.ping_timeout: 30s
discovery.zen.fd.ping_timeout: 30s

# ========================
# 安全加固(可选但推荐)
# ========================
# 防止非集群节点加入
discovery.zen.no_master_block: write    # 无 Master 时只阻塞写入(默认)

# ========================
# 内存与线程(Master 节点轻量)
# ========================
indices.memory.index_buffer_size: "10%"
thread_pool:
  management.size: 2                    # Master 节点管理线程少即可

# ========================
# 日志级别(便于排查选举问题)
# ========================
logger.discovery: DEBUG                # 关键!记录选举过程
配置项 为什么重要
discovery.zen.minimum_master_zones: 2 防脑裂核心:3 节点下,单节点无法自选为 Master
unicast.hosts 列出所有 Master 避免通过广播发现非预期节点
no_master_block: write 无 Master 时允许读,提升可用性
logger.discovery: DEBUG 出现选举异常时,日志会记录详细过程

选举对照

特性 Elasticsearch 6.x(Zen Discovery) Elasticsearch 7.x+(Coordination Layer)
共识算法 自定义多数派投票 基于 Raft 的改进版
脑裂防护 依赖手动配置 minimum_master_nodes 自动内置,无需配置
法定人数计算 用户指定 N/2+1 自动:(master_eligible_nodes / 2) + 1
配置项 discovery.zen.minimum_master_nodes 已移除(设置会报错)
选举日志 无持久化日志 持久化到 data/<cluster_uuid>/nodes/0/_state/
网络分区行为 可能多主(若配置错误) 最多一个 Master 可接受写入
升级兼容性 --- 从 6.x 升级需先正确配置 minimum_master_nodes
官方态度 已废弃 唯一支持的协调机制

🔍 关键差异详解

1. Raft 的"持久化日志"机制
  • 每次 Master 变更都写入 本地磁盘日志
  • 新节点加入时,必须同步完整日志才能参与选举
  • 杜绝了"失联节点回归后自立为王"
2. 自动法定人数
  • 7.x+ 启动时自动计算:quorum = (number_of_master_eligible_nodes // 2) + 1
  • 用户无法覆盖,从根本上消除配置错误
3. 写入安全性
  • 7.x+ 要求:元数据变更必须被 quorum 节点持久化成功
  • 6.x:仅需 quorum 节点"收到请求",不保证落盘
版本 行动
ES 7.x+ ✅ 默认安全,无需额外配置 ✅ 确保至少 3 个 master-eligible 节点
ES 6.x 🔒 必须设置 minimum_master_nodes = N/2 + 1 🔒 所有 Master 节点配置完全一致 🚨 尽快升级到 7.x+ 然后你会发现7+ 让你升级8+

朋友们,这升级是真的有用

相关推荐
搞科研的小刘选手6 小时前
【EI稳定检索会议】第七届计算机信息和大数据应用国际学术会议(CIBDA 2026)
大数据·acm·学术会议·计算机工程·计算机信息·大数据应用·信息与技术
成长之路5146 小时前
【数据集】地级市公共安全基建省内横向压力(2015-2025)
大数据
YangYang9YangYan7 小时前
2026中专大数据专业学习指南
大数据
yumgpkpm7 小时前
预测:2026年大数据软件+AI大模型的发展趋势
大数据·人工智能·算法·zookeeper·kafka·开源·cloudera
无级程序员7 小时前
大数据Hive之拉链表增量取数合并设计(主表加历史表合并成拉链表)
大数据·hive·hadoop
py小王子8 小时前
dy评论数据爬取实战:基于DrissionPage的自动化采集方案
大数据·开发语言·python·毕业设计
龙山云仓8 小时前
MES系统超融合架构
大数据·数据库·人工智能·sql·机器学习·架构·全文检索
无忧智库9 小时前
某市“十五五“知识产权大数据监管平台与全链条保护系统建设方案深度解读(WORD)
大数据·人工智能
综合热讯9 小时前
股票融资融券交易时间限制一览与制度说明
大数据·人工智能·区块链