5月28日 02:00

Elasticsearch 集群架构中分片和副本的作用是什么?

Elasticsearch 的分布式能力建立在两个核心机制之上:分片(Shard)副本(Replica)。分片解决"一台机器存不下、算不快"的问题,副本解决"一台机器挂了数据丢了"的问题。理解这两者的工作方式,是掌握 Elasticsearch 集群架构的关键。

分片(Shard):水平拆分,并行提速

分片是将一个索引拆分为多个独立存储单元的机制。每个分片本质上是一个完整的 Lucene 索引,可以独立存储和检索数据,分布在集群的不同节点上。

水平扩展存储容量

单节点存储有上限。假设一个索引有 60GB 数据,设置 number_of_shards=5,则每个分片存储约 12GB,可分散到 5 个节点上。数据量增长时,通过增加节点即可承载更多分片。

并行提升查询性能

搜索请求到达后,协调节点将查询分发到所有相关分片并行执行,各分片返回局部结果后由协调节点合并排序。5 个分片意味着 5 路并行,查询延迟显著降低。

分片数量在索引创建时确定,不可修改

这是一个常考的面试点。主分片数一旦设定就无法更改(因为文档路由公式依赖分片数)。如果需要调整,只能通过 Reindex 重建索引。设置时需预估数据规模:

shell
PUT /my_index { "settings": { "number_of_shards": 3, "number_of_replicas": 1 } }

副本(Replica):高可用与读扩展

副本是主分片的完整拷贝,与主分片存储在不同节点上。它的核心价值有两个:故障容错和读性能提升。

故障容错——节点宕机数据不丢失

当持有主分片的节点故障时,集群会自动将对应的副本提升为主分片,保证数据可继续读写。故障节点恢复后,集群会重新同步数据,恢复副本。整个过程中,用户无感知。

读请求负载均衡

读操作(搜索、聚合)可以在主分片和副本上同时执行。3 个主分片 + 1 副本 = 6 个可读分片,查询吞吐量翻倍。写操作仍然只发生在主分片上,之后异步复制到副本。

副本数量可以随时修改

与分片不同,副本数可动态调整,不需要重建索引:

shell
PUT /my_index/_settings { "number_of_replicas": 2 }

分片与副本的协作机制

文档写入流程

  1. 客户端发送写请求到协调节点
  2. 协调节点根据文档 ID 计算目标分片:shard = hash(routing) % number_of_primary_shards
  3. 请求转发到主分片所在节点,主分片完成写入
  4. 主分片将数据同步到所有副本分片
  5. 所有副本确认后,返回成功响应给客户端

文档读取流程

  1. 协调节点收到读请求
  2. 根据路由信息确定目标分片组(主分片 + 副本)
  3. 采用轮询策略在主分片和副本间选择一个执行查询,实现负载均衡
  4. 返回结果

故障转移流程

当节点宕机时,集群执行以下步骤:

  • 主节点检测到节点离线,将集群状态标记为 yellow(有副本丢失)或 red(有主分片丢失)
  • 若主分片丢失,将对应副本提升为新主分片
  • 在剩余节点上重新分配分片,恢复副本数量
  • 数据通过副本重新同步,最终恢复为 green 状态

配置原则与最佳实践

分片数设置

  • 单分片建议大小 30-50GB,不超过 50GB
  • 分片数 = 预估数据量 / 单分片目标大小
  • 避免过度分片:每个分片消耗内存和文件句柄,分片过多导致性能下降
  • 官方建议:每个节点分片数不超过 堆内存(GB) × 20

副本数设置

  • 生产环境至少 1 个副本,保证单节点故障不丢数据
  • 对读吞吐要求高的场景可增加到 2 个副本
  • 副本会增加存储开销和写入延迟(写操作需同步到所有副本),需要权衡

常见配置错误

  • 小索引设置过多分片(如 1GB 数据设 5 个分片),浪费资源
  • 副本数为 0 且只有单节点,节点故障即数据丢失
  • 分片大小不均,部分热点分片成为瓶颈

面试常见追问

Q: 分片数为什么创建后不能改?

文档路由公式 hash(routing) % primary_shards 依赖分片数。如果分片数变化,已有文档的路由结果改变,查询时无法定位到正确的分片。

Q: 副本同步是同步还是异步?

写入时是同步的——主分片写入后等待所有副本确认才返回成功(可通过 consistency 参数调整)。副本之间的分段合并等操作则是异步进行。

Q: 如何选择分片数量?

基于数据量和节点数预估。核心公式:分片数 = 总数据量 / 30GB(单分片建议上限)。同时确保分片数不超过 节点数 × 每节点分片上限。实际场景中需结合写入频率和查询复杂度调整。

标签:ElasticSearch