elasticsearch.yml 里既能出现静态配置,也能出现动态配置;PUT _cluster/settings 只能修改动态的集群配置;索引又有一套自己的静态与动态规则。只按“写在哪个文件里”记忆,配置边界很快就会混乱。

本文面向自建 Elasticsearch 8.x/9.x 集群,按作用域、载体和生效时机建立一棵完整目录树。Elastic 的滚动文档会随版本增加、废弃或调整具体键。本文列出三组完整清单:官方配置参考的全部一级类别、全部索引设置模块,以及全部配置载体和更新路径。具体键的默认值与限定条件仍以目标版本的官方参考为准。

静态与动态先按生命周期判断

集群与节点配置里的 Static 表示节点启动后不能在线重载,必须在未启动或已停止的节点上修改,再通过重启生效。Dynamic 表示运行中的集群可以通过 Cluster update settings API 修改。

索引配置的定义不同。动态索引设置可以在打开的索引上修改;静态索引设置通常只能在创建索引时、关闭索引后,或通过 reopen=true 让 Elasticsearch 自动关闭并重新打开索引时修改。具体设置还可能更严格,例如 index.number_of_shards 只能在创建索引时确定,关闭索引也不能改。

图 1:Elasticsearch 配置生命周期树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Elasticsearch setting
├── cluster / node setting
│ ├── [S] Static
│ │ ├── 写入 elasticsearch.yml
│ │ ├── 在每个相关节点保持一致或按节点分别设置
│ │ └── 重启相关节点后生效
│ └── [D] Dynamic
│ ├── 首选 PUT _cluster/settings
│ ├── persistent:跨集群重启保留
│ ├── transient:重启后清除,官方不再推荐
│ └── 也能写入 elasticsearch.yml,但会失去在线更新优势
├── index setting
│ ├── [IS-C] creation-only static
│ │ ├── index.number_of_shards
│ │ └── index.sort.*
│ ├── [IS-R] reopenable static
│ │ ├── index.number_of_routing_shards(8.x;9.4.0 起废弃)
│ │ ├── 关闭索引后修改
│ │ └── 或 PUT /index/_settings?reopen=true
│ └── [ID] Dynamic
│ └── 打开的索引可直接 PUT /index/_settings
└── secure setting
├── [K-S] Secure:写入 elasticsearch.keystore
├── [K-R] Secure + Reloadable:调用 reload API 在线重载
└── [K-NR] Secure + non-reloadable:更新后重启节点

这里最重要的边界是:配置文件不是生命周期。动态集群配置也可以写进 elasticsearch.yml,但它不会因此变成静态配置;elasticsearch.yml 中已有的动态值,还可能被 cluster state 里的 persistent 或 transient 值覆盖。

四类配置载体互不替代

Elasticsearch 的配置不只在 elasticsearch.yml。JVM 参数、Log4j 2 和安全配置都有独立载体;集群与索引的在线值则保存在 cluster state 的不同部分。

