ES 集群调优:分片、副本与堆内存

FreeGuideOnline 最新 2026-07-03

bash GET _cat/shards?v&h=index,shard,prirep,state,node


- **避免过度分片**  
  创建索引时预先评估数据量增长,利用 Rollover 和 ILM 生命周期管理分割索引。勿用超大`number_of_shards`“一劳永逸”。

### 索引设计原则

- **面向查询时间分片**  
  日志类时序数据,按天/小时滚动索引,将热数据集中到少量分片,冷数据可 shrink 合并。

- **分片数设置公式**  
  预估数据总量 ÷ 单分片目标大小 × 1.2(冗余系数),再结合节点数微调。例如 500GB 数据,目标 30GB 一个分片,主分片数 ≈ 20。

### 分片分配策略

- **使用分片分配感知**  
  通过 `cluster.routing.allocation.awareness.attributes` 设置机架、可用区感知,避免主副分片在同一故障域。

- **自定义分片过滤规则**  
  可对热点节点设置 `_cluster/settings` 排除特定索引分配,或强制将索引固定在 SSD 节点:

```json
PUT _cluster/settings
{
  "transient": {
    "cluster.routing.allocation.exclude._ip": "10.0.0.1"
  }
}

副本调优:性能与冗余的平衡

副本提供高可用并分担查询负载,但不合理的副本数会成倍放大写入开销。

副本数量的选择

  • 生产环境至少 1 个副本,保证数据可靠性与故障恢复。
  • 写入密集型集群可临时将副本数降为 0,待写入高峰过后再增加,使用:
PUT /my-index/_settings
{
  "index": {
    "number_of_replicas": 0
  }
}
  • 读多写少场景可适当增加副本提升并发查询吞吐量,但注意不要超过节点数 -1。

同步与异步复制

  • ES 默认使用同步复制(wait_for_active_shards 默认为 1),仅需主分片写入成功即返回。为保证一致性,可设置为 allquorum
  • 在批量写入时,设置 wait_for_active_shards1 可获得更好性能,但存在数据丢失风险。

副本的搜索负载均衡

  • 集群会自动将查询请求分发到主副分片,可配合自适应副本选择(ARS)让查询优先落到响应较快的副本节点,开启方式:
PUT _cluster/settings
{
  "transient": {
    "cluster.routing.use_adaptive_replica_selection": true
  }
}

堆内存调优:JVM 的生命线

ES 对堆内存极度敏感,配置不当直接导致频繁 GC 甚至 OOM。

堆内存规模与设置

  • 堆内存上限:不超过宿主机物理内存的 50%,且最大不超过 31GB。超过 32GB 会导致对象指针压缩失效,内存浪费并降低性能。
  • jvm.options 中固定配置:
-Xms16g
-Xmx16g

一定要确保 -Xms 和 -Xmx 一致,避免运行期调整堆大小的开销。

垃圾收集器选择与调优

  • 推荐使用 G1GC(JDK 11+ 默认)。若使用 JDK 8,需在 jvm.options 显式开启:
-XX:+UseG1GC
  • 关键 GC 日志分析:关注 _cat/nodes?v&h=name,heap.percent,ram.percent 实时监控堆使用率,长期超过 75% 是危险信号。
  • 调整 -XX:MaxGCPauseMillis(默认 200ms),适当的停顿目标可平衡吞吐与延迟。

避免堆内存暴增的操作

  • 聚合与深度分页:使用 search_after 替代 from/size 深度跳页;聚合时尽量限制桶数量,可用 terminate_after 提前终止。
  • Fielddata 与 doc_values:默认禁用 fielddata。若必须对 text 字段排序/聚合,需设 fielddata=true,但会大量占用堆。优先使用 keyword 类型并启用 doc_values
  • 熔断机制保护:配置合理断路限制,防止单次请求打爆堆:
PUT _cluster/settings
{
  "transient": {
    "indices.breaker.request.limit": "50%",
    "indices.breaker.fielddata.limit": "40%"
  }
}