解决磁盘负载不均——ElasticSearch 分片分配和路由设置

ES 分片分配(Shard Allocation)时间点:

  1. 初始恢复(Initial Recovery)
  2. 副本分配(Replica Allocation)
  3. 重平衡(Rebalance)
  4. 节点添加或移除

image.png

小结:

  • 准备移除节点时,使用过滤器禁止路由到节点

  • 增加新节点时,降低磁盘水位线触发重平衡,使分片分布均匀

  • 旧节点分片不均,综合考虑每个节点分片数量和磁盘占有率调整

一. 集群级别分片分配设置

下方均为动态设置

  • cluster.routing.allocation.enable

不影响重启主分片恢复

  • all默认

  • primaries 只允许主分片分配

  • new_primaries 只允许新索引的主分片

  • none 不允许分片分配

  • cluster.routing.allocation.node_concurrent_incoming_recoveries

    • 单节点并发恢复分片请求数,默认为2。指在节点上分配目标分片
  • cluster.routing.allocation.node_concurrent_outgoing_recoveries

    • 单节点源分片分配到新节点请求数,默认2
  • cluster.routing.allocation.node_concurrent_recoveries

上方两个配置的合并

  • cluster.routing.allocation.node_initial_primaries_recoveries 副本通过网络恢复,未分配的主分片使用本地数据恢复。此配置用于配置并行未分配主分片恢复,默认4

  • cluster.routing.allocation.same_shard.host 禁止多个副本分片被分配到相同ip节点上

1.1 分片重平衡设置

保证分片数量在每个节点上尽可能相同。受分配过滤(Allocation Filtering)和 forced awareness 影响

  • cluster.routing.rebalance.enable

    • all 默认

    • primaries 只允许主分片重平衡

    • replicas 只允许副本重平衡

    • none

  • cluster.routing.allocation.allow_rebalance

    • always

    • indices_primaries_active 仅当所有主分片被分配时

    • indices_all_active 默认。仅当集群中所有分片被分配时

  • cluster.routing.allocation.cluster_concurrent_rebalance

1.2 分片平衡启发式(Heruistics)设置

(黑盒设置,未找到计算公式)

计算权重,根据权重从高分到低,从高的重平衡到权重低的节点,受到阈值的配置影响,低于阈值不需要重平衡(这个数值没有说明是怎么计算的)

  • cluster.routing.allocation.balance.shard0.45,提升此值会使所有节点分片数量趋于平衡

  • cluster.routing.allocation.balance.index 0.55

  • cluster.routing.allocation.balance.threshold 1.0f, 大于0,越大则越不激进

1.3 基于磁盘的分片分配设置

通过水位线来控制重平衡

  1. 当高于洪水线(flood_stage)时,写入请求会被阻塞,只要有一个节点到达,所有节点被阻塞

  2. 当高于水位线(high watermark),ES 尝试将节点数据重平衡到其他节点

  3. 当低于水位线 (low watermark),不会触发重平衡或者重平衡将停止。同时不再向该节点派发新分片

  • cluster.routing.allocation.disk.threshold_enabled 启用磁盘阈值限制,默认开启

  • cluster.routing.allocation.disk.watermark.low 最低水位线,默认85%

  • cluster.routing.allocation.disk.watermark.low.max_headroom 默认200GB

  • cluster.routing.allocation.disk.watermark.high 最高水位线,默认90%

  • cluster.routing.allocation.disk.watermark.high.max_headroom 默认 150GB

  • cluster.routing.allocation.disk.watermark.flood_stage 洪水线,默认 95%

  • cluster.routing.allocation.disk.watermark.flood_stage.max_headroom 默认 100GB

  • cluster.info``.update.interval 集群信息检查间隔,默认 30s

1.4 集群级别分片过滤器

上下线节点或节点处于不平衡状态时,可以通过过滤器临时阻止分片路由到该节点

PUT _cluster/settings
{
  "persistent" : {
    "cluster.routing.allocation.exclude._ip" : "10.0.0.1"
  }
}
  • cluster.routing.allocation.include.{attribute}

  • cluster.routing.allocation.require.{attribute}

  • cluster.routing.allocation.exclude.{attribute}

    • 属性列表:_name(node name), _host_ip(node ip) _publish_ip, _ip(short cuts of _host_ip and _publish_ip), _host, _id, _tier

二. 索引分片分配设置

与集群级别一样,可以设置分片过滤器、数据层(data-tier)过滤器,但增加了每个节点的分片数设置

