「集群分片与高可用架构」

深入讲解 Elasticsearch 集群架构:master 与 data 节点角色、分片副本分配原理、脑裂与 quorum 选举、跨机房高可用设计,以及磁盘水印与集群健康监控实践经验。

单节点 Elasticsearch 无法支撑生产流量,但把节点连成集群只是第一步,分片怎么分配、副本怎么放、脑裂怎么防才是高可用的关键。本文从节点角色、分片分配、quorum 选举、水印机制到跨机房架构,梳理一个稳定集群的全貌。

1. 集群节点角色

1.1 角色的划分

ES 7 之后通过 node.roles 显式声明节点职责,避免一个节点既是 master 又是 data 的隐性风险。

角色职责典型数量配置示例
master集群元数据、分片分配决策3(奇数)master
data数据存储与查询执行按容量规划data
ingest管道预处理0-Ningest
ml机器学习作业按需ml
coordinating路由与聚合转发2+空 roles
# elasticsearch.yml 数据节点
node.name: es-data-01
node.roles: [ data, ingest ]
cluster.name: production-cluster
network.host: 0.0.0.0
discovery.seed_hosts: ["es-master-01:9300", "es-master-02:9300", "es-master-03:9300"]

1.2 为什么需要专用主节点

数据节点的堆内存主要用于存储与查询,而 master 要维护全局元数据与分片分配状态。让大内存节点兼任 master,JVM GC 抖动会拖慢集群级的决策,因此生产环境至少部署 3 个专用 master 节点。

# 专用主节点,不存数据
node.name: es-master-01
node.roles: [ master ]

1.3 协调节点与路由

coordinating 节点接收客户端请求,解析后转发到各分片,再合并结果返回。它不做数据存储,适合承载高并发查询入口。集群可以复用 data 节点做协调,规模大时建议独立 2-3 个轻量协调节点。

2. 分片与副本

2.1 主分片与副本分片

每个索引由若干主分片(primary shard)构成,每个主分片可以有零到多个副本分片(replica shard)。副本承载读流量,并在主分片故障时晋升为新的主分片。

索引 blog(3 主分片 × 1 副本 = 6 个分片)
┌─────────────┬─────────────┬─────────────┐
│ primary 0   │ primary 1   │ primary 2   │  → 节点 A
├─────────────┼─────────────┼─────────────┤
│ replica 0   │ replica 1   │ replica 2   │  → 节点 B
└─────────────┴─────────────┴─────────────┘
副本不会与对应主分片落在同一节点

2.2 主分片数不可变

索引创建后主分片数无法修改,这是 ES 与分库分表最大的不同。主分片数决定了数据分布粒度,副本数可以随时调整。

# 创建索引:3 主分片 1 副本
curl -X PUT 'http://localhost:9200/blog?pretty' \
  -H 'Content-Type: application/json' \
  -d '{"settings": {"number_of_shards": 3, "number_of_replicas": 1}}'

# 调整副本数到 2
curl -X PUT 'http://localhost:9200/blog/_settings?pretty' \
  -H 'Content-Type: application/json' \
  -d '{"number_of_replicas": 2}'

2.3 分片数规划

场景建议主分片数说明
测试/日志1-3单分片免路由开销
中小业务数据量 / 单分片 30GB分片过大影响恢复
大吞吐写入节点数 × 1-3摊平写入热点
超大规模节点数 × 2-4分片过多拖慢协调节点

经验公式:单分片数据量控制在 30-50GB,分片总数不超过节点数 × 10,避免协调节点聚合开销过大。分片太少则单分片过大、恢复慢;太多则集群状态臃肿。

3. 分片分配机制

3.1 分配逻辑

master 节点维护分片分配器,将未分配分片按策略放置到合适节点,考虑磁盘余量、节点属性、过滤器与并发限制。

curl -s 'http://localhost:9200/_cluster/allocation/explain?pretty' \
  -H 'Content-Type: application/json' \
  -d '{"index": "blog", "shard": 0, "primary": true}'

