面向 P6-P7+ 工程师 问题现场型 · 长文 约 9,500–11,000 字 信息截止 2026-08

ES 线上稳定性治理:
脑裂、磁盘水位、重平衡与 ILM

这篇文章不是 Elasticsearch 入门,而是给已经在跑生产集群的工程师一套可巡检、可预案的架构治理框架: 如何规避脑裂、如何在 flood_stage 之前止血、如何让扩容重平衡不打穿晚高峰,以及如何用 ILM 把「只进不出」的日志索引变成可审计的生命周期。

主线风格:问题现场 50% + 体系架构 35% + 框架 15% 版本假设:Elasticsearch 8.x(标注与 7.x 关键差异) 证据等级:官方文档优先,标注推断与生产经验
问题现场 · 复合场景

1同一凌晨窗口:为什么黄红绿、只读与双版本一起炸

复合场景 · 综合多家日志/检索平台值班复盘的典型链条,非指代具体单一事件 TYPICAL SCENARIO

某日志检索平台运行 Elasticsearch 8.11,三可用区部署:dedicated Master 3 台、Data 12 台。 某日凌晨机房 A 与 B 之间网络抖动持续约 90 秒,值班收到「集群状态 yellow → red → green」连环告警; 与此同时 Data 节点 es-data-07 磁盘使用率突破 95%,索引 logs-app-* 被标记只读, Filebeat bulk 大量 reject。网络恢复后,部分业务反馈「同一 document_id 出现两条版本不同的记录」—— 疑似短暂权威性窗口内的双写或客户端重试幂等缺失。

复盘叠出三层问题:Master 候选与 Data 角色曾在早期 POC 混部未收敛;磁盘仅依赖默认 flood_stage, 缺少低水位预警与带 delete 的 ILM;前一周刚扩容 4 台 Data,大规模 shard relocation 叠加晚高峰,查询 P99 抖动约 3 倍。 三类信号分别对应本篇四条治理回路:选举与 quorum、磁盘水位、重平衡节流、ILM 生命周期。

这段复合场景在日志平台与检索中台的值班复盘里反复出现。它暴露的核心不是「ES 难用」,而是稳定性是 多反馈回路耦合系统:Master 失联会冻结元数据变更;磁盘 flood 会触发只读与迁出;relocation 抬高 IO 与网络; ILM delete 失败则把水位线推回 flood。单点改参可能激活相邻回路——只解除只读而不释空间,会形成「解块 → 再锁」循环。

本篇定位「架构治理落地」,假设读者已掌握 T05 的分片副本与节点角色、T06 的查询优化与冷热分层基础。 我们不再讲「什么是 Master」,而聚焦:集群会不会挂、挂之前有没有信号、挂之后按什么顺序救。 与 T06 的边界可以这样划:T06 回答「查得慢怎么办」,本篇回答「写得进写不进、权威是否唯一、扩容是否引发绿色雪崩」。

ES 8.x 在 Master 选举上采用基于 term 的协调协议(与 7.x 一致),并移除 Zen Discovery 时代的 discovery.zen.minimum_master_nodes,改为由 cluster.initial_master_nodes 与 voting 配置推导 quorum。 若集群从 6.x 升级路径迁来,需核对是否残留旧参数。下文机制描述基于 8.x 官方文档与作者经验总结,具体阈值请在目标版本复测。

常见陷阱

索引 red 不等于脑裂——单分片无主也会 red。脑裂是集群元数据层的权威性问题,必须结合 Master 选举日志、 多节点上的 master_node / cluster state version,以及变更时间线交叉验证。 「双版本 document」也可能是客户端重试 + 缺少幂等,不宜未取证就对外宣称脑裂。

组织协同上建议三类责任人:平台团队负责集群参数、水位、ILM 模板;业务或数据团队负责索引命名与留存合规; SRE 负责告警、runbook 与 on-call 升级。检查表中的「责任人」列可按组织填入真实角色。 全文结构:现场 → 四层总览 → 四条机制 → 适合/不适合 → 应急 SOP 与巡检 → 决策矩阵收尾。

风格路由对齐 execution-plan 中 T07:问题现场 50%(复合场景贯穿各章)、体系架构 35%(反馈回路与失败窗口)、 框架 15%(告警到来时的决策顺序)。现场部分用同一复合场景串联,避免脑裂、磁盘、重平衡、ILM 彼此割裂; 架构部分强调四条回路如何互相激活;框架部分给出压力下的收窄顺序,便于 on-call 快速止血。

阅读建议:若你正在处理只读事故,可先跳第四章与第八章 SOP;若你在做扩容评审,先读第五章与检查表中的 rebalance 项; 若你在做集群新建,从第三章 quorum 与第六章 ILM 模板一次做对,比事后救火便宜一个数量级。

证据等级约定贯穿全文:标注「已核验事实」的条目对应官方文档语义;标注「生产经验」的阈值来自常见集群规格下的运维实践,必须在目标环境复测; 标注「机制推断」的排序(例如稳定性优先于成本)用于决策,而非声称官方强制。无来源的性能数字不会作为基线推荐。 版本假设为 Elasticsearch 8.x;若你仍在 7.x,选举与水位主线仍适用,但请核对 Zen 遗留参数是否清理干净。