假设索引共 A 个节点,B 个分片,C 个副本共 BC 个分片,则每个节点最大分片数设置为 BC/A 得到最平均的分片数,(B*C/A)+1 允许节点挂掉后还有一个可以正常分配分片

index.routing.allocation.total_shards_per_node 默认不设置,可能会导致数据很不平衡

三. 实操

现象: 节点 10.15.213.12 磁盘高于 86%,虽然停止写入,但无法到达重平衡线,其他节点的分片数不均

10.15.213.12: app-es110(86.8%)

10.15.219.125: app-es 138(77.66%)

10.15.220.165: app-es 158(77.53%)

10.15.213.8: app-es 138 (69.05%)

10.15.213.9: app-es 129 (68.65%)

10.15.213.11: app-es 132 (56%)

操作: 默认水位线为 90%,降低至 85%,手动触发重平衡,重平衡完毕后再恢复设置

PUT _cluster/settings
{
  "persistent": {
    "cluster": {
      "routing": {
        "allocation.disk.watermark.low": "80%",
        "allocation.allow_rebalance": "always",
        "allocation.disk.watermark.high": "85%"
      }
    }
  }
}

POST /_cluster/reroute?dry_run=false&explain=true&retry_failed=false

另外针对节点10.15.220.165 上分片较多,先计算平衡时的分片数:

  • app-es 为 410 个分片,1副本,6个节点,则平均为 410*2/6=136,设置为 136+6=142
PUT clue-online-*/_settings
{
  "routing": {
    "allocation": {
      "total_shards_per_node": 142
    }
  }
}

操作后:10.15.213.12 降至 83%,报警解除

四. 相关命令

// 查看未分配或待分配分片状态,如果为 STARTED 则正常,为 UNASSIGNED 异常
GET  _cat/shards?h=index,shard,prirep,state,unassigned.reason
// 集群设置
GET _cluster/settings
// 解释待分配分片去向
GET _cluster/allocation/explain
PUT clue-online-*/_settings
{
  "routing": {
    "allocation": {
      "total_shards_per_node": 142
    }
  }
}
// 强制 Reroute
POST /_cluster/reroute?dry_run=false&explain=true&retry_failed=false

五. 重平衡可能的问题

  1. 数据极速写入导致负载上升
    a. 解决方式:使用写入限流器等方式控制重平衡速度
  2. 重平衡进入无限循环状态
    a. 解决方式:检查集群整体的磁盘比例,如各分片均处在水位线附近,此问题可能出现。建议临时调整水位线,待重平衡结束后,删除不需要的数据或扩容

Ref: Cluster-level shard allocation and routing settings | Elasticsearch Guide [7.10] | Elastic

