0%

elasticsearch分片

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
2
3
4
5
6
7
8
9
10
11
// 写入文档时指定路由
PUT video/default/1?routing=user123
{
"title": "用户123的视频"
}

// 查询时需指定相同路由(仅查询该分片)
GET video/default/_search?routing=user123
{
"query": { "term": { "user_id": "user123" } }
}

优点:减少查询时的分片扫描(仅访问目标分片)。
缺点:可能导致分片数据分布不均(热点问题)。

分片配置策略

主分片数量规划

主分片数量需根据数据量查询并发量提前规划,原则如下:

  • 数据量:单个主分片建议存储 20GB~50GB 数据(过大影响恢复速度)。
  • 节点数量:主分片数量应 ≥ 数据节点数量(避免单节点承载过多主分片)。
  • 扩展考虑:未来如需扩容,可通过 _reindex 迁移数据到新索引(主分片数更多)。

示例:预计总数据量 100GB → 主分片数 = 100GB / 25GB = 4 个。

副本分片配置

副本分片数量需平衡可用性资源消耗

  • 生产环境:至少 1 个副本(确保主分片故障时数据不丢失)。
  • 查询密集型场景:增加副本数(如 2~3 个),利用副本分担查询压力(需更多节点资源)。
  • 存储受限场景:可临时将副本数设为 0(不推荐,风险高)。

动态调整副本数

1
2
3
4
PUT video/_settings
{
"number_of_replicas": 2 // 将副本数调整为2
}

分片与节点的分配

Elasticsearch 自动均衡分片分配,遵循以下规则:

  • 主分片均匀分布在不同节点。
  • 副本分片与对应主分片不在同一节点。
  • 同节点上的分片总数不超过阈值(避免资源过载)。

手动调整分片分配(如需):

1
2
3
4
5
6
7
8
9
10
11
12
13
PUT _cluster/reroute
{
"commands": [
{
"move": {
"index": "video",
"shard": 0, // 分片ID
"from_node": "node1",
"to_node": "node2"
}
}
]
}

常见问题与最佳实践

主分片数量过多 / 过少的影响

  • 过多:
    • 优点:并行查询能力强。
    • 缺点:元数据管理开销大,小分片增多(每个分片有固定元数据消耗)。
  • 过少:
    • 优点:元数据管理简单。
    • 缺点:单分片数据量大,查询 / 恢复速度慢,无法充分利用多节点资源。

分片不均(热点问题)

  • 原因:自定义路由不当(如大量文档路由到同一分片)。
  • 解决:
    • 避免使用过于集中的路由键(如按用户 ID 哈希后取模)。
    • 通过 _cat/shards 监控分片大小,及时迁移热点分片。

分片恢复优化

节点故障后,分片需从副本恢复,可通过以下参数加速:

1
2
3
4
5
6
PUT _cluster/settings
{
"transient": {
"indices.recovery.max_bytes_per_sec": "100mb" // 提升恢复速度(默认40mb/s)
}
}

欢迎关注我的其它发布渠道