体系总览 · 概念地图

2四层治理回路:选举、水位、重平衡、ILM 如何耦合

稳定性治理不是四本独立手册,而是四条回路共享同一张磁盘与同一条跨可用区链路。 理解耦合,才能在告警风暴里决定「先查什么、后改什么」。

图 1 · ES 稳定性四层治理与复合场景入口映射
自制示意图
复合场景入口 网络分区 / 疑似脑裂 Master 振荡 · 双版本疑云 磁盘 flood_stage 只读 bulk reject · cluster_block 扩容后绿色雪崩 recovery 占满 · P99 抖动 四层治理体系 Master / quorum 奇数 eligible dedicated + seed 磁盘三级水位 low / high / flood 只读安全阀 重平衡节流 allocation 窗口 recovery 带宽 ILM 四阶段 hot→warm→cold 必须含 delete 耦合点:flood 触发迁出 → 加重 recovery → 占磁盘/带宽 → 抬高水位 Master 不稳则 allocation 变更停滞;ILM 卡住则水位只升不降 沉淀:稳定性巡检检查表 + on-call 决策顺序 可写性 → Master 唯一性 → recovery 是否过量 → ILM 是否含 delete 值班时先分层定位红灯落在哪条回路,再决定改 quorum、水位、节流还是补 ILM
关键点:三条现场入口映射四条回路;磁盘问题同时牵动水位与 ILM;扩容牵动重平衡。沉淀层用检查表把回路闭环。
来源:Elasticsearch · Cluster formation / Disk-based shard allocation / Index lifecycle management(discovery · disk watermark · ILM)。版本假设 8.x。

各层答什么问题

层级核心机制答什么问题典型失败表现
选举term / quorum / voting exclusions谁有权改 cluster stateMaster 频繁切换、无法选举、疑似双权威
磁盘low / high / flood_stage节点还能不能接分片与写入只读锁定、bulk 403、解除后立刻再锁
重平衡allocation / recovery 节流自愈是否会打穿业务窗口green 但 P99 恶化、跨 AZ 带宽占满
ILMrollover / allocate / delete数据只进不出还是有出水口磁盘线性增长、explain 长期 ERROR
已核验事实

Elasticsearch 的磁盘水位基于各节点数据路径的可用空间判定;触及 flood stage 时,集群会为受影响索引设置 index.blocks.read_only_allow_delete,阻止继续写入以保护数据完整性。 详见官方 Disk-based shard allocation 文档。具体默认百分比以目标小版本为准,上线前用 GET _cluster/settings?include_defaults=true 核对。

组织协同:谁负责哪条回路

四条回路横跨平台、业务与 SRE。建议分工:平台负责 dedicated master、seed_hosts、水位与 ILM 模板; 业务负责索引命名、别名与留存天数;SRE 负责告警阈值、runbook 与 on-call 升级。扩容与大促变更由发布负责人召集三方会签, 避免「平台加了节点、业务不知情、SRE 未调 recovery」的三方错位。核心原则是:能写进模板与检查表的,不要只留在个人经验里。

失败窗口意识是本篇与「性能调优」最大的差别:从磁盘 85% 到只读可能只有数小时,从 Master 失联到选举完成可能只有数十秒。 窗口内运维决策的质量决定事故等级。后面四章分别把窗口拆开讲清,第八章再合成 on-call 顺序。

核心机制 · 选举与 quorum

3集群脑裂规避:quorum、discovery 与 voting exclusions

脑裂(split-brain)的本质是:网络分区或节点失联时,两个子集各自认为自己是合法 Master 并接受写入, 导致同一索引出现不一致的主分片权威版本。ES 8.x 通过「仅 master-eligible 参与选举」与「多数派投票」规避双主。 稳定性治理的第一块基石,是把选举失败窗口变成可预期的「少数派拒绝写入」,而不是「双主各自为政」。

如何识别疑似脑裂

典型信号:短时间内多个不同 node id 的 Master 变更;不同协调节点对同一 document_id 的 GET 返回不同 _seq_no; health 在 green/yellow/red 间快速振荡;极端情况下不同节点 _cluster/state?filter_path=master_node 不一致。 现场第一步应固定证据:多协调节点分别拉取 master_node 与 state version; 保存 Master 日志中 election 相关行;对照变更系统是否在窗口内执行重启、ACL 或 CNI 升级。

注意把「元数据权威性问题」与「分片级 red」分开:某个主分片未分配会造成索引 red,但 cluster state 仍可能由唯一 Master 正常发布。 反之,Master 振荡时健康色可能快速变化,但根因在协调层。复合场景中两者可能叠在一起——先固定 Master 是否唯一,再解释 red 分片,顺序反了会浪费黄金处置时间。

