跳到主要内容

集群管理

Elasticsearch 集群是由一个或多个节点组成的分布式系统,共同存储数据并提供搜索服务。本章将介绍集群的架构设计、配置管理和运维技巧,帮助你构建和管理稳定高效的 Elasticsearch 集群。

集群架构基础

节点类型

Elasticsearch 集群中的节点可以承担不同的角色,每种角色负责特定的功能:

节点类型配置职责
Masternode.roles: [master]管理集群状态、创建/删除索引、分配分片
Datanode.roles: [data]存储数据、执行搜索和聚合
Ingestnode.roles: [ingest]预处理管道,转换文档
Coordinatingnode.roles: []处理请求、路由分发、结果合并
MLnode.roles: [ml]机器学习任务处理

节点角色组合:

节点可以同时拥有多个角色。例如,小型集群中节点通常同时是 Master 和 Data 节点:

node.roles: [master, data]

大型生产集群通常会将角色分离,实现更好的资源隔离和管理:

# 专用 Master 节点(3 个,避免脑裂)
node.roles: [master]

# 专用 Data 节点(多个,水平扩展)
node.roles: [data]

# 协调节点(处理请求路由)
node.roles: []

集群健康状态

GET /_cluster/health

响应示例:

{
"cluster_name": "my-cluster",
"status": "green",
"number_of_nodes": 3,
"number_of_data_nodes": 2,
"active_primary_shards": 10,
"active_shards": 20,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0
}

状态说明:

状态含义可能原因
green所有分片正常分配集群健康
yellow主分片正常,副本未分配单节点集群、节点故障
red部分主分片未分配节点故障、磁盘问题

集群架构图解

一个典型的三节点集群架构:

┌─────────────────────────────────────────────────────────────┐
│ Elasticsearch 集群 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 节点1 (Master + Data) 节点2 (Master + Data) │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ Master 候选 │ │ Master 候选 │ │
│ │ P0 P1 P2 │ │ P0 P1 P2 │ 主分片 │
│ │ R1 R2 │ │ R0 │ 副本分片 │
│ └─────────────────┘ └─────────────────┘ │
│ │
│ 节点3 (Data only) │
│ ┌─────────────────┐ │
│ │ R0 R1 R2 │ 只存储副本,不参与选主 │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

P0, P1, P2 = 主分片 (Primary Shard)
R0, R1, R2 = 副本分片 (Replica Shard)

集群配置

基本配置

每个节点都需要配置 elasticsearch.yml 文件:

# 集群名称(同一集群必须相同)
cluster.name: my-application

# 节点名称(同一集群必须唯一)
node.name: node-1

# 节点角色
node.roles: [master, data]

# 网络配置
network.host: 0.0.0.0
http.port: 9200
transport.port: 9300

# 发现配置
discovery.seed_hosts: ["node-1", "node-2", "node-3"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]

# 内存锁定
bootstrap.memory_lock: true

配置详解:

配置项说明
cluster.name集群名称,用于节点发现和隔离
node.name节点名称,默认自动生成
network.host绑定的网络接口,0.0.0.0 表示所有接口
discovery.seed_hosts种子节点列表,用于发现其他节点
cluster.initial_master_nodes初始 Master 候选列表,首次启动时使用

三节点集群配置示例

节点 1 配置(Master + Data):

cluster.name: my-cluster
node.name: node-1
node.roles: [master, data]

network.host: 192.168.1.10
http.port: 9200
transport.port: 9300

discovery.seed_hosts: ["192.168.1.10", "192.168.1.11", "192.168.1.12"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]

path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

节点 2 配置(Master + Data):

cluster.name: my-cluster
node.name: node-2
node.roles: [master, data]

network.host: 192.168.1.11
http.port: 9200
transport.port: 9300

discovery.seed_hosts: ["192.168.1.10", "192.168.1.11", "192.168.1.12"]
cluster.initial_master_nodes: ["node-1", "node-2", "node-3"]

path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

节点 3 配置(Data only):

cluster.name: my-cluster
node.name: node-3
node.roles: [data] # 只作为数据节点

network.host: 192.168.1.12
http.port: 9200
transport.port: 9300

