elasticsearch集群
Elasticsearch 集群:分布式架构与管理详解
Elasticsearch 集群是由多个节点(Node)组成的分布式系统,通过协同工作实现高可用、高扩展的数据存储与查询。集群的核心是节点角色分工、分片(Shard)分布式管理及动态配置,以下从架构、监控、配置等方面详细解析。
集群核心组件
节点(Node):集群的基本单元
节点是 Elasticsearch 的运行实例,每个节点通过 cluster.name 标识所属集群。根据功能分工,节点分为以下类型:
| 节点类型 | 作用 | 核心配置(elasticsearch.yml) |
|---|---|---|
| 主节点(Master) | 管理集群元数据(索引创建 / 删除、分片分配),不处理数据读写。 | node.master: true node.data: false node.ingest: false |
| 数据节点(Data) | 存储索引数据,处理索引 / 查询请求,对 CPU、内存、IO 要求高。 | node.master: false node.data: true node.ingest: false |
| 客户端节点(Client) | 作为协调节点(路由请求、合并结果),不存储数据也不参与主节点选举。 | node.master: false node.data: false node.ingest: true |
| 预处理节点(Ingest) | 处理文档预处理(如添加字段、转换格式),可与其他角色叠加。 | node.ingest: true(默认开启) |
分片(Shard):数据分布式存储的核心
分片是索引数据的最小存储单元,分为主分片和副本分片,实现数据分布式存储与高可用:
- 主分片(Primary Shard):
- 负责数据写入,数量在索引创建时指定(
number_of_shards),不可动态修改。 - 作用:通过横向扩展(增加主分片)提升存储容量。
- 负责数据写入,数量在索引创建时指定(
- 副本分片(Replica Shard):
- 主分片的冗余副本,负责分担查询压力,数量可动态调整(
number_of_replicas)。 - 作用:提高查询吞吐量,保障数据可用性(主分片故障时自动升级为新主分片)。
- 主分片的冗余副本,负责分担查询压力,数量可动态调整(
集群监控与管理 API
Elasticsearch 提供丰富的 API 监控集群状态、节点信息及分片分布,核心接口如下:
集群状态监控
(1)查看集群健康状态
GET _cluster/health
返回关键字段:
status:集群健康状态(green:所有分片可用;yellow:主分片可用,副本不全;red:主分片不可用)。active_primary_shards:活跃主分片数;active_shards:活跃总分片数(主 + 副本)。
(2)查看集群详细状态
GET _cluster/state // 完整状态
GET _cluster/state/metadata // 仅查看索引元数据
GET _cluster/state/routing_table // 仅查看分片路由信息
(3)集群统计信息
返回索引、节点的详细统计(存储大小、内存使用、CPU 等):
GET _cluster/stats
节点监控
(1)查看节点基本信息
GET _nodes // 所有节点信息
GET _nodes/node-1 // 指定节点(node-1)信息
GET _cat/nodes?v // 表格形式展示节点信息(含角色、内存使用率)
(2)查看节点统计信息
GET _nodes/stats // 所有节点统计(索引、JVM、线程池等)
GET _nodes/node-1/stats/jvm // 仅查看node-1的JVM信息
分片迁移与重分配
通过 _cluster/reroute API 手动调整分片分布(如平衡负载、故障恢复):
POST _cluster/reroute
{
"commands": [
{
"move": { // 迁移分片(从node1到node2)
"index": "test",
"shard": 0,
"from_node": "node1",
"to_node": "node2"
}
},
{
"allocate_replica": { // 分配未分配的副本分片到node3
"index": "test",
"shard": 1,
"node": "node3"
}
}
]
}
集群核心配置详解
集群配置分为静态配置(elasticsearch.yml)和动态配置(_cluster/settings API),核心参数如下:
主节点选举与脑裂防护
discovery.zen.minimum_master_nodes:
防止脑裂(集群分裂为多个子集群)的关键参数,需设置为(主节点候选数 / 2) + 1。例如,3 个主节点候选时,值为 2。discovery.zen.ping.unicast.hosts:
单播发现的初始节点列表(生产环境推荐,替代组播),如["node1:9300", "node2:9300"]。
故障检测(主节点与节点通信)
# 主节点检测节点超时配置
discovery.zen.fd.ping_interval: 1s # 检测频率
discovery.zen.fd.ping_retries: 3 # 重试次数
discovery.zen.fd.ping_timeout: 30s # 超时时间(超时则认为节点故障)
分片分配与平衡
cluster.routing.allocation.enable:
控制分片分配类型(all:允许所有分片;primaries:仅主分片;none:禁止分配)。cluster.routing.rebalance.enable:
控制分片重平衡(all:允许所有;replicas:仅副本;none:禁止)。磁盘水位控制:
cluster.routing.allocation.disk.watermark.low: 85% # 磁盘使用率>85%时停止分配新分片 cluster.routing.allocation.disk.watermark.high: 90% # 磁盘使用率>90%时迁移分片到其他节点
动态配置更新
通过 API 实时修改集群配置(无需重启),分为:
persistent:永久生效(重启后保留);transient:临时生效(重启后失效)。
示例:调整分片恢复速度:
PUT _cluster/settings
{
"persistent": {
"indices.recovery.max_bytes_per_sec": "100mb" // 提升恢复速度至100MB/s
}
}
集群配置示例(生产环境参考)
# 集群名称(所有节点必须一致)
cluster.name: my-es-cluster
# 节点名称(每个节点唯一)
node.name: node-1
# 节点角色(数据节点配置)
node.master: false
node.data: true
node.ingest: true
# 数据与日志路径
path.data: /data/elasticsearch/data
path.logs: /var/log/elasticsearch
# 网络配置(允许远程访问)
network.host: 0.0.0.0
http.port: 9200
transport.tcp.port: 9300
# 内存锁定(防止JVM内存交换)
bootstrap.memory_lock: true
# 主节点选举配置(3个主节点候选时,minimum_master_nodes=2)
discovery.zen.minimum_master_nodes: 2
discovery.zen.ping.unicast.hosts: ["node-1:9300", "node-2:9300", "node-3:9300"]
# 故障检测
discovery.zen.fd.ping_timeout: 30s
# 分片分配与磁盘水位
cluster.routing.allocation.disk.watermark.low: 80%
cluster.routing.allocation.disk.watermark.high: 90%
# 跨域配置(允许Kibana访问)
http.cors.enabled: true
http.cors.allow-origin: "*"
集群管理最佳实践
- 节点角色分离:
- 主节点与数据节点分离(主节点仅负责集群管理,避免资源竞争)。
- 大规模集群(>10 节点)可增加客户端节点作为协调节点。
- 分片规划:
- 主分片数量:根据数据量规划(单分片建议 20~50GB),创建后不可修改。
- 副本分片:至少 1 个(保障可用性),查询密集型场景可增加至 2~3 个。
- 监控与告警:
- 使用 Kibana Monitoring 或
_catAPI 监控集群健康、分片分布、节点资源。 - 对
status: red、磁盘使用率超 90% 等异常设置告警。
- 使用 Kibana Monitoring 或
- 避免脑裂:
严格设置discovery.zen.minimum_master_nodes,主节点候选数建议为奇数(3、5 个)