图 2 · Master-eligible 选举与 quorum 约束(简化)
自制示意图
Follower 跟随当前 Leader Candidate 选举超时发起投票 Leader (Master) 唯一更新 cluster state 超时 获 quorum 失去 quorum / 更高 term → 降级 生产拓扑约束(3 AZ) AZ-A · master-01 roles: [master] 1 票 AZ-B · master-02 roles: [master] 1 票 AZ-C · master-03 roles: [master] 1 票 · quorum=2 单 AZ 故障剩 2 票仍可形成多数派;偶数 eligible 或混部 Data+Master 会放大失败窗口 下线 Master 必须走 voting_config_exclusions,禁止同时替换半数以上 eligible
关键点:仅 Leader 可更新元数据;quorum = floor(N/2)+1;跨 AZ 必须保证任意单 AZ 故障后仍能凑齐多数派。
来源:Elasticsearch · Discovery and cluster formation / Voting configurations(modules-discovery · voting · exclusions)。

discovery 与 seed_hosts

节点发现依赖 discovery.seed_hosts(静态种子)或云插件。机制要点:新节点只需连上集群中任意一个可达节点, 即可通过集群成员协议获取完整列表;seed_hosts 应列出稳定可达的 master-eligible 地址。 与 7.x 差异:8.x 已移除 zen 前缀参数,统一为 seed_hosts;升级文档若仍引用 minimum_master_nodes,应迁移为正确的 eligible 计数与 voting 配置。

生产配置要点

  • master-eligible 必须为奇数(3 或 5),避免平分票无法形成多数派。
  • dedicated master:生产使用 node.roles: [ master ],与 Data 分离,避免 indexing / GC 与选举耦合。
  • seed_hosts:只列稳定可达的 master-eligible 地址,不要把全部 Data 塞进种子列表。
  • initial_master_nodes:仅首次 bootstrap;集群已 formed 后勿随意改写,否则可能触发非预期 bootstrap。
  • voting-only:跨机房可用 voting-only 拉平 quorum 而不承担 Master 写入延迟(需规划 tie-breaker)。
# elasticsearch.yml — ES 8.x dedicated master 示例
cluster.name: logs-prod
node.roles: [ master ]
node.name: es-master-01
discovery.seed_hosts:
  - es-master-01:9300
  - es-master-02:9300
  - es-master-03:9300
cluster.initial_master_nodes:
  - es-master-01
  - es-master-02
  - es-master-03

永久下线 master-eligible 时,先 POST _cluster/voting_config_exclusions?node_names=..., 待节点移出 voting 配置后再物理下线,避免「幽灵节点」占用席位导致无法达成多数派。 Master 替换必须逐台进行:若同时有 2 个处于 excluded 过渡态而剩余仅 2 个,任一再故障即丧失 quorum。

生产经验

复合场景里「Data 节点曾参与选举」往往源于 POC 阶段 node.roles: [ master, data, ingest ] 未收敛。 ES 8.x 默认仍允许多角色,但生产必须 dedicated master。一次 GC 停顿导致 Master 失联数十秒, 若同时存在多个 data+master,选举行为会与堆压力耦合,极易放大抖动。 24 小时内无计划变更却出现多次 Master 切换,应视为稳定性 incident,而非「自动恢复可忽略」。

配置项推荐原则风险反例
master-eligible 数量3 或 5(奇数)2 节点:任一故障即无法选举
node.rolesMaster 与 Data 分离全体 data+master 混部
seed_hosts仅列稳定 master列全部 data 造成发现噪声
跨 AZ剩余 AZ 仍能 quorum2+2 对称部署无 tie-breaker

与 K8s 的交叉(待验证推断,需结合 Operator):StatefulSet 若未限制并发,可能短暂同时重启多个 Master Pod; 建议 PDB minAvailable: 2(3 Master 场景),并配合 readiness 确保选主完成后再接入 Service。 ECK 已内置多数最佳实践,自建 ES on K8s 需自行补齐。

失败窗口与预防清单

即使 quorum 配置正确,网络分区期间少数派子集将无法选举 Master 并拒绝写入——这是预期行为(可用性换一致性)。 真正危险的失败窗口在于:分区恢复前若因错误配置出现双主,则产生数据分叉,事后几乎无法无损合并。 预防清单应写进变更系统,而不是停留在口头约定。

  1. master-eligible 固定为 3 或 5,禁止临时把 Data 节点改为 master「凑数」救火。
  2. 跨 AZ 部署时,确保任意单 AZ 故障后剩余 AZ 仍能形成 quorum;对称 2+2 无 tie-breaker 是反模式。
  3. 监控 master_not_discovered_exceptionorg.elasticsearch.cluster.coordination 选举日志。
  4. 永久下线 Master 的流程必须文档化,包含 voting exclusions 与回滚条件。
  5. 滚动替换 Master 时逐台进行,任意时刻在线 eligible 数始终满足奇数 quorum。

现场取证建议固定三件套:多协调节点上的 master_node 与 state version、Master 节点选举日志片段、 变更系统时间线。没有这三类证据,不宜对外宣称脑裂,避免把客户端重试问题误判为元数据分叉,从而采取错误的「强制选举」类处置。

核心机制 · 磁盘反馈回路

4磁盘打爆治理:三级水位与只读应急

磁盘打爆是 ES 生产最高频的 P0 之一。与脑裂不同,它通常有渐进信号:使用率上升 → 高水位拒绝新分片分配 → flood_stage 索引只读。理解水位反馈回路,才能在只读锁触发前完成清理或扩容。