<think>嗯,用户之前问过关于Elasticsearch分布式架构如何处理节点故障的问题,现在又接着问分片副本。看来他们可能是在学习ES的分布式机制,或者是正在搭建集群需要了解这些概念。 首先,用户之前的问题是关于节点故障的自动处理,所以现在问分片副本应该是想深入理解数据存储冗余的机制。分片副本是ES实现高可用扩展性的核心,需要详细解释两者的区别联系。 用户可能不太清楚分片副本的作用,或者混淆了它们的概念。需要明确分片是数据分割的单位,而副本是分片的复制,用于故障恢复负载均衡。可能还需要举例说明,比如索引如何被分成多个分片,每个分片如何有副本。 另外,用户可能关心实际应用中的配置,比如如何设置分片副本数,最佳实践是什么。需要提到分片过多或过少的影响,副本数量的调整对集群性能的影响,以及如何根据硬件资源来规划。 还要注意用户可能的误区,比如认为增加副本可以无限提高性能,但实际上副本会占用存储计算资源。需要解释平衡可用性资源消耗的重要性。 用户可能还需要知道分片副本在故障恢复中的具体作用,比如主分片失效时副本如何提升为主分片,恢复过程中数据如何同步。这部分可以结合之前的节点故障处理机制来回答,形成知识连贯性。 最后,可能还需要提到一些常见问题,比如分片无法分配的原因,如何监控分片状态,以及调整分片副本时的注意事项。这些实际操作的内容对用户来说可能非常实用。</think>### Elasticsearch 分片(Shard)与副本(Replica)详解 --- #### 一、核心概念对比 | 特性 | **分片(Shard)** | **副本(Replica)** | |-------------|--------------------------------------|--------------------------------------| | **本质** | 数据的最小物理存储单元 | 分片的完整拷贝 | | **类型** | 主分片(Primary) / 副本分片(Replica)| 只能是主分片的副本 | | **读写权限** | 主分片可读写,副本分片默认只读 | 仅响应查询请求 | | **创建时机** | 索引创建时固定数量(不可修改) | 可动态调整数量 | | **作用目标** | 解决**数据水平扩展**问题 | 解决**高可用****查询负载均衡**问题 | --- #### 二、技术实现细节 ##### 1. **分片工作机制** - **分片公式**: $$ \text{总数据存储量} = \text{主分片数} \times (1 + \text{副本数}) \times \text{单分片数据量} $$ - **路由机制**: 文档通过哈希算法分配到指定主分片: $$ \text{shard\_num} = hash(\_routing) \% \text{num\_primary\_shards} $$ - **分片限制**: 单个分片建议大小在 `10GB-50GB`(超过 `100GB` 可能影响性能) ##### 2. **副本运作原理** - **实时同步**: 主分片通过 `Translog` 保证数据变更顺序,副本采用 `pull` 模式同步数据 - **一致性模型**: - **同步写入**:需多数副本确认(通过 `wait_for_active_shards` 参数控制) - **异步刷新**:默认每秒刷新(`refresh_interval=1s`) --- #### 三、配置与优化策略 ##### 1. **分片数量决策** - **黄金法则**: 分片总数 = 节点数 × 单节点承载分片数(建议 `500-1000`/节点) 例如:3节点集群,单节点承载上限 800 分片 → 总容量约 `2400` 分片 - **动态调整限制**: 主分片数创建后不可变,只能通过 `Reindex API` 重建索引调整 ##### 2. **副本配置技巧** ```json // 创建索引时指定分片配置 PUT /my_index { "settings": { "number_of_shards": 3, // 主分片数 "number_of_replicas": 2 // 每个主分片的副本数 } } // 动态修改副本数(实时生效) PUT /my_index/_settings { "number_of_replicas": 1 } ``` ##### 3. **性能优化要点** - **冷热分离架构**: 使用 `ILM(Index Lifecycle Management)` 将旧索引副本数降为 `0` - **写入优化**: 临时关闭副本(`index.number_of_replicas=0`)提升批量导入速度 - **查询加速**: 增加副本可实现读请求的**多副本负载均衡** --- #### 四、故障场景应对 ##### 1. **分片分配(UNASSIGNED)** - **常见原因**: - 磁盘空间不足(`85%` 水位线触发只读模式) - 节点属性不匹配分配规则(如 `rack` 标签约束) - **解决方案**: ```bash # 强制分配分片(慎用) POST /_cluster/reroute { "commands": [{ "allocate_stale_primary": { "index": "my_index", "shard": 0, "node": "node-1", "accept_data_loss": true } }] } ``` ##### 2. **副本同步延迟** - **检测方法**: ```bash GET /_cat/shards?v&h=index,shard,prirep,state,docs,store ``` - **处理方案**: - 检查网络带宽(`indices.recovery.max_bytes_per_sec`) - 优化映射字段类型,减少 `_source` 体积 --- #### 五、最佳实践总结 1. **容量规划**: - 预估数据总量 → 确定主分片数 - 根据 SLA 要求 → 确定副本数(生产环境至少 `1` 副本) 2. **硬件匹配原则**: - 单个分片数据量 ≈ 节点内存的 `1/10`(如 `64GB` 内存 → 分片大小 `6-7GB`) - 使用 `SSD` 磁盘降低副本同步延迟 3. **监控关键指标**: - `indices.search.fetch_current`(副本查询负载) - `indices.indexing.index_current`(主分片写入压力) - `thread_pool` 的 `write`/`search` 队列深度 4. **特殊场景处理**: - **时序数据**:使用 `Rollover API` 自动创建新分片 - **全局搜索**:设置 `preference=_primary` 强制主分片查询 --- #### 六、经典误区解析 - **误区1**:"增加副本数一定能提升查询性能" ✅ 实际:当查询为 `CPU 密集型` 时,过多副本可能引发线程竞争 - **误区2**:"主分片越多越好" ✅ 实际:分片过多会导致 `元数据管理开销` 指数级增长 - **误区3**:"副本可以替代备份" ✅ 实际:副本不能防范 `误删除`,仍需 `Snapshot` 实现真正备份 --- 通过合理配置分片与副本,可在**数据可靠性**、**查询性能**、**硬件成本**之间找到最佳平衡点。建议通过 `Elasticsearch Rally` 进行分片方案的基准测试验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值