_allocation/explain API 是排查分片未分配的利器,会返回当前节点与候选节点的决策原因。

3.2 分片分配感知

跨机房或异构节点场景,用 allocation awareness 让副本与主分片分布在不同的属性域。

# elasticsearch.yml
cluster.routing.allocation.awareness.attributes: rack_id
node.attr.rack_id: rack-a
curl -X PUT 'http://localhost:9200/_cluster/settings?pretty' \
  -H 'Content-Type: application/json' \
  -d '{
    "persistent": {
      "cluster.routing.allocation.awareness.attributes": "rack_id"
    }
  }'

此时主分片落在 rack-a,副本会优先落到 rack-b,实现机架级容错。

3.3 分片分配过滤与平衡

curl -X PUT 'http://localhost:9200/_cluster/settings?pretty' \
  -H 'Content-Type: application/json' \
  -d '{
    "persistent": {
      "cluster.routing.allocation.exclude._name": "es-data-03"
    }
  }'

滚动升级或下线节点前,用 exclude 过滤逐节点排空分片,避免大范围移动引发 IO 风暴。平衡参数 cluster.routing.allocation.balance.shard 可调整分片数量均衡与磁盘均衡的权重。

3.4 延迟分配与恢复

{
  "persistent": {
    "cluster.routing.allocation.node_concurrent_recoveries": 4,
    "cluster.routing.allocation.node_concurrent_incoming_recoveries": 2
  }
}

节点重启后分片恢复默认有 1 分钟延迟,避免节点短暂抖动触发全量恢复。并发恢复数过高会抢占查询 IO,应根据磁盘性能调节。

4. 脑裂与选举机制

4.1 什么是脑裂

网络分区时,集群可能被拆成多个互相不可见的小集群,各自认为自己是主,同时接受写入,导致数据分片状态分裂。ES 7 之前用 discovery.zen.minimum_master_nodes 防脑裂。

4.2 现代选举与 quorum

ES 7 之后引入 cluster.initial_master_nodes 与基于投票的选举机制,主节点需要获得严格多数(quorum)选票才能当选。

master-eligible 节点数 = 3
quorum = 节点数 / 2 + 1 = 2

网络分区:3 节点被拆成 2 + 1
  分组 2:满足 quorum(2 ≥ 2),可产生主节点
  分组 1:不满足 quorum(1 < 2),降级为只读
# elasticsearch.yml 每个 master-eligible 节点
discovery.seed_hosts: ["es-master-01:9300", "es-master-02:9300", "es-master-03:9300"]
cluster.initial_master_nodes: ["es-master-01", "es-master-02", "es-master-03"]

4.3 部署奇数个主节点

主节点数quorum可容忍故障数
110
220(防止对半分)
321
532

必须部署奇数个 master-eligible 节点,偶数个会在 2+2 分区时无法达成一致。生产至少 3 个,大型集群 5 个。

5. 高可用架构

5.1 跨机房与同城双活

同城双机房 + 三 master 节点是最常见的生产布局:master 分散在两个机房,第三个放在仲裁位置(如独立机房或云间)。

机房 A:master-01 + data 节点组 A
机房 B:master-02 + data 节点组 B
机房 C(仲裁):master-03(仅 master 角色)

任一机房整体故障,剩余节点仍 ≥ quorum,集群可用。

5.2 冷热分离架构

{
  "persistent": {
    "cluster.routing.allocation.awareness.attributes": "box_type",
    "cluster.routing.allocation.awareness.force.box_type.values": ["hot", "warm"]
  }
}

配合 node.attr.box_type,把热数据分片放到 SSD 节点、温数据放到大容量节点,再结合 ILM 生命周期实现数据分层。详细策略见《部署运维与备份恢复》。

5.3 节点故障恢复流程

节点宕机
   │
   ▼
master 检测到节点离线(默认 30s 超时)
   │
   ▼