故障现场:flood_stage 与误操作

【复合场景续】es-data-07 数据目录挂载点使用率 96%。日志出现 high / flood watermark exceeded, 该节点上索引被设 index.blocks.read_only_allow_delete: true。Bulk 返回 403 或 cluster_block_exception。 若多节点同时触达 flood,可能全集群写入停摆。

值班常见误操作:仅执行解除只读却未清理磁盘,数分钟后再次锁定,且 merge / recovery 可能加速消耗; 或为腾空间随意 DELETE 仍带 replica 的生产索引,导致 red 并触发更多 recovery。正确优先级通常是: 删除已确认过期的时序索引 → 清理 snapshot 失败遗留 → 扩容或迁 cold → 最后才动仍在用的 warm 索引。

还有一类隐性加速器:索引增长率在水位告警前 48~72 小时往往已经异常抬升(新业务接入、日志级别误开、某管道重复投递)。 因此磁盘治理的可观测性不能只盯使用率百分比,还要盯「每天新增多少 GB」。百分比告警是结果,增长率告警才是趋势。

图 3 · Data 节点磁盘三级水位反馈回路
自制示意图
磁盘采样 max mount % low 水位 默认约 85% · 停分配新分片 high 水位 默认约 90% · 尝试迁出 flood_stage 默认约 95% · 只读锁定 告警应早于 low 70/80/85 分级,勿对齐 flood 应急:释空间再解块 限流写入 · ILM execute 长期阀门 = ILM 水位是最后安全阀 失败窗口:high → flood 之间若清理跟不上,全速写入可在分钟级触顶 监控取 max mount,勿用节点多盘 avg;混合盘按挂载点分别告警
关键点:low 停新分配、high 尝试迁出、flood 只读锁定。告警必须早于 low;解除只读前磁盘必须回到 flood 以下。
来源:Elasticsearch · Disk-based shard allocation(disk-based-shard-allocation)。水位可用百分比或绝对值(如 20gb)。

参数边界与监控

GET _cluster/settings?include_defaults=true&filter_path=**.disk.watermark*

PUT _cluster/settings
{
  "transient": {
    "cluster.routing.allocation.disk.watermark.low": "80%",
    "cluster.routing.allocation.disk.watermark.high": "85%",
    "cluster.routing.allocation.disk.watermark.flood_stage": "90%"
  }
}

# 磁盘已降至 flood 以下后再解除
PUT logs-app-2026.08.01/_settings
{ "index.blocks.read_only_allow_delete": null }

作者经验总结(需结合扩容周期复测):生产可将 low/high/flood 设为比默认更紧(例如 75% / 80% / 85%), 更早触发 relocation,为 ILM 清理赢得时间。监控至少覆盖:节点级 max mount 使用率、索引增长率(GB/天)、 cluster blocks 事件与 relocating_shards。告警建议:70% 信息、80% 警告、85% 严重、90% 紧急—— 阈值必须早于 low,而非与 flood 对齐。

与 ILM 的联动关系

磁盘治理不能仅靠调水位。没有 delete / rollover 策略的 logs-* 索引,等价于「只进不出」的蓄水池。 第六章的 ILM 是磁盘稳定的上游阀门;水位线是最后一道安全阀。两者缺任一,复合场景中的只读事故都会复发。 应急处置若只解 block 不补阀门,等于把下一次 flood 的时钟重新上发条。

另一条容易忽视的回路:high watermark 触发迁出本身会消耗源节点与目标节点的磁盘与网络。 若多个节点同时逼近 high,relocation 可能「越搬越满」——源节点尚未释放足够空间,目标节点又被新分片推高。 此时应并行限流写入与加速过期删除,而不是单纯调高 recovery 带宽。SSD 与 HDD 混合集群建议按挂载点分别监控, 勿用节点级平均使用率掩盖单盘触顶。

若业务允许短暂停写,可临时用索引级 allocation require 把新写入导向磁盘健康节点子集(作者经验,仅作临时措施, 需评估 skew 加剧风险)。长期仍依赖 ILM 与容量规划,而非永久写隔离。

只读解除的纪律

解除 read_only_allow_delete 之前,至少确认三件事:触水节点的 max mount 已稳定低于 flood; 上游写入已被限流或确认不会瞬时打满;过期索引删除或扩容已产生可观测的可用空间回升。 三件事缺一,解块几乎必然复发。解块后应持续观察 15~30 分钟的磁盘斜率与 bulk 拒绝率,再宣布事故降级。

对「全集群只读」类事件,沟通口径建议分层:对业务说明写入暂停与预计恢复窗口;对平台说明触水节点清单与出水动作; 对管理层用失败窗口语言(从告警到只读用了多久、此前 70% 告警是否被忽略)推动告警阈值改革。 稳定性治理若不能改变告警与变更行为,技术参数改完仍会回到同一现场。

核心机制 · 分片重平衡

5分片重平衡:触发条件、节流与大集群抖动规避

