Elasticsearch 核心参数调优指南
本文档整理了 ES 集群中最重要的配置参数,帮助运维人员快速理解和优化集群性能。
目录
- 配置优先级
- 分片路由与恢复参数
- 磁盘水位线
- [Segment Merge 段合并](#Segment Merge 段合并)
- 索引级别核心参数
- 线程池配置
- 内存与熔断器
- 搜索相关配置
- 集群发现与故障检测
- 常用调参命令
配置优先级
ES 配置生效优先级(从高到低):
transient(临时) > persistent(持久化) > defaults(默认值)
| 类型 |
说明 |
重启后 |
transient |
临时配置,用于紧急调整 |
丢失 |
persistent |
持久化配置,推荐使用 |
保留 |
defaults |
系统默认值,由版本决定 |
不变 |
分片路由与恢复参数
🔥 核心参数一览
| 参数 |
默认值 |
推荐值 |
说明 |
node_concurrent_recoveries |
2 |
8-16 |
单节点同时恢复分片数 |
node_initial_primaries_recoveries |
4 |
32 |
初始主分片恢复并发数 |
node_concurrent_incoming_recoveries |
2 |
2-4 |
入向恢复并发数 |
node_concurrent_outgoing_recoveries |
2 |
2-4 |
出向恢复并发数 |
cluster_concurrent_rebalance |
2 |
2-4 |
集群同时 rebalance 分片数 |
max_bytes_per_sec |
40mb |
100-200mb |
恢复时最大传输速率 |
详细说明
1. node_concurrent_recoveries
cluster.routing.allocation.node_concurrent_recoveries
- 作用:控制单个节点同时恢复的分片数量
- 影响:值越大恢复越快,但占用更多 CPU/网络/磁盘资源
- 场景 :
- 小集群/资源紧张:2-4
- 大集群/快速恢复:16-32
- 紧急恢复:可临时调高
2. node_initial_primaries_recoveries
cluster.routing.allocation.node_initial_primaries_recoveries
- 作用:节点启动时,本地主分片的恢复并发数
- 特点:只涉及本地磁盘读取,不消耗网络
- 推荐:可以设置较高值(32+),加速节点启动
3. cluster_concurrent_rebalance
cluster.routing.allocation.cluster_concurrent_rebalance
- 作用:整个集群同时进行 rebalance 的分片数
- 场景 :
- 日常运维:2(保守)
- 扩缩容时:4-8(加速)
- 业务高峰:0(禁止 rebalance)
4. max_bytes_per_sec
indices.recovery.max_bytes_per_sec
- 作用:限制恢复时的网络传输速率
- 注意:设置过高可能影响业务查询
- 推荐:根据网络带宽调整,通常 100-200mb
调参示例
# 加速分片恢复(适合扩容/故障恢复场景)
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.node_concurrent_recoveries": 16,
"cluster.routing.allocation.cluster_concurrent_rebalance": 4,
"indices.recovery.max_bytes_per_sec": "200mb"
}
}
# 恢复完成后调回保守值
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.node_concurrent_recoveries": 8,
"cluster.routing.allocation.cluster_concurrent_rebalance": 2,
"indices.recovery.max_bytes_per_sec": "40mb"
}
}
磁盘水位线
🔥 核心参数
| 参数 |
默认值 |
说明 |
watermark.low |
85% |
停止分配新分片到该节点 |
watermark.high |
90% |
开始迁移分片离开该节点 |
watermark.flood_stage |
95% |
索引变为只读(危险!) |
详细说明
cluster.routing.allocation.disk.watermark.low # 低水位
cluster.routing.allocation.disk.watermark.high # 高水位
cluster.routing.allocation.disk.watermark.flood_stage # 洪水位
水位触发行为
磁盘使用率
│
│ ┌─────────────────────────────────────┐
95% ├───┤ flood_stage: 索引变只读,无法写入! │ ⚠️ 危险
│ └─────────────────────────────────────┘
│ ┌─────────────────────────────────────┐
90% ├───┤ high: 开始迁移分片到其他节点 │ ⚠️ 警告
│ └─────────────────────────────────────┘
│ ┌─────────────────────────────────────┐
85% ├───┤ low: 停止分配新分片到该节点 │ 注意
│ └─────────────────────────────────────┘
│
│ 正常运行
│
调参示例
# 调整水位线(适合大磁盘场景)
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "80%",
"cluster.routing.allocation.disk.watermark.high": "85%",
"cluster.routing.allocation.disk.watermark.flood_stage": "90%"
}
}
# 也可以用绝对值
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.disk.watermark.low": "100gb",
"cluster.routing.allocation.disk.watermark.high": "50gb",
"cluster.routing.allocation.disk.watermark.flood_stage": "20gb"
}
}
⚠️ 紧急处理:索引变只读
当触发 flood_stage 后,需要手动解除只读:
# 解除所有索引的只读状态
PUT /_all/_settings
{
"index.blocks.read_only_allow_delete": null
}
# 解除单个索引
PUT /your_index/_settings
{
"index.blocks.read_only_allow_delete": null
}
Segment Merge 段合并
📚 什么是 Segment?
Elasticsearch 底层使用 Lucene,数据存储在 Segment(段) 中。
Index (索引)
└── Shard (分片)
└── Segment (段) ← 不可变的数据块
└── Document (文档)
Segment 的特点
| 特点 |
说明 |
| 不可变 |
一旦写入,Segment 不可修改 |
| 只增不改 |
更新 = 标记删除旧文档 + 写入新文档 |
| 定期合并 |
多个小 Segment 合并成大 Segment |
🔄 为什么需要 Segment Merge?
随着数据写入,会产生大量小 Segment:
写入过程:
┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐
│ S1│ │ S2│ │ S3│ │ S4│ │ S5│ │ S6│ ← 6个小 Segment
└───┘ └───┘ └───┘ └───┘ └───┘ └───┘
Merge 后:
┌─────────────────────────────────┐
│ Merged Segment │ ← 1个大 Segment
└─────────────────────────────────┘
Merge 的好处
| 好处 |
说明 |
| 🗑️ 清理删除 |
真正删除标记为 deleted 的文档 |
| 📉 减少文件 |
减少文件句柄和系统开销 |
| 🚀 加速查询 |
查询需要遍历的 Segment 更少 |
| 💾 节省空间 |
合并后去除冗余,压缩存储 |
⚙️ Merge 相关参数(索引级别)
重要 :Segment Merge 参数主要是索引级别配置,不在集群配置中!
核心参数
| 参数 |
默认值 |
说明 |
index.merge.scheduler.max_thread_count |
自动 |
Merge 线程数(SSD:max(1,min(4,cores/2)), HDD:1) |
index.merge.policy.expunge_deletes_allowed |
10 |
允许的删除文档百分比 |
index.merge.policy.floor_segment |
2mb |
最小 Segment 大小 |
index.merge.policy.max_merge_at_once |
10 |
一次 Merge 最多合并的 Segment 数 |
index.merge.policy.max_merged_segment |
5gb |
单个 Segment 最大大小(不参与普通 Merge) |
index.merge.policy.segments_per_tier |
10 |
每层允许的 Segment 数 |
配置示例
# 创建索引时设置 Merge 参数
PUT /my_index
{
"settings": {
"index.merge.scheduler.max_thread_count": 2,
"index.merge.policy.max_merged_segment": "2gb"
}
}
# 修改已有索引的 Merge 参数
PUT /my_index/_settings
{
"index.merge.scheduler.max_thread_count": 4
}
🔧 手动触发 Force Merge
什么时候使用 Force Merge?
| 场景 |
说明 |
| ✅ 只读索引 |
历史数据、归档数据,不再写入 |
| ✅ 清理删除 |
大量删除后,回收磁盘空间 |
| ❌ 活跃写入索引 |
不推荐,会消耗大量资源 |
Force Merge 命令
# 合并单个索引到指定 Segment 数
POST /my_index/_forcemerge?max_num_segments=1
# 合并多个索引
POST /index1,index2/_forcemerge?max_num_segments=1
# 只清理删除的文档(不强制合并到指定数量)
POST /my_index/_forcemerge?only_expunge_deletes=true
# 异步执行(推荐大索引使用)
POST /my_index/_forcemerge?max_num_segments=1&wait_for_completion=false
Force Merge 参数说明
| 参数 |
说明 |
max_num_segments |
目标 Segment 数量,通常设为 1 |
only_expunge_deletes |
仅清理删除文档,不强制合并 |
wait_for_completion |
是否等待完成,大索引建议 false |
📊 查看 Segment 信息
# 查看索引的 Segment 信息
GET /my_index/_segments
# 查看分片的 Segment 详情
GET /_cat/segments/my_index?v
# 输出示例:
# index shard prirep segment generation docs.count docs.deleted size
# my_index 0 p _0 0 1000 50 1mb
# my_index 0 p _1 1 500 10 512kb
Segment 信息字段说明
| 字段 |
说明 |
segment |
Segment 名称(_0, _1, _2...) |
generation |
生成序号 |
docs.count |
有效文档数 |
docs.deleted |
已删除文档数(标记删除,未真正清理) |
size |
Segment 大小 |
⚡ Refresh vs Flush vs Merge
这三个操作容易混淆,这里做个对比:
| 操作 |
触发时机 |
作用 |
数据持久化 |
| Refresh |
默认 1s |
使新文档可搜索 |
❌ 否 |
| Flush |
默认 5s 或达到阈值 |
将 translog 写入磁盘 |
✅ 是 |
| Merge |
后台自动 |
合并 Segment,清理删除 |
✅ 是 |
写入流程:
Document → Memory Buffer → [Refresh] → Segment (in memory)
↓
[Flush] → Segment (on disk)
↓
[Merge] → Merged Segment
🔍 Merge 监控
# 查看正在进行的 Merge
GET /_cat/nodes?v&h=name,merges.current,merges.total
# 查看详细的 Merge 统计
GET /_nodes/stats/indices/merges
# 返回示例
{
"merges": {
"current": 0, # 当前进行的 Merge 数
"current_docs": 0, # 当前 Merge 涉及的文档数
"current_size_in_bytes": 0,
"total": 10, # 累计 Merge 次数
"total_time_in_millis": 5000,
"total_docs": 100000,
"total_size_in_bytes": 104857600
}
}
⚠️ Merge 注意事项
-
不要对活跃写入索引执行 Force Merge
- 会占用大量 I/O 和 CPU
- 可能影响正常写入性能
-
Force Merge 到 1 个 Segment
- 适合只读索引
- 单个 Segment 可能很大,影响恢复速度
-
监控 docs.deleted
- 如果删除文档占比高,考虑触发 Merge
- 使用
only_expunge_deletes=true 仅清理删除
-
SSD vs HDD
- SSD 可以用更多 Merge 线程
- HDD 建议限制为 1 个线程
索引级别核心参数
重要:索引级别参数可以在创建索引时设置,也可以动态修改。部分参数需要关闭索引后才能修改。
📋 参数分类概览
| 分类 |
说明 |
配置方式 |
| 静态参数 |
创建时设置,后续只能 close 后修改 |
创建时 / close-update-open |
| 动态参数 |
可随时修改,立即生效 |
PUT /_settings |
🔥 分片与副本配置
| 参数 |
默认值 |
动态 |
说明 |
number_of_shards |
1 |
❌ |
主分片数量(创建后不可变!) |
number_of_replicas |
1 |
✅ |
副本数量 |
routing_partition_size |
1 |
❌ |
自定义路由分区大小 |
codec |
default |
❌ |
压缩算法(default/best_compression) |
分片数量规划原则
📌 经验公式:
单个分片大小 = 10GB ~ 50GB(推荐 30GB 左右)
主分片数 ≈ 预估数据量 / 30GB
📌 示例:
- 预估 300GB 数据 → 10 个主分片
- 预估 1TB 数据 → 30-35 个主分片
配置示例
# 创建索引时设置分片数
PUT /my_index
{
"settings": {
"number_of_shards": 5,
"number_of_replicas": 1
}
}
# 动态调整副本数(线上常用!)
PUT /my_index/_settings
{
"index": {
"number_of_replicas": 2
}
}
# 临时关闭副本(批量导入时加速)
PUT /my_index/_settings
{
"index": {
"number_of_replicas": 0
}
}
⚡ Refresh 刷新配置
| 参数 |
默认值 |
说明 |
index.refresh_interval |
1s |
刷新间隔(使新文档可搜索) |
刷新机制原理
文档写入 → Memory Buffer → [Refresh] → Segment(可搜索)
↑
每 1 秒执行一次
调优场景
| 场景 |
推荐值 |
说明 |
| 实时搜索 |
1s(默认) |
新数据 1 秒内可搜索 |
| 近实时搜索 |
5s-30s |
降低刷新频率,提升写入性能 |
| 批量导入 |
-1(禁用) |
导入完成后手动刷新 |
| 日志场景 |
30s-60s |
日志通常不需要实时搜索 |
配置示例
# 延长刷新间隔(提升写入性能)
PUT /my_index/_settings
{
"index": {
"refresh_interval": "30s"
}
}
# 禁用自动刷新(批量导入时)
PUT /my_index/_settings
{
"index": {
"refresh_interval": "-1"
}
}
# 导入完成后手动刷新
POST /my_index/_refresh
# 恢复默认刷新间隔
PUT /my_index/_settings
{
"index": {
"refresh_interval": "1s"
}
}
📝 Translog 事务日志配置
| 参数 |
默认值 |
说明 |
index.translog.durability |
request |
持久化策略 |
index.translog.sync_interval |
5s |
异步刷盘间隔 |
index.translog.flush_threshold_size |
512mb |
触发 flush 的 translog 大小 |
持久化策略对比
| 策略 |
说明 |
性能 |
可靠性 |
request |
每次请求后刷盘 |
低 |
高(不丢数据) |
async |
按 sync_interval 异步刷盘 |
高 |
中(可能丢失 5s 数据) |
配置示例
# 高性能模式(允许少量数据丢失)
PUT /my_index/_settings
{
"index": {
"translog.durability": "async",
"translog.sync_interval": "10s"
}
}
# 高可靠模式(默认)
PUT /my_index/_settings
{
"index": {
"translog.durability": "request"
}
}
# 调整 flush 阈值
PUT /my_index/_settings
{
"index": {
"translog.flush_threshold_size": "1gb"
}
}
🔍 搜索相关配置
| 参数 |
默认值 |
说明 |
index.max_result_window |
10000 |
from + size 最大值 |
index.max_inner_result_window |
100 |
内层查询最大结果数 |
index.max_rescore_window |
10000 |
rescore 窗口最大值 |
index.max_docvalue_fields_search |
100 |
单次查询最大 docvalue 字段数 |
index.max_script_fields |
32 |
单次查询最大脚本字段数 |
index.max_terms_count |
65536 |
terms 查询最大项数 |
index.max_regex_length |
1000 |
正则表达式最大长度 |
max_result_window 详解
📌 分页限制:from + size 不能超过 max_result_window
示例:
- from=0, size=100 ✅ 0+100=100 < 10000
- from=9990, size=10 ✅ 9990+10=10000 = 10000
- from=9990, size=100 ❌ 9990+100=10090 > 10000 报错!
深度分页解决方案
| 方案 |
适用场景 |
说明 |
| scroll |
批量导出全部数据 |
保持快照,适合一次性遍历 |
| search_after |
实时深度分页 |
推荐!使用上一页最后一条的排序值 |
| 调大 max_result_window |
临时方案 |
⚠️ 不推荐,消耗内存 |
配置示例
# 调整分页限制(慎用!)
PUT /my_index/_settings
{
"index": {
"max_result_window": 50000
}
}
# 调整 terms 查询最大项数
PUT /my_index/_settings
{
"index": {
"max_terms_count": 100000
}
}
💾 存储与压缩配置
| 参数 |
默认值 |
说明 |
index.codec |
default |
压缩算法 |
index.store.type |
fs |
存储类型 |
index.store.preload |
\[\] |
预加载文件扩展名 |
压缩算法对比
| 算法 |
压缩率 |
速度 |
适用场景 |
default (LZ4) |
中等 |
快 |
大多数场景 |
best_compression (DEFLATE) |
高 |
慢 |
冷数据、归档索引 |
配置示例
# 创建高压缩索引(只能创建时设置)
PUT /archive_index
{
"settings": {
"index.codec": "best_compression"
}
}
# 预加载特定文件类型到内存
PUT /my_index/_settings
{
"index": {
"store.preload": ["nvd", "dvd"]
}
}
🔒 索引块(Blocks)配置
| 参数 |
默认值 |
说明 |
index.blocks.read_only |
false |
完全只读(包括元数据) |
index.blocks.read_only_allow_delete |
false |
只读但允许删除 |
index.blocks.read |
false |
禁止读取 |
index.blocks.write |
false |
禁止写入 |
index.blocks.metadata |
false |
禁止元数据修改 |
常用场景
# 手动设置索引只读(保护重要数据)
PUT /my_index/_settings
{
"index": {
"blocks.write": true
}
}
# 解除只读(磁盘满自动触发后)
PUT /my_index/_settings
{
"index": {
"blocks.read_only_allow_delete": null
}
}
# 批量解除所有索引只读
PUT /_all/_settings
{
"index.blocks.read_only_allow_delete": null
}
📊 慢日志配置
| 参数 |
默认值 |
说明 |
index.search.slowlog.threshold.query.warn |
-1 |
查询慢日志 WARN 阈值 |
index.search.slowlog.threshold.query.info |
-1 |
查询慢日志 INFO 阈值 |
index.search.slowlog.threshold.fetch.warn |
-1 |
Fetch 慢日志 WARN 阈值 |
index.indexing.slowlog.threshold.index.warn |
-1 |
索引慢日志 WARN 阈值 |
配置示例
# 配置查询慢日志
PUT /my_index/_settings
{
"index": {
"search.slowlog.threshold.query.warn": "10s",
"search.slowlog.threshold.query.info": "5s",
"search.slowlog.threshold.query.debug": "2s",
"search.slowlog.threshold.query.trace": "500ms"
}
}
# 配置写入慢日志
PUT /my_index/_settings
{
"index": {
"indexing.slowlog.threshold.index.warn": "10s",
"indexing.slowlog.threshold.index.info": "5s"
}
}
# 设置慢日志记录级别
PUT /my_index/_settings
{
"index": {
"search.slowlog.level": "info"
}
}
⚙️ 分片分配控制
| 参数 |
默认值 |
说明 |
index.routing.allocation.enable |
all |
分片分配策略 |
index.routing.allocation.total_shards_per_node |
-1 |
每节点最大分片数 |
index.routing.allocation.include.* |
- |
分配到包含指定属性的节点 |
index.routing.allocation.exclude.* |
- |
不分配到包含指定属性的节点 |
index.routing.allocation.require.* |
- |
必须分配到包含指定属性的节点 |
allocation.enable 选项
| 值 |
说明 |
all |
允许所有分片分配(默认) |
primaries |
只允许主分片分配 |
new_primaries |
只允许新索引的主分片分配 |
none |
禁止分片分配 |
配置示例
# 限制每个节点最多分配该索引的 2 个分片
PUT /my_index/_settings
{
"index": {
"routing.allocation.total_shards_per_node": 2
}
}
# 将索引迁移到热节点
PUT /my_index/_settings
{
"index": {
"routing.allocation.require.box_type": "hot"
}
}
# 将索引迁移到冷节点(归档)
PUT /my_index/_settings
{
"index": {
"routing.allocation.require.box_type": "cold"
}
}
# 从特定节点排除
PUT /my_index/_settings
{
"index": {
"routing.allocation.exclude._name": "node-1"
}
}
🎯 索引生命周期(ILM)相关
| 参数 |
默认值 |
说明 |
index.lifecycle.name |
- |
关联的 ILM 策略名称 |
index.lifecycle.rollover_alias |
- |
rollover 使用的别名 |
index.lifecycle.indexing_complete |
false |
标记索引已完成写入 |
配置示例
# 关联 ILM 策略
PUT /my_index/_settings
{
"index": {
"lifecycle.name": "my_policy"
}
}
# 取消 ILM 策略关联
PUT /my_index/_settings
{
"index": {
"lifecycle.name": null
}
}
📋 索引参数快速参考表
写入优化
| 场景 |
参数调整 |
| 批量导入 |
refresh_interval: -1, number_of_replicas: 0 |
| 日志场景 |
refresh_interval: 30s, translog.durability: async |
| 高吞吐写入 |
translog.flush_threshold_size: 1gb |
查询优化
| 场景 |
参数调整 |
| 深度分页 |
使用 search_after,不要调大 max_result_window |
| 大量 terms 查询 |
max_terms_count: 100000 |
| 开启慢日志 |
配置 slowlog 阈值 |
存储优化
| 场景 |
参数调整 |
| 冷数据/归档 |
codec: best_compression, 迁移到冷节点 |
| 热数据 |
codec: default, 放在 SSD 节点 |
批量导入最佳实践
# 1. 导入前调整设置
PUT /my_index/_settings
{
"index": {
"refresh_interval": "-1",
"number_of_replicas": 0,
"translog.durability": "async"
}
}
# 2. 执行批量导入...
# 3. 导入后恢复设置
PUT /my_index/_settings
{
"index": {
"refresh_interval": "1s",
"number_of_replicas": 1,
"translog.durability": "request"
}
}
# 4. 手动刷新并 force merge
POST /my_index/_refresh
POST /my_index/_forcemerge?max_num_segments=5
线程池配置
🔥 核心线程池
| 线程池 |
用途 |
关键参数 |
search |
搜索查询 |
size=25, queue=1000 |
write |
写入/更新/删除 |
size=16, queue=10000 |
get |
GET 请求 |
size=16, queue=1000 |
analyze |
分析请求 |
size=1, queue=16 |
refresh |
刷新操作 |
动态调整 |
flush |
flush 操作 |
动态调整 |
线程池类型
| 类型 |
说明 |
fixed |
固定大小,超出进队列 |
scaling |
动态伸缩(core → max) |
查看线程池状态
# 查看所有线程池
GET /_cat/thread_pool?v
# 查看详细信息
GET /_cat/thread_pool?v&h=name,active,queue,rejected,size,type
# 查看 search 线程池
GET /_cat/thread_pool/search?v
关键指标
- active:正在执行的线程数
- queue:等待队列中的任务数
- rejected:被拒绝的请求数(⚠️ 重要!)
⚠️ rejected 不为 0 怎么办?
-
search rejected:查询压力大
- 增加节点
- 优化查询语句
- 增加 queue_size(临时)
-
write rejected:写入压力大
内存与熔断器
🔥 熔断器参数
| 熔断器 |
默认限制 |
说明 |
total |
95% |
总内存限制 |
fielddata |
40% |
fielddata 缓存 |
request |
60% |
单个请求内存 |
inflight_requests |
100% |
传输中请求 |
详细说明
indices.breaker.total.limit # 总熔断器
indices.breaker.fielddata.limit # fielddata 熔断器
indices.breaker.request.limit # 请求熔断器
network.breaker.inflight_requests.limit # 传输熔断器
熔断器触发表现
# 查询报错示例
{
"error": {
"type": "circuit_breaking_exception",
"reason": "[parent] Data too large..."
}
}
调参建议
# 查看熔断器状态
GET /_nodes/stats/breaker
# 调整熔断器限制(谨慎操作)
PUT /_cluster/settings
{
"persistent": {
"indices.breaker.total.limit": "90%",
"indices.breaker.fielddata.limit": "30%",
"indices.breaker.request.limit": "50%"
}
}
内存相关参数
| 参数 |
说明 |
indices.memory.index_buffer_size |
索引缓冲区大小(默认10%) |
indices.fielddata.cache.size |
fielddata 缓存大小 |
indices.queries.cache.size |
查询缓存大小(默认10%) |
indices.requests.cache.size |
请求缓存大小(默认1%) |
搜索相关配置
🔥 核心参数
| 参数 |
默认值 |
说明 |
max_buckets |
65535 |
聚合桶最大数量 |
max_open_scroll_context |
500 |
最大 scroll 上下文数 |
default_search_timeout |
-1 |
默认搜索超时(-1=无限) |
max_keep_alive |
24h |
scroll 最大保持时间 |
调参示例
# 增加聚合桶限制
PUT /_cluster/settings
{
"persistent": {
"search.max_buckets": 100000
}
}
# 设置默认搜索超时
PUT /_cluster/settings
{
"persistent": {
"search.default_search_timeout": "30s"
}
}
# 查看当前 scroll 上下文
GET /_nodes/stats/indices/search
# 清除所有 scroll
DELETE /_search/scroll/_all
集群发现与故障检测
🔥 核心参数
| 参数 |
默认值 |
说明 |
leader_check.interval |
1000ms |
leader 检查间隔 |
leader_check.timeout |
10000ms |
leader 检查超时 |
leader_check.retry_count |
3 |
leader 检查重试次数 |
follower_check.interval |
1000ms |
follower 检查间隔 |
follower_check.timeout |
10000ms |
follower 检查超时 |
follower_check.retry_count |
3 |
follower 检查重试次数 |
故障检测逻辑
故障判定时间 = interval × retry_count + timeout
默认 = 1s × 3 + 10s = 13秒
调参场景
# 更快检测故障(适合稳定网络)
PUT /_cluster/settings
{
"persistent": {
"cluster.fault_detection.leader_check.timeout": "5000ms",
"cluster.fault_detection.follower_check.timeout": "5000ms"
}
}
# 更宽容的故障检测(适合不稳定网络)
PUT /_cluster/settings
{
"persistent": {
"cluster.fault_detection.leader_check.timeout": "30000ms",
"cluster.fault_detection.leader_check.retry_count": 5
}
}
常用调参命令
查看当前配置
# 查看所有集群配置
GET /_cluster/settings?include_defaults=true
# 只看 persistent 和 transient
GET /_cluster/settings
# 查看特定配置
GET /_cluster/settings?flat_settings=true&filter_path=**.recovery*
修改配置
# 持久化修改(推荐)
PUT /_cluster/settings
{
"persistent": {
"参数名": "参数值"
}
}
# 临时修改
PUT /_cluster/settings
{
"transient": {
"参数名": "参数值"
}
}
# 重置为默认值(设为 null)
PUT /_cluster/settings
{
"persistent": {
"参数名": null
}
}
常用监控命令
# 集群健康
GET /_cluster/health
# 节点状态
GET /_cat/nodes?v
# 分片状态
GET /_cat/shards?v
# 恢复进度
GET /_cat/recovery?v&active_only=true
# 未分配分片原因
GET /_cluster/allocation/explain
调参最佳实践
✅ 推荐做法
- 先测试后生产:在测试环境验证参数效果
- 使用 persistent:避免重启后配置丢失
- 记录变更:记录每次调参的原因和效果
- 监控指标:调参后观察相关监控指标
- 逐步调整:不要一次改太多参数
❌ 避免做法
- 直接修改 elasticsearch.yml(需要重启)
- 在业务高峰期调参
- 一次性调整多个参数
- 不了解参数含义就调整
- 忽略调参后的监控
快速参考卡片
扩容/恢复加速
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.node_concurrent_recoveries": 16,
"cluster.routing.allocation.cluster_concurrent_rebalance": 4,
"indices.recovery.max_bytes_per_sec": "200mb"
}
}
禁止分片移动(维护时)
PUT /_cluster/settings
{
"transient": {
"cluster.routing.allocation.enable": "none"
}
}
恢复分片分配
PUT /_cluster/settings
{
"transient": {
"cluster.routing.allocation.enable": "all"
}
}
解除索引只读
PUT /_all/_settings
{
"index.blocks.read_only_allow_delete": null
}
索引参数查看命令
查看索引设置
# 查看单个索引的所有设置
GET /my_index/_settings
# 查看包括默认值在内的所有设置
GET /my_index/_settings?include_defaults=true
# 查看多个索引设置
GET /index1,index2/_settings
# 查看所有索引设置
GET /_all/_settings
# 使用通配符
GET /log-*/_settings
查看索引 Mapping
# 查看索引 mapping
GET /my_index/_mapping
# 查看特定字段 mapping
GET /my_index/_mapping/field/field_name
查看索引统计
# 查看索引统计信息
GET /my_index/_stats
# 查看特定统计项
GET /my_index/_stats/docs,store,indexing,search
# 查看所有索引统计
GET /_stats
查看索引健康状态
# 查看索引列表
GET /_cat/indices?v
# 查看特定索引
GET /_cat/indices/my_index?v
# 按磁盘使用排序
GET /_cat/indices?v&s=store.size:desc
# 只看红色/黄色索引
GET /_cat/indices?v&health=red
GET /_cat/indices?v&health=yellow