图 2:配置载体与生效路径树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Elasticsearch configuration
├── process startup files
│ ├── elasticsearch.yml
│ │ ├── cluster / node static settings
│ │ ├── dynamic cluster settings 的启动默认值
│ │ └── ${ENV_VAR} 环境变量替换
│ ├── jvm.options.d/*.options
│ │ ├── -Xms / -Xmx
│ │ ├── -XX:HeapDumpPath
│ │ ├── -XX:ErrorFile
│ │ └── -Xlog:... GC logging
│ ├── log4j2.properties
│ │ ├── appender
│ │ ├── layout
│ │ ├── rolling policy
│ │ └── file retention
│ └── elasticsearch.keystore
│ ├── cloud / repository credentials
│ ├── realm / bind credentials
│ └── other settings marked Secure
├── cluster state
│ ├── persistent cluster settings
│ ├── transient cluster settings
│ └── index metadata
│ ├── index settings
│ ├── mappings
│ └── aliases
└── runtime update APIs
├── PUT _cluster/settings
├── PUT /index/_settings
├── POST _nodes/reload_secure_settings
└── logger.* dynamic logging level

生产环境不要直接修改发行包自带的根 jvm.options。官方建议在 jvm.options.d/ 中增加自定义 .options 文件。ES_JAVA_OPTS 适合测试和开发,生产环境仍应使用 options 文件。

Log4j 2 的输出格式、滚动和保留策略属于 log4j2.properties;日志级别还可以使用 logger.* 动态集群设置临时或持久调整。这两个入口控制的不是同一件事。

动态集群设置有固定优先级

同一个动态集群设置可能同时出现在 transient、persistent、elasticsearch.yml 和默认值中。Elasticsearch 按固定优先级取最终值。

图 3:动态集群配置优先级树

1
2
3
4
5
6
7
8
9
10
effective cluster setting
└── first defined value wins
├── 1. transient cluster setting
│ └── 最高优先级;可能在集群不稳定时意外清除,不推荐使用
├── 2. persistent cluster setting
│ └── 推荐的动态配置保存方式;集群重启后仍保留
├── 3. elasticsearch.yml
│ └── 适合作为静态配置或节点启动默认值
└── 4. built-in default
└── 目标版本内置默认值

这个优先级只适用于动态集群设置,不能套到索引设置、JVM 参数或 keystore。修改 elasticsearch.yml 后发现值没有变化时,应先检查 persistent 和 transient 层,而不是继续重启节点。

查看全部显式值和默认值:

1
GET /_cluster/settings?include_defaults=true&flat_settings=true

推荐使用 persistent 更新:

1
2
3
4
5
6
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": "primaries"
}
}

移除某一层 API 覆盖时写 null,不要猜测默认值并把它硬编码回去。移除 persistent 和 transient 后,最终值还可能回落到 elasticsearch.yml,只有文件层也没有定义时才使用产品默认值:

1
2
3
4
5
6
7
8
9
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.enable": null
},
"transient": {
"cluster.routing.allocation.enable": null
}
}

自建集群的启动配置树

节点能否启动、加入哪个集群、监听哪些地址、使用哪些目录,主要由静态配置决定。下面的树覆盖自建集群最常见的启动配置面;标记为 [S] 的键需要重启相关节点。

图 4:节点启动与集群形成配置树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
elasticsearch.yml
├── identity
│ ├── [S] cluster.name
│ ├── [S] node.name
│ ├── [S] node.roles
│ └── [S] node.attr.*
├── storage paths
│ ├── [S] path.data
│ ├── [S] path.logs
│ └── [S] path.repo
├── memory and bootstrap
│ ├── [S] bootstrap.memory_lock
│ └── [S] node.store.allow_mmap
├── network
│ ├── [S] network.host
│ ├── [S] network.bind_host
│ ├── [S] network.publish_host
│ ├── [S] http.host / http.port
│ └── [S] transport.host / transport.port
├── discovery
│ ├── [S] discovery.seed_hosts
│ ├── [S] discovery.seed_providers
│ ├── [S] discovery.type
│ └── [S] cluster.initial_master_nodes
│ ├── 只用于全新集群首次引导
│ └── 集群形成后删除,重启或扩容时不得再次设置
├── security bootstrap
│ ├── [S] xpack.security.enabled
│ ├── [S] xpack.security.http.ssl.enabled / .keystore.path
│ ├── [S] xpack.security.transport.ssl.enabled / .keystore.path
│ ├── [K] xpack.security.http.ssl.keystore.secure_password
│ ├── [K] xpack.security.transport.ssl.keystore.secure_password
│ └── [K] realm / bind credentials
└── feature participation
├── [S] xpack.ml.enabled
├── [S] xpack.security.audit.enabled
└── [S] feature-specific node capabilities

一次滚动修改静态配置的最小顺序是:确认目标键确实为 Static;修改一个节点;停止并启动该节点;等待它重新加入且集群恢复到预期状态;再处理下一个节点。cluster.name 一类全局身份配置需要完整集群重启,不能让一半节点使用旧值、另一半使用新值。

官方配置参考的全部一级类别

当前滚动版 Elasticsearch configuration reference 的正文示例与侧栏导航合计覆盖 36 个一级配置页。一个类别里可能同时有 Static、Dynamic、Secure 和 Reloadable 设置,因此类别名称不能直接推出生命周期,必须继续查看具体键旁边的标记。

图 5:Elasticsearch 官方配置类别全树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
Elasticsearch configuration reference
├── security and governance
│ ├── Auditing
│ ├── Cluster state encryption
│ ├── License
│ ├── Security
│ └── Watcher
├── cluster formation and topology
│ ├── Cluster formation and discovery
│ ├── Local gateway
│ ├── Miscellaneous cluster settings
│ ├── Nodes
│ ├── Networking
│ ├── Path
│ ├── Remote clusters
│ └── Shard routing
├── data lifecycle and replication
│ ├── Cross-cluster replication
│ ├── Data stream lifecycle
│ ├── Index lifecycle management
│ ├── Index management
│ ├── Index recovery
│ ├── Snapshot and restore
│ └── Transforms
├── indexing and ingest
│ ├── Enrich settings
│ ├── Index buffer
│ ├── Indexing pressure
│ ├── Inference
│ └── Ingest
├── search and cache
│ ├── ES|QL Data Federation settings
│ ├── Field data cache
│ ├── Node query cache
│ ├── Search
│ └── Shard request cache
├── resource protection
│ ├── Circuit breaker
│ ├── Merge resource limits
│ └── Thread pools
└── operations and observability
├── Health diagnostic
├── Machine learning
└── Monitoring

这棵树的用途是防漏项,不是把整类配置粗暴地判成静态或动态。同一个 Networking 类别里,监听地址通常是 Static,而某些统计采集开关可以是 Dynamic;同一个 discovery 文档里也同时存在 discovery.type 这样的 Static 设置和文件系统健康检查阈值这样的 Dynamic 设置。Cluster state encryption 和 ES|QL Data Federation 属于当前 9.x 滚动文档新增的版本敏感区域,其中 Data Federation 仍有实验性与部署类型限制,8.x 集群不能照抄。

动态集群配置的常见落点

动态集群设置影响整个集群,最终值发布到各节点。下面列出的具体键都应在目标版本文档中再次确认标记和取值范围。

图 6:动态集群配置树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
PUT _cluster/settings
└── persistent
├── shard allocation and routing
│ ├── cluster.routing.allocation.enable
│ ├── cluster.routing.allocation.exclude.*
│ ├── cluster.routing.allocation.awareness.*
│ ├── cluster.routing.rebalance.enable
│ ├── cluster.routing.allocation.disk.watermark.low
│ ├── cluster.routing.allocation.disk.watermark.high
│ └── cluster.routing.allocation.disk.watermark.flood_stage
├── recovery and concurrency
│ ├── cluster.routing.allocation.node_concurrent_*_recoveries
│ ├── cluster.routing.allocation.cluster_concurrent_rebalance
│ └── indices.recovery.max_bytes_per_sec
├── cluster protection
│ ├── cluster.blocks.read_only
│ ├── cluster.blocks.read_only_allow_delete
│ ├── cluster.max_shards_per_node
│ ├── indices.breaker.request.limit / .overhead
│ └── network.breaker.inflight_requests.limit / .overhead
├── search and task behavior
│ ├── search.max_buckets
│ ├── async_search.default_keep_alive
│ ├── async_search.max_keep_alive
│ └── cluster.persistent_tasks.allocation.*
└── diagnostics
├── logger.*
├── health.periodic_logger.*
└── monitor.fs.health.slow_path_logging_threshold

动态不等于安全。调高 breaker、并发恢复、最大 bucket 或 shard 上限,可能把原本受控的拒绝变成堆内存、网络或磁盘故障。Cloud Hosted 和 ECE 也不会替使用者拦截 Cluster update settings API 中的所有危险值。

索引设置有独立的静态与动态边界

当前 Index settings 导航包含 14 个配置面。General 同时包含 creation-only static 和 dynamic 设置;Time series 等模块也可能混合多种生命周期。

图 7:索引设置模块全树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Index settings
├── General
│ ├── [IS-C] index.number_of_shards
│ ├── [IS-R] index.number_of_routing_shards(8.x;9.4.0 起废弃)
│ ├── [ID] index.number_of_replicas
│ ├── [ID] index.auto_expand_replicas
│ ├── [ID] index.refresh_interval
│ ├── [ID] index.max_result_window
│ ├── [ID] index.search.idle.after
│ └── [IS-R] index.codec
├── Index shard allocation
│ └── [ID] index.routing.allocation.*
├── History retention
│ └── [ID] index.soft_deletes.retention_lease.period
├── Index blocks
│ └── [ID] index.blocks.*
├── Mapping limits
│ └── [ID] index.mapping.*.limit
├── Merge
│ └── [ID] index.merge.*
├── Similarities
│ └── [IS-R] index.similarity.*
├── Slowlog
│ ├── [ID] index.search.slowlog.*
│ └── [ID] index.indexing.slowlog.*
├── Sorting
│ └── [IS-C] index.sort.*
├── Store
│ └── [IS-R] index.store.type
├── Source
│ ├── [IS-R] index.mapping.source.mode
│ ├── [IS-R] index.recovery.use_synthetic_source
│ └── [IS-R] index.mapping.synthetic_source_keep
├── Time series
│ ├── [IS-C] index.mode
│ ├── [IS-C] index.routing_path
│ ├── [IS-R] index.time_series.start_time
│ ├── [ID] index.time_series.end_time
│ ├── [IS-R] index.time_series.look_ahead_time
│ ├── [IS-R] index.time_series.look_back_time
│ └── [ID] index.mapping.dimension_fields.limit
├── Translog
│ ├── [ID] index.translog.durability
│ ├── [ID] index.translog.sync_interval
│ └── [ID] index.translog.flush_threshold_size
└── Text analysis
├── [IS-R] analysis.analyzer.*
├── [IS-R] analysis.tokenizer.*
├── [IS-R] analysis.filter.*
└── [IS-R] analysis.char_filter.*

树中把 Source 和 Text analysis 单独列出,是因为它们在当前索引设置导航中各有独立页面。合计就是文章需要覆盖的 14 个索引配置面。

动态索引设置可直接更新:

1
2
3
4
5
6
7
PUT /logs-2026.11/_settings
{
"index": {
"number_of_replicas": 2,
"refresh_interval": "30s"
}
}

需要重新打开的静态索引设置可以显式关闭再修改,也可以在目标版本支持时使用 reopen=true:

1
2
3
4
5
6
PUT /logs-2026.11/_settings?reopen=true
{
"index": {
"codec": "best_compression"
}
}

reopen=true 不是绕过 creation-only 限制的开关。主分片数需要通过 split、shrink 或 reindex 改变数据布局,不能直接修改 index.number_of_shards。

index.number_of_routing_shards 还带有版本边界:它在 8.x 和较早 9.x 中用于预留 split 的路由空间,当前滚动文档已将其标记为 9.4.0 起废弃。升级前应按目标版本重新核对,不能把旧版本的用途当成长期不变的行为。

Secure 与 Reloadable 是第二组标签

Secure 描述存储位置,Reloadable 描述是否能在线重载。它们与 Static/Dynamic 不是同一套分类轴。只有官方标为 Secure 的设置才能放进 Elasticsearch keystore;把普通配置塞入 keystore 会在校验或启动时失败。

图 8:安全配置生命周期树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
secure setting
├── write path
│ ├── self-managed
│ │ └── bin/elasticsearch-keystore add <setting>
│ ├── ECK
│ │ └── Kubernetes Secret → spec.secureSettings
│ └── ECH / ECE
│ └── deployment keystore UI / API
├── distribution
│ ├── 每个节点都有自己的 keystore
│ └── 除非具体文档另有说明,各节点值应一致
└── activation
├── [K-R] Secure + Reloadable
│ ├── 先更新所有节点的值
│ └── POST _nodes/reload_secure_settings
└── [K-NR] Secure only
└── 更新后滚动重启节点

调用重载 API 时,Elasticsearch 会解密、重读并校验整个 keystore,但只把标记为 Reloadable 的设置应用到运行时。其他修改仍要等下次节点重启。

1
2
3
4
POST /_nodes/reload_secure_settings
{
"secure_settings_password": "keystore-password"
}

密码保护的 keystore 不应把密码硬编码进脚本或版本库。示例只表示请求结构。

怎样取得目标集群的完整配置视图

官方参考告诉配置能不能改,运行中的 API 告诉当前值是什么。单个 API 无法返回 JVM、日志、节点、集群、索引和 keystore 的全部内容,需要按载体分别采集。

图 9:配置盘点树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
configuration inventory
├── node startup settings
│ ├── GET /_nodes/settings?flat_settings=true
│ ├── elasticsearch.yml
│ ├── jvm.options.d/*.options
│ └── log4j2.properties
├── cluster settings
│ └── GET /_cluster/settings?include_defaults=true&flat_settings=true
│ ├── persistent
│ ├── transient
│ └── defaults
├── index settings
│ └── GET /_all/_settings?include_defaults=true&flat_settings=true
│ ├── explicit settings
│ └── defaults
└── secure settings
├── bin/elasticsearch-keystore list
└── 只盘点键名,不导出秘密值

include_defaults=true 很适合排查,但 Cluster get settings API 补充的 YAML/default 视图来自某个节点,不能单独证明所有节点的文件配置一致;节点差异还要结合 GET /_nodes/settings。返回的默认值也不能直接保存为配置文件。默认值会随版本演进;把它们全部显式化,会制造升级漂移,也会遮住真正有意修改的少数配置。

更新前按这棵树选择操作

图 10:配置更新决策树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
准备修改一个 setting
├── 官方文档是否标记 Secure?
│ ├── 是
│ │ ├── 是否标记 Reloadable?
│ │ │ ├── 是 → 更新所有节点 keystore → reload_secure_settings
│ │ │ └── 否 → 更新所有节点 keystore → 滚动重启
│ │ └── 不写入 elasticsearch.yml 或环境变量
│ └── 否
│ ├── 是否是 index.* setting?
│ │ ├── Dynamic → PUT /index/_settings
│ │ ├── reopenable Static → 关闭索引或 reopen=true
│ │ └── creation-only → 新索引 / split / shrink / reindex
│ └── 是否是 cluster / node setting?
│ ├── Dynamic → PUT /_cluster/settings 的 persistent
│ └── Static → elasticsearch.yml → 滚动或完整重启
└── 修改后验证
├── API 回读 effective value
├── 检查 cluster health 与节点数量
├── 检查 rejected、GC、磁盘和恢复流量
└── 在变更记录中保存旧值、目标值与回滚路径

这棵决策树比背配置键更稳定。新版本增加设置时,只要文档仍标明作用域和生命周期,就能沿同一路径决定写在哪里、是否需要重启以及怎样验证。

与本系列其他文章的边界

《深入 Elasticsearch(01)》已经解释 cluster state 中的 persistent cluster settings 在哪里;《深入 Elasticsearch(16)》使用过 shard allocation 的 persistent 更新;《深入 Elasticsearch(19)》给出了 node.roles、发现和故障域配置。那些文章分别讨论架构、运维动作和生产拓扑,没有建立完整的配置生命周期。

本文补齐的是配置目录和更新规则。实际调优仍要回到相应专题:分片与副本看第 10、11 篇,选举与集群形成看第 12 篇,性能设置看第 14 篇,监控与故障排查看第 16 篇,生产节点配置看第 19 篇。

参考资料