Rebalance / relocation 是 ES 保证数据均匀分布的自愈能力,也是稳定性「隐形杀手」: 扩容、缩容、节点重启、水位迁出都会引起大量 segment 跨节点拷贝,占用磁盘 IO 与网络带宽。 目标不是「零 relocation」,而是把 relocation 限制在可预期窗口与带宽内。

故障现场:绿色雪崩

【复合场景续】Data 从 8 扩到 12 后,_cat/recovery?active_only=true 出现数百条 recovering; 大索引单分片数十 GB,recovery 持续数小时。晚高峰 search 线程池 queue 升高—— 集群 health 已是 green,业务体感却更卡。若维护窗外误开 allocation,或同时下线多台节点, 并发 relocation 可打满跨 AZ 带宽并连锁 timeout。

图 4 · 扩容维护窗口:allocation 与 recovery 节流节奏
自制示意图
1. 低峰公告 业务可接受抖动 2. enable none 冻结分配变更 3. 加入节点 完成 discovery 4. 调 recovery 并发与带宽上限 5. enable all 监控至恢复完成 反模式:高峰直接加节点 + 默认并发 recovery 短期性能常比扩容前更差;叠加磁盘迁出时 relocation 队列 double 大促前可设 rebalance.enable=none,结束后再恢复 观测:_cat/recovery 行数、recovery current、transport 与磁盘 util 相关性
关键点:扩容 SOP = 冻结分配 → 加节点 → 节流 → 再开放;「扩容解决一切」在 ES 上短期常失效。

触发条件与关键参数

分配器在节点加入/离开、触达 high watermark、手动 reroute、副本数变更、shrink/split 等情况下触发 relocation。 均衡不仅看分片个数,还看磁盘权重——「每节点分片数相同但磁盘差 30%」仍可能持续 relocation。

PUT _cluster/settings
{
  "persistent": {
    "cluster.routing.allocation.enable": "none"
  }
}
# 节点就绪后
PUT _cluster/settings
{
  "persistent": {
    "cluster.routing.allocation.enable": "all",
    "cluster.routing.allocation.node_concurrent_recoveries": 2,
    "indices.recovery.max_bytes_per_sec": "100mb"
  }
}
参数作用调优方向(经验,需压测)
node_concurrent_recoveries单节点并发 recovery大集群降至 2~4
indices.recovery.max_bytes_per_secrecovery 带宽上限低峰可提到 100~200mb/s
cluster.routing.rebalance.enable是否允许 rebalance大促前可 none
allocation.enable分配总开关维护窗 none,结束 all
常见陷阱

Rebalance 不消除业务热点。若 custom routing 把写入打到同一分片,_cat/allocation 显示分片数均衡, 但磁盘与查询热点仍在——这是数据模型问题。热点节点往往最先触 watermark,形成 「热点 → 迁出 → recovery → 更卡 → 重试放大」负反馈。优先用 rollover 切开写入热点,并控制单分片体积(见 T05)。

作者经验总结:在约 12 节点、总分片 8000+ 的集群,扩容 4 节点若不做 allocation none 窗口, recovery 峰值带宽可占跨 AZ 专线显著份额,连带 coordinating 节点 timeout。 扩容 SOP 应写入变更管理,并公告「查询可能抖动」窗口。

如何判断 relocation 是否过量

观测面建议同时看:_cat/recovery 活跃行数、节点作为 source/target 的 recovery 计数、 transport 发送量与磁盘 util。判读标准:若 recovery 持续超过一个业务高峰周期,且 search latency 与 recovery 带宽正相关, 说明并发过高或单分片过大——应优先通过 ILM rollover 缩小新分片体积,而非无限加节点。 「加节点」在未节流时会立刻制造更多 relocation,短期把问题放大。

分片重平衡在集群生命周期中是常态:每日 rollover、ILM allocate 到 warm、节点替换都会引起 relocation。 稳定性目标是可预期,而不是零事件。业务侧应对维护窗口内的延迟波动有熔断与降级预案; 平台侧应把「是否允许 rebalance」写进大促变更检查项,避免高峰自动均衡与业务峰值撞车。

变更管理系统里建议把扩容拆成可勾选步骤:低峰公告、allocation enable none、节点加入并确认 discovery、 设置 node_concurrent_recoveries 与 max_bytes_per_sec、allocation enable all、观察 recovery 完成度、再开放大促流量。 任一步被跳过,都更接近第一章的「绿色雪崩」。复合场景若叠加磁盘迁出,必须合并排期,而不是同一晚并行「扩容 + 清盘 + 大促」。

与第四章联动:若 relocation 由磁盘 high watermark 驱动,单纯降低 recovery 并发只会拉长「危险水位」停留时间。 正确做法是双轨:一边节流保护查询,一边加速出水(删过期、扩容、ILM execute)。只做节流不做出水, 等于让集群在高水位上慢跑,最终仍可能撞上 flood。

核心机制 · 索引生命周期

6ILM:hot-warm-cold-delete 作为磁盘上游阀门

ILM 是磁盘稳定与查询性能的长期阀门。T06 已从检索角度介绍 rollover 与冷热;本篇从稳定性视角强调: 没有 delete 阶段的 ILM 只是「搬家」,不是「出水」。水位线是最后安全阀,ILM 才是上游阀门。