discovery.seed_hosts: ["192.168.1.10", "192.168.1.11", "192.168.1.12"]

path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch

避免脑裂

脑裂(Split Brain)是指集群被网络分区后,两个分区各自选举出 Master,导致数据不一致。预防措施:

1. 设置最小 Master 数量

# 在 Elasticsearch 7.x+ 中,通过投票配置自动管理
# 但仍建议保持奇数个 Master 候选节点(3、5、7)

2. 自动处理投票配置排除

# 查看当前投票配置
GET /_cluster/state?filter_path=metadata.cluster_coordination

# 排除故障节点
POST /_cluster/voting_config_exclusions/node-3

# 清除排除配置
DELETE /_cluster/voting_config_exclusions

分片管理

分片分配设置

# 查看分配设置
GET /_cluster/settings?include_defaults=true&filter_path=**.allocation.*

# 设置分片分配
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "all",
"cluster.routing.allocation.cluster_concurrent_rebalance": 2,
"cluster.routing.allocation.node_concurrent_recoveries": 2,
"cluster.routing.allocation.disk.watermark.low": "85%",
"cluster.routing.allocation.disk.watermark.high": "90%",
"cluster.routing.allocation.disk.watermark.flood_stage": "95%"
}
}

分配设置说明:

设置说明
cluster.routing.allocation.enable分配策略:all、primaries、new_primaries、none
cluster_concurrent_rebalance集群级别并发重平衡数
node_concurrent_recoveries节点级别并发恢复数
disk.watermark.low低水位,超过后不再向该节点分配新分片
disk.watermark.high高水位,超过后尝试迁移分片
disk.watermark.flood_stage洪水水位,超过后将索引设为只读

分片分配过滤

可以将特定索引分配到特定节点:

# 节点属性配置(elasticsearch.yml)
node.attr.rack: rack1

# 分配规则
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.include._attr": "rack:rack1",
"cluster.routing.allocation.exclude._name": "node-3"
}
}

手动移动分片

POST /_cluster/reroute
{
"commands": [
{
"move": {
"index": "articles",
"shard": 0,
"from_node": "node-1",
"to_node": "node-2"
}
}
]
}

分片重平衡控制

PUT /_cluster/settings
{
"persistent": {
"cluster.routing.rebalance.enable": "all",
"cluster.routing.balance.shard": 0.45,
"cluster.routing.balance.index": 0.55,
"cluster.routing.balance.threshold": 1.0
}
}

集群监控

集群状态 API

# 集群健康
GET /_cluster/health?pretty

# 集群状态
GET /_cluster/state?pretty

# 集群统计
GET /_cluster/stats?pretty

# 节点统计
GET /_nodes/stats?pretty

Cat API

Cat API 提供简洁的文本输出,适合命令行查看:

# 查看节点
GET /_cat/nodes?v

# 查看分片
GET /_cat/shards?v

# 查看索引
GET /_cat/indices?v

# 查看分配情况
GET /_cat/allocation?v

# 查看恢复状态
GET /_cat/recovery?v

# 查看线程池
GET /_cat/thread_pool?v

# 查看主节点
GET /_cat/master?v

常用查询参数:

  • v:显示列名
  • h:指定显示的列
  • s:排序
  • format=json:JSON 格式输出
# 示例:查看节点的堆内存使用率
GET /_cat/nodes?v&h=name,heap.percent,ram.percent,cpu

# 示例:按文档数排序索引
GET /_cat/indices?v&s=docs.count:desc

关键监控指标

1. JVM 指标

GET /_nodes/stats?filter_path=nodes.*.jvm

关注:

  • heap_used_percent:堆内存使用率,建议不超过 75%
  • gc:垃圾回收频率和时间

2. 线程池指标

GET /_nodes/stats?filter_path=nodes.*.thread_pool

关注:

  • searchwrite 队列情况
  • rejected 拒绝数量

3. 磁盘指标

GET /_cat/allocation?v

4. 索引性能

GET /_nodes/stats?filter_path=nodes.*.indices.indexing

故障处理

节点故障

当节点故障时,集群会自动处理:

# 查看未分配的分片
GET /_cat/shards?v&s=state

# 解释分片未分配原因
GET /_cluster/allocation/explain
{
"index": "articles",
"shard": 0,
"primary": true
}

# 重试分配
POST /_cluster/reroute?retry_failed=true

常见未分配原因:

原因解决方法
NODE_LEFT节点离线,等待恢复或添加新节点
ALLOCATION_FAILED分配失败,查看日志,重试分配
DECIDERS_NO分配器拒绝,检查配置限制
DISK_WATERMARK磁盘空间不足,清理或扩容

集群重启

滚动重启过程:

# 步骤1:禁用分片分配
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "primaries"
}
}

# 步骤2:执行同步刷新
POST /_flush/synced

# 步骤3:停止节点(逐个进行)
systemctl stop elasticsearch

# 步骤4:维护完成后启动节点
systemctl start elasticsearch

# 步骤5:等待节点加入集群
GET /_cat/health

# 步骤6:重复步骤3-5,处理所有节点

# 步骤7:恢复分片分配
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "all"
}
}

数据恢复

# 查看恢复进度
GET /_cat/recovery?v&active_only=true

# 取消恢复
POST /_cluster/reroute
{
"commands": [
{
"cancel": {
"index": "articles",
"shard": 0,
"node": "node-1"
}
}
]
}

快照和恢复

创建仓库

# 创建文件系统仓库
PUT /_snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/mount/backups/my_backup",
"compress": true
}
}

# 创建 S3 仓库
PUT /_snapshot/s3_backup
{
"type": "s3",
"settings": {
"bucket": "my-bucket",
"region": "us-east-1",
"base_path": "elasticsearch/snapshots"
}
}

# 创建 Azure 仓库
PUT /_snapshot/azure_backup
{
"type": "azure",
"settings": {
"container": "backup-container",
"base_path": "elasticsearch"
}
}

创建快照

# 快照所有索引
PUT /_snapshot/my_backup/snapshot_1

# 快照指定索引
PUT /_snapshot/my_backup/snapshot_2
{
"indices": "articles,products",
"ignore_unavailable": true,
"include_global_state": false
}

# 查看快照进度
GET /_snapshot/my_backup/snapshot_1/_status

# 查看所有快照
GET /_snapshot/my_backup/_all

恢复快照

# 恢复所有索引
POST /_snapshot/my_backup/snapshot_1/_restore

# 恢复指定索引
POST /_snapshot/my_backup/snapshot_1/_restore
{
"indices": "articles",
"ignore_unavailable": true,
"include_global_state": false,
"rename_pattern": "(.+)",
"rename_replacement": "restored_$1"
}

参数说明:

  • rename_pattern:匹配索引名的正则表达式
  • rename_replacement:替换后的索引名
  • include_global_state:是否恢复集群状态(模板、设置等)

快照生命周期管理

# 创建快照生命周期策略
PUT /_slm/policy/nightly-snapshots
{
"schedule": "0 30 1 * * ?", # 每天凌晨 1:30
"name": "<nightly-snap-{now/d}>",
"repository": "my_backup",
"config": {
"indices": ["*"],
"ignore_unavailable": true,
"include_global_state": false
},
"retention": {
"expire_after": "30d",
"min_count": 5,
"max_count": 50
}
}

小结

本章我们深入学习了 Elasticsearch 集群管理的核心知识:

  1. 集群架构:节点类型、角色配置、集群健康状态
  2. 集群配置:基本配置、多节点部署、避免脑裂
  3. 分片管理:分配设置、分配过滤、手动移动分片
  4. 集群监控:健康 API、Cat API、关键监控指标
  5. 故障处理:节点故障、滚动重启、数据恢复
  6. 快照恢复:仓库创建、快照管理、生命周期策略

练习

  1. 配置一个三节点的 Elasticsearch 集群,包含 2 个 Master+Data 节点和 1 个 Data 节点
  2. 使用 Cat API 监控集群状态,重点关注 JVM、线程池、磁盘指标
  3. 配置快照仓库,创建一个包含所有索引的快照
  4. 模拟节点故障,观察集群自动恢复过程

参考资料