副本分片被提升为主分片(无数据丢失)
   │
   ▼
缺失的副本被分配到其他节点重建(网络复制)
   │
   ▼
集群恢复 green

保证高可用的前提是每个主分片都有副本,且副本不与主分片同机。单副本下丢失一个数据节点可能丢数据,关键索引建议副本 ≥ 2。

6. 磁盘水印与只读保护

6.1 三种水印

水印默认阈值触发动作
low watermark85%不再向该节点分配新分片
high watermark90%尝试把分片移走
flood stage95%强制所有索引只读
{
  "persistent": {
    "cluster.routing.allocation.disk.watermark.low": "80%",
    "cluster.routing.allocation.disk.watermark.high": "85%",
    "cluster.routing.allocation.disk.watermark.flood_stage": "90%"
  }
}

6.2 flood stage 的处置

达到 flood stage 后索引被置为只读,写入报 cluster_block_exception。处理步骤是先释放空间,再手动解除只读。

# 查看被锁索引
curl -s 'http://localhost:9200/_cat/indices?s=store.size:desc' | head

# 清理或扩容后解除只读
curl -X PUT 'http://localhost:9200/*/_settings?expand_wildcards=all' \
  -H 'Content-Type: application/json' \
  -d '{"index.blocks.read_only_allow_delete": null}'

6.3 磁盘规划经验

日志类索引建议按时序切分并配置 ILM 删除,避免无限增长触发 flood stage。主分片与副本分布在不同节点,同一分片副本不要落在同一物理磁盘。

7. 集群监控

7.1 CAT API 快速体检

curl -s 'http://localhost:9200/_cat/health?v'
curl -s 'http://localhost:9200/_cat/nodes?v'
curl -s 'http://localhost:9200/_cat/shards?v&s=prirep'
curl -s 'http://localhost:9200/_cat/allocation?v'
状态含义
green所有主分片与副本已分配
yellow主分片已分配,副本缺失
red存在未分配的主分片,有数据风险

7.2 未分配分片排查

# 查看未分配原因
curl -s 'http://localhost:9200/_cat/shards?v' | grep UNASSIGNED

# 详细解释
curl -s 'http://localhost:9200/_cluster/allocation/explain?pretty' \
  -H 'Content-Type: application/json' \
  -d '{"index": "blog", "shard": 2, "primary": false}'

常见原因包括节点磁盘高水位、分片数量超限、副本数设置、属性感知不匹配。修复分配后执行 _cluster/reroute 触发重分配。

7.3 集群状态缓存与慢日志

curl -s 'http://localhost:9200/_cluster/settings?pretty' | jq '.persistent'

集群状态(cluster state)每次变更全量广播,频繁创建索引会拖慢所有节点。查询慢日志与索引慢日志阈值应开启,帮助定位慢分片。

8. 总结

环节要点
节点角色master 奇数个专用节点,data 按容量规划,coordinating 承载入口
分片规划主分片数创建后不可变,单分片 30-50GB,副本数可调
分配机制awareness 实现机架/机房容错,explain API 排查未分配
防脑裂quorum 选举,master-eligible 必须奇数个
高可用副本 ≥ 1 且不与主分片同机,跨机房需仲裁节点
磁盘水印low/high/flood 三级,95% 强制只读
监控CAT API 看健康,allocation explain 看原因
恢复节点宕机副本晋升,并发恢复数限流防 IO 风暴

集群高可用的核心是分片有副本、选举有 quorum、磁盘有水位。把这些机制理解透,才能应对节点宕机、机房故障与磁盘打满三类最常见事故。分片内部的写入与查询路径可阅读《性能调优与缓存策略》,索引分层运维见《部署运维与备份恢复》。

延伸阅读

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「elasticsearch」更多文章

  1. 「搜索服务架构:从索引到容错」
  2. 「安全加固与访问控制:从角色到审计」
  3. 「地理空间搜索:从坐标到地图」