图 5 · ILM 四阶段数据流转与磁盘占用变化
自制示意图
Hot 写入别名 · rollover 按大小/时间切开 data_hot / SSD Warm shrink / forcemerge allocate → data_warm 只读优化 Cold searchable snapshot 本地占用下降 依赖仓库可用 Delete 到期删除 磁盘终极释放 对齐合规留存 SLM 快照留存应略长于 ILM delete(例如 delete 30d / SLM 35d) 三目标冲突时:稳定性优先于成本——先保证 rollover + delete,再优化 cold 比例 验证:GET <index>/_ilm/explain · 检查 phase/step 与 is_write_index
关键点:Hot 控制单分片体积,Warm/Cold 控制成本,Delete 控制磁盘上限。缺 Delete = 蓄水池只进不出。
PUT _ilm/policy/logs-app-policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_primary_shard_size": "30gb",
            "max_age": "1d"
          }
        }
      },
      "warm": {
        "min_age": "2d",
        "actions": {
          "shrink": { "number_of_shards": 1 },
          "forcemerge": { "max_num_segments": 1 },
          "allocate": { "require": { "data": "warm" } }
        }
      },
      "cold": {
        "min_age": "14d",
        "actions": {
          "searchable_snapshot": {
            "snapshot_repository": "s3-repo"
          }
        }
      },
      "delete": {
        "min_age": "30d",
        "actions": { "delete": {} }
      }
    }
  }
}

常见失败模式

  • rollover 前提:写入必须打到带 is_write_index: true 的别名,否则 ILM 不触发。
  • shrink:目标分片数须能整除源分片数,索引需只读;卡住时 explain 停在 check-shrink-ready,旧分片仍占盘。
  • searchable snapshot:仓库故障会导致 cold 无限 retry,占用 Master 任务队列。
  • 多租户:按业务线拆分 ILM,勿全局一套 delete 天数,避免合规过度保留或过早删除。
  • 强制 execute:磁盘应急时可对卡住的索引执行 ILM 手动推进,但必须记录原因并在事后把模板修到可自动推进,避免「靠人工 execute 续命」。

模板绑定示例思路:索引模式 logs-app-* 绑定策略名与 index.lifecycle.rollover_alias; 首次创建写入索引时设置别名 is_write_index: true。接入后立刻用 explain 确认 phase 为 hot、step 非 ERROR。 任何「策略写了但磁盘仍涨」的投诉,第一反应应是 explain,而不是先调 flood 百分比。

机制推断

同一套 ILM 同时服务三个目标:hot 控制单分片大小(利于 recovery)、delete 控制磁盘上限(利于水位)、 warm/cold 控制硬件成本。三目标冲突时,应优先保证 delete 与 rollover 生效,再优化 cold 快照比例—— 这是稳定性优先于成本的治理排序,而非官方硬性规则。

SLM 与合规留存

delete 阶段之前,建议在 warm 末或 cold 初通过 SLM 保留合规快照。ES 8.x 中 SLM 与 ILM 独立运行,但策略必须对齐: 例如 ILM delete 30 天,则 SLM 至少保留 35 天,避免误删后无恢复路径。定期检查策略的 last_success, 以及仓库是否堆积失败的 IN_PROGRESS 快照。searchable snapshot 依赖同一仓库时,仓库不可用会同时击穿 cold 与备份两条防线。

delete 的 min_age 必须先对齐合规留存(安全、审计、业务合同),再谈磁盘目标。 delete 不可逆,建议先在非生产或小流量索引上验证 explain 全链路,再推广模板。 多租户场景按租户或业务线拆分策略,比运行时手工改 settings 更安全,也更可审计。

与 T06 的衔接:T06 侧重「查得慢」时的冷热查询优化;本篇侧重「存得满」时的稳定性。 同一套策略应同时满足 hot 控制单分片、delete 控制磁盘上限、warm/cold 控制成本。 分享评审时建议同时打开 _ilm/explain 与磁盘趋势图,避免只看策略 JSON 而看不到执行卡点。

新建集群或新业务接入时,把「索引模板 + ILM 策略 + 写入别名 + SLM」作为四件套门禁:缺别名则 rollover 永不触发; 缺 delete 则磁盘必然线性上涨;缺 SLM 则误删不可恢复。门禁放在创建之前,比放在 flood 之后便宜得多。

边界判断 · 适合 / 不适合

7这套稳定性治理适合什么,不适合什么

四层回路适合「有持续写入、有容量增长、需要跨 AZ 高可用」的生产检索/日志集群。 它不替代容量规划(T05),也不替代查询语句调优(T06)。

适合继续用这套治理

  • 时序日志 / 埋点索引,每日 rollover、有明确留存期
  • 多 AZ 部署且已能配 3/5 dedicated master
  • 磁盘增长可预测,可接入 ILM + SLM
  • 扩容/升级有变更窗口,能接受节流后的恢复时长
  • 平台与 SRE 能执行周巡检与大促前检查表

