Elasticsearch 分片:分布式存储与查询的核心
分片(Shard)是 Elasticsearch 实现分布式存储和并行查询的基础,将一个索引的数据拆分为多个片段,分布在不同节点上。理解分片的工作原理和配置策略,对优化集群性能和可靠性至关重要。
分片的基本概念
主分片与副本分片
- 主分片(Primary Shard):
- 索引数据的原始存储单元,负责处理写入请求(索引、更新、删除)。
- 数量在索引创建时指定(
number_of_shards),创建后不可修改(因路由依赖主分片数量)。 - 默认值:5 个(6.8.x 版本)。
- 副本分片(Replica Shard):
- 主分片的副本,用于冗余备份和分担查询压力(只读,不处理写入)。
- 数量可动态调整(
number_of_replicas),默认 1 个。 - 副本分片不能与对应的主分片位于同一节点(避免单点故障)。
分片的核心作用
- 分布式存储:突破单节点存储上限,支持海量数据(如 10 个主分片可存储 10 倍于单节点的数据)。
- 并行处理:查询请求可同时在多个分片(主或副本)上执行,提升查询效率。
- 高可用性:主分片故障时,副本分片可自动升级为主分片(需集群有足够节点)。
分片路由机制
当文档写入或查询时,Elasticsearch 需要确定文档属于哪个主分片,这一过程通过路由算法实现:
路由公式
1 | shard_number = hash(routing_value) % number_of_primary_shards |
routing_value:路由键,默认值为文档的_id(可自定义)。hash():Elasticsearch 内置哈希函数,确保值均匀分布。number_of_primary_shards:主分片数量(固定值)。
自定义路由
默认路由基于 _id,但可通过 routing 参数指定自定义路由键(如用户 ID),将相关文档路由到同一分片,提升查询效率:
1 | // 写入文档时指定路由 |
优点:减少查询时的分片扫描(仅访问目标分片)。
缺点:可能导致分片数据分布不均(热点问题)。
分片配置策略
主分片数量规划
主分片数量需根据数据量和查询并发量提前规划,原则如下:
- 数据量:单个主分片建议存储 20GB~50GB 数据(过大影响恢复速度)。
- 节点数量:主分片数量应 ≥ 数据节点数量(避免单节点承载过多主分片)。
- 扩展考虑:未来如需扩容,可通过
_reindex迁移数据到新索引(主分片数更多)。
示例:预计总数据量 100GB → 主分片数 = 100GB / 25GB = 4 个。
副本分片配置
副本分片数量需平衡可用性和资源消耗:
- 生产环境:至少 1 个副本(确保主分片故障时数据不丢失)。
- 查询密集型场景:增加副本数(如 2~3 个),利用副本分担查询压力(需更多节点资源)。
- 存储受限场景:可临时将副本数设为 0(不推荐,风险高)。
动态调整副本数:
1 | PUT video/_settings |
分片与节点的分配
Elasticsearch 自动均衡分片分配,遵循以下规则:
- 主分片均匀分布在不同节点。
- 副本分片与对应主分片不在同一节点。
- 同节点上的分片总数不超过阈值(避免资源过载)。
手动调整分片分配(如需):
1 | PUT _cluster/reroute |
常见问题与最佳实践
主分片数量过多 / 过少的影响
- 过多:
- 优点:并行查询能力强。
- 缺点:元数据管理开销大,小分片增多(每个分片有固定元数据消耗)。
- 过少:
- 优点:元数据管理简单。
- 缺点:单分片数据量大,查询 / 恢复速度慢,无法充分利用多节点资源。
分片不均(热点问题)
- 原因:自定义路由不当(如大量文档路由到同一分片)。
- 解决:
- 避免使用过于集中的路由键(如按用户 ID 哈希后取模)。
- 通过
_cat/shards监控分片大小,及时迁移热点分片。
分片恢复优化
节点故障后,分片需从副本恢复,可通过以下参数加速:
1 | PUT _cluster/settings |