2. Elasticsearch 基础回顾:ES 集群架构、节点角色、索引与分片的关系、副本机制原理

在深入 Kubernetes 环境下的分片与副本调优之前,必须牢固掌握 Elasticsearch 的核心基础。本章将系统回顾 ES 集群的物理与逻辑架构、节点角色分工、索引与分片的映射关系,以及副本机制的高可用原理。这些概念是后续所有调优策略的基石。

2.1 ES 集群架构:从单点到分布式

Elasticsearch 是一个分布式搜索与分析引擎,其核心设计理念是将数据分散到多个节点上,实现水平扩展与高可用。一个 ES 集群由多个节点(Node)组成,每个节点是一个独立的 ES 进程。节点之间通过发现模块(Discovery)自动组建集群,并通过 Zen Discovery 或新的 Seeded Discovery 协议维护集群拓扑。

下图展示了 ES 集群的基本架构,包含主节点、数据节点、协调节点以及客户端请求的流转路径:

Elasticsearch 集群架构示意图 ES 集群架构:节点角色与请求流转 客户端 / Kibana 协调节点 (Coordinating) 主节点 (Master) 数据节点组 (Data Nodes) 数据节点 1 P0, R1 数据节点 2 P1, R0 数据节点 3 R0, R1 节点角色说明 • Master:集群管理 • Data:存储与检索 • Coordinating:路由与聚合
关键认知:在 Kubernetes 环境中,每个 ES 节点通常对应一个 Pod。节点角色的合理分配直接影响集群的稳定性与资源利用率。生产环境中建议将 Master 节点与 Data 节点分离部署。

2.2 节点角色详解

ES 节点可以承担多种角色,通过 elasticsearch.yml 中的配置项控制。理解每种角色的职责,是设计集群拓扑的前提。

角色名称 配置项 核心职责 资源消耗特点
Master node.roles: [master] 集群元数据管理、索引创建/删除、节点加入/离开处理、选主 CPU 与内存适中,对磁盘 I/O 要求低
Data node.roles: [data] 存储分片数据、执行 CRUD、搜索与聚合操作 高 CPU、高内存、高磁盘 I/O
Ingest node.roles: [ingest] 数据预处理管道(Pipeline),如字段转换、Grok 解析 CPU 密集型,内存适中
Coordinating node.roles: [](空列表) 接收客户端请求,分发到数据节点,合并结果返回 高网络带宽,内存用于结果聚合
Machine Learning node.roles: [ml] 运行异常检测、数据帧分析等 ML 任务 高 CPU、高内存
K8s 部署提示:在 Kubernetes 中,建议为不同角色使用独立的 StatefulSet 和资源配额。Master 节点使用较小的 CPU 请求(如 2-4 核),Data 节点根据数据量配置 8-32 核,并挂载 SSD 持久卷。

2.3 索引与分片的关系

索引(Index)是 ES 中存储相关数据的逻辑容器,类似于关系数据库中的“表”。每个索引在物理上被划分为多个分片(Shard),分片是 ES 分布式存储的最小工作单元。分片本质上是 Lucene 索引实例,拥有完整的倒排索引和段文件。

分片分为两类:

  • 主分片(Primary Shard):索引创建时指定,负责处理写入请求。主分片数量在索引创建后不可更改。
  • 副本分片(Replica Shard):主分片的完整拷贝,负责处理只读请求(搜索、聚合),提供故障转移能力。

索引与分片的关系可以用以下公式表达:

索引的总分片数 = 主分片数 × (1 + 副本数)
例如:主分片数 = 5,副本数 = 1 → 总分片数 = 5 × 2 = 10

下图展示了索引、主分片、副本分片在集群节点上的分布关系:

索引与分片分布关系图 索引与分片:主分片与副本分片的分布 索引 "logs" 主分片数: 3, 副本数: 1 物理分片分布 节点 1 主分片 P0 副本分片 R1 节点 2 主分片 P1 副本分片 R2 节点 3 主分片 P2 副本分片 R0 分片分布规则 • 主分片 P0、P1、P2 分别分布在节点 1、2、3 上 • 副本分片 R0、R1、R2 分别分布在节点 3、1、2 上 • 主分片与它的副本分片 不会 落在同一节点
重要约束:主分片数量在索引创建后不可修改。如果预估数据量会大幅增长,建议设置较大的主分片数(如 5-10 个),或使用 ILM(索引生命周期管理)配合滚动索引策略。副本数可以动态调整。

2.4 副本机制原理

副本分片是 ES 高可用的核心保障。每个主分片可以拥有零个或多个副本分片。副本机制遵循以下原则:

  1. 写操作流程:客户端请求到达主分片 → 主分片写入本地 Lucene 索引 → 并行转发到所有副本分片 → 等待副本确认(可配置 wait_for_active_shards)→ 返回成功。
  2. 读操作流程:协调节点将搜索请求分发到索引的所有分片(主分片和副本分片均可处理),采用自适应副本选择(ARS)策略选择最优副本。
  3. 故障转移:当主分片所在节点宕机时,集群会从该主分片的副本中选举一个提升为新的主分片。新主分片会立即开始服务,同时集群会在其他节点上创建新的副本分片以维持副本数。
  4. 数据一致性:ES 采用最终一致性模型。写入请求在主分片和所有活跃副本都确认后才返回成功,确保数据不丢失。搜索请求可能读取到稍旧的数据,但不会读到未提交的数据。

副本数的配置直接影响集群的容错能力和查询吞吐量:

副本数 容错能力 查询吞吐量 磁盘使用量 写入性能影响
0 无容错,节点宕机即丢失数据 低(仅主分片提供服务) 基础数据量 无额外开销
1 允许 1 个节点宕机 翻倍(主+副本均可查询) 2 倍 增加一次网络复制
2 允许 2 个节点宕机 3 倍 3 倍 增加两次网络复制
K8s 环境建议:在 Kubernetes 集群中,由于 Pod 可能因节点故障、资源抢占等原因重启,建议至少设置 1 个副本。对于关键业务索引,设置 2 个副本可以提供更高的容错冗余。同时,利用 Pod 反亲和性(PodAntiAffinity)确保副本分片分布在不同的 K8s 节点上。

2.5 分片分配与平衡

ES 集群会自动管理分片在节点间的分配与平衡。核心机制包括:

  • 分片分配(Shard Allocation):当节点加入或离开时,集群会重新分配分片。分配策略由 cluster.routing.allocation 系列参数控制。
  • 再平衡(Rebalancing):集群持续监控各节点的分片数量,当节点间分片数量差异超过阈值(默认 2)时,触发再平衡操作。
  • 感知分配(Allocation Awareness):支持基于属性(如机架、可用区)的分配策略,确保分片分布在不同的故障域。

在 Kubernetes 环境中,分片分配策略需要与 K8s 的调度策略协同。例如,通过设置 node.attr.zone 属性对应 K8s 节点所在的可用区,可以实现跨可用区的高可用部署。

# 配置节点属性(elasticsearch.yml)
node.attr.zone: us-east-1a

# 集群感知分配配置
cluster.routing.allocation.awareness.attributes: zone
cluster.routing.allocation.awareness.force.zone.values: us-east-1a, us-east-1b, us-east-1c
核心要点回顾:索引是逻辑容器,分片是物理存储单元。主分片负责写入,副本分片提供高可用与读扩展。副本数越多,容错与查询能力越强,但写入开销和磁盘占用也越大。在 K8s 中,需要结合 Pod 调度策略和节点拓扑来优化分片分布。