不适合硬套或需先改造

  • 单节点或 2 节点「伪高可用」——先补 eligible,再谈 quorum
  • 把 ES 当强一致主库、依赖跨分区双写合并——模型错位
  • 无限保留全量热数据且无对象存储预算——ILM cold 无法落地
  • 业务要求 7×24 零抖动却频繁强制全局 rebalance——目标冲突
  • 尚无索引命名规范与别名体系——先补模板再上 ILM
生产经验

若集群稳定性已达标但容器层仍出现 OOMKilled 或探针误杀,应联动 T10 / T17,而不是继续只拧 ES 水位。 ES 参数解决的是「分片与元数据回路」;运行时合同解决的是「进程是否被内核或 kubelet 杀掉」。 两者同时红灯时,先分清是 cluster_block 还是 Pod 重启,再决定改哪一层。

边界案例:何时该拆集群而不是继续拧参

当单一集群承载多条业务线、留存策略冲突、写入峰值彼此挤压时,继续收紧水位或加大 recovery 往往只是把故障在租户间转移。 此时更适合按业务域拆分集群或至少拆分 ILM 与节点属性(hot/warm 标签),让失败域变小。 反之,若问题仅是缺少 delete、Master 混部、扩容无窗口,则继续在本套治理内闭环即可,不必过早拆集群。

判断口诀:参数能闭合的回路用参数,组织与合规冲突用隔离,模型错位用迁移。 把 ES 当主库强一致写入、把无限热数据当廉价对象存储,都属于模型错位,拧水位解决不了。

生产实践 · SOP 与巡检

8应急 SOP、决策顺序与稳定性巡检检查表

框架层只解决「先查什么、后查什么」。把稳定性当作多回路耦合:Master 失联会暂停 allocation 变更; 磁盘 flood 触发 relocation;relocation 抬高负载;ILM delete 失败推高磁盘。决策顺序比单条命令更重要。

图 6 · on-call 稳定性告警决策顺序
自制示意图
1. 是否可写 health / blocks 2. Master 唯一 选举日志 / state 3. recovery 过量? _cat/recovery 4. ILM / delete _ilm/explain 5. 结构债 联动 T05/T06 只读 → 走磁盘 SOP;Master 振荡 → 走选举/网络;green 却慢 → 查 recovery 磁盘线性增长 → 查 ILM delete;分片过多/过大 → 回 T05 容量与 T06 查询 红灯时避免直接重启全部 Data——可能扩大 unassigned
关键点:先可写性,再权威性,再自愈是否过量,再生命周期,最后才谈结构性容量债。

磁盘只读应急 SOP

  1. 确认范围GET _cat/nodes?v&h=name,disk.used_percent,disk.avail,定位触水节点与索引。
  2. 止血写入:上游限流或暂停非关键 ingest,避免解块后立即再打满。
  3. 释放空间:按优先级删过期索引、强制 ILM execute、或扩容磁盘。
  4. 解除只读:使用率稳定低于 flood 后,逐索引或批量解除 block。
  5. 预防闭环:补 ILM delete、磁盘 70% 告警、定期 _cat/allocation 审计 skew。
告警类型首选章节关键命令
cluster_block_exception第 4 章磁盘_cat/nodes_cluster/settings
Master 频繁切换第 3 章脑裂Master 日志、_cluster/health
查询突然变慢且 green第 5 章重平衡_cat/recovery
磁盘线性增长第 6 章 ILM_ilm/explain_cat/indices

稳定性巡检检查表

建议每周自动化脚本 + 每月人工 spot check,大促前必跑一轮。可直接复制到 Wiki。

检查项标准责任人
Master 角色隔离仅 dedicated master,数量奇数 3/5;无 data+master 混部平台/SRE
quorum 跨 AZ任意单 AZ 故障后剩余仍过半数;文档化 voting-only架构
discovery.seed_hosts仅列稳定 master;无过期 IP平台
磁盘峰值Data 节点 max mount < 约定阈值(如 75%);skew < 15%SRE
水位配置low/high/flood 已显式设置并与告警对齐平台
只读 block无异常 read_only*;若有则关联工单值班
分片密度按堆内存与规格控制分片总数;避免单节点分片爆炸平台
recovery 队列常态 active recovery 有上限;持续高位查扩容计划SRE
大促 rebalance大促前评估 rebalance.enable;变更窗评审 allocation发布负责人
ILM 覆盖时序索引绑定 ILM,含 delete 与合规留存数据负责人
ILM 健康explain 无长期 ERROR;rollover 别名正确平台
快照仓库SLM 近 7 日成功;searchable snapshot 失败告警已接入备份负责人
应急预案磁盘只读、Master 全失联、全 red 三类 runbook 可检索SRE
升级兼容大版本升级前评审 deprecated settings;升级窗 allocation none + 快照平台
跨系列一致性ILM rollover 大小与 T05 分片规划一致;查询别名不含已删模式平台+业务

巡检脚本可将上表映射为自动化 probe:每日 Cron 调用 _cat/nodes_ilm/explain_cluster/health, 失败项开 ticket。人工 spot check 每月抽样 2 个业务索引,从创建到 delete 全链路走读 ILM explain, 确认无「卡在 warm 三十天」类僵尸索引。

框架使用示例

某晚告警「bulk reject + 部分索引 red」。按序执行:先看 _cat/indices?v&health=red 判断是单索引还是集群级; 若伴随 read_only block,走第四章磁盘路径;若 red 且无 block,用 GET _cluster/allocation/explain 看 unassigned 原因, 可能是第五章 relocation 卡住或第三章 Master 不稳。避免在 red 时直接重启全部 Data 节点——可能扩大 unassigned 范围。

组织上建议把本篇检查表粘进大促与扩容变更模板:平台勾选 Master / 水位 / ILM,SRE 勾选告警与 runbook, 业务勾选留存合规。缺一项就开 blocker,而不是依赖值班记忆。tabletop 演练可问两题:磁盘从 70% 到只读的历史最短窗口是多少; 最近一次扩容是否评估过 rebalance 带宽。有真实数据更好,无则用检查表推演。

决策框架 · 收尾

9决策矩阵、相邻知识地图与延伸

ES 线上稳定性不是「记住几个水位百分比」,而是在选举权威、磁盘反馈、重平衡节流、生命周期出水 四条线上同时成立。遇到红灯时,用下表决定继续调参、迁移模型,还是先补齐相邻能力。

决策矩阵:继续 / 迁移 / 选型

信号 / 处境继续(调参)迁移(换模型)选型补充
flood 只读反复触发 收紧水位、限流、强制 ILM delete 热数据无限保留则迁对象存储 / 拆集群 先补 delete,再谈冷热节点硬件
Master 频繁切换 dedicated master、查网络与 GC 2 节点伪 HA 则扩到 3/5 eligible K8s 场景补 PDB / 滚动并发限制
扩容后 green 却更慢 allocation 窗口 + recovery 节流 分片过大则对新索引改规划并 rollover 联动 T05 单分片体积建议
ILM explain 长期 ERROR 修 shrink/别名/仓库后重试 策略与合规冲突则按租户拆策略 SLM 留存略长于 delete
疑似双版本 document 取证 Master/state version;修客户端幂等 若误把 ES 当强一致主库,迁回主库模型 勿未取证宣称脑裂
已核验事实

永久移除 master-eligible 节点前,应使用 voting configuration exclusions API, 确保集群能在节点离线后继续形成合法 voting 配置。详见官方 Voting exclusions 文档。 集群已形成后,cluster.initial_master_nodes 不应再作为日常运维旋钮随意改写。

相邻知识地图

  • T05 ES 核心底层原理:分片、副本、节点角色与容量估算——本篇治理的前提模型。
  • T06 ES 检索性能调优:查得慢时的语句与冷热优化;与本篇共享 ILM,但目标不同。
  • T10 容器化 JVM 适配:ES 进程跑在容器内时的堆与 cgroup 合同。
  • T17 K8s 生产稳定性:PDB、探针与优雅停机,避免滚动时同时打掉多个 Master。
  • T19 Kafka 高可靠:上游 ingest 背压与 bulk reject 的联动治理。

要点沉淀

  • 脑裂:奇数 quorum + dedicated master + 正确 seed;下线走 voting exclusions。
  • 磁盘:水位是最后安全阀;先释空间再解 block;告警必须早于 low。
  • 重平衡:扩容用冻结分配与 recovery 节流,避免绿色雪崩。
  • ILM:必须含 delete;rollover 控制单分片;SLM 与 delete 对齐对齐。
  • 闭环:检查表管事前,SOP 管事中,决策矩阵管「继续还是迁移」。

回到第一章的复合场景:当黄红绿振荡、只读与疑似双版本同时出现时,不要平行开三场无重点的战争。 先分层——可写性、Master 权威、recovery 是否过量、ILM 是否出水——再决定改 quorum、水位、节流还是补 delete。 分层对了,往往一处止血能熄两盏灯;分层错了,只会把 recovery 与只读循环放大。 同板块路径是 T05 建模型 → T06 优化读路径 → 本篇补齐写路径与集群级失败模式。 稳定性治理的终点不是参数表漂亮,而是值班不再被同一类红灯反复叫醒。

分享讨论环节建议准备两类题:其一,贵司 ES 磁盘从 70% 到只读的历史最短窗口是多少;其二,最近一次扩容是否评估过 rebalance 带宽。 有真实数据更好,无则用第八章检查表做 tabletop。把检查表粘到变更工单,并与 flood_stage、Master 失联、red 索引数等告警绑定, 使配置治理与运行时信号形成反馈回路——这才是「架构治理落地」相对「原理讲解」的增量。

最后强调证据纪律:默认水位百分比、recovery 默认带宽、具体小版本行为,必须以目标集群的 include_defaults 与官方对应版本文档为准。本文给出的经验阈值用于建立判断顺序,不是可直接照抄的生产基线。 先理解回路,再填写你们自己的数字,才是可辩护的稳定性工程。

把本篇检查表、磁盘只读 SOP 与扩容节流节奏固化进团队 runbook 之后,再回头看第一章的复合场景,会发现它不再是「倒霉的叠加」, 而是四条回路同时失守的可预防结果。预防比救火便宜,分层比平行救火更快——这是 ES 稳定性治理要留下的工程习惯。