1同一凌晨窗口:为什么黄红绿、只读与双版本一起炸
某日志检索平台运行 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 如何耦合
稳定性治理不是四本独立手册,而是四条回路共享同一张磁盘与同一条跨可用区链路。 理解耦合,才能在告警风暴里决定「先查什么、后改什么」。
各层答什么问题
| 层级 | 核心机制 | 答什么问题 | 典型失败表现 |
|---|---|---|---|
| 选举 | term / quorum / voting exclusions | 谁有权改 cluster state | Master 频繁切换、无法选举、疑似双权威 |
| 磁盘 | low / high / flood_stage | 节点还能不能接分片与写入 | 只读锁定、bulk 403、解除后立刻再锁 |
| 重平衡 | allocation / recovery 节流 | 自愈是否会打穿业务窗口 | green 但 P99 恶化、跨 AZ 带宽占满 |
| ILM | rollover / 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 顺序。
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 分片,顺序反了会浪费黄金处置时间。
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.roles | Master 与 Data 分离 | 全体 data+master 混部 |
| seed_hosts | 仅列稳定 master | 列全部 data 造成发现噪声 |
| 跨 AZ | 剩余 AZ 仍能 quorum | 2+2 对称部署无 tie-breaker |
与 K8s 的交叉(待验证推断,需结合 Operator):StatefulSet 若未限制并发,可能短暂同时重启多个 Master Pod;
建议 PDB minAvailable: 2(3 Master 场景),并配合 readiness 确保选主完成后再接入 Service。
ECK 已内置多数最佳实践,自建 ES on K8s 需自行补齐。
失败窗口与预防清单
即使 quorum 配置正确,网络分区期间少数派子集将无法选举 Master 并拒绝写入——这是预期行为(可用性换一致性)。 真正危险的失败窗口在于:分区恢复前若因错误配置出现双主,则产生数据分叉,事后几乎无法无损合并。 预防清单应写进变更系统,而不是停留在口头约定。
- master-eligible 固定为 3 或 5,禁止临时把 Data 节点改为 master「凑数」救火。
- 跨 AZ 部署时,确保任意单 AZ 故障后剩余 AZ 仍能形成 quorum;对称 2+2 无 tie-breaker 是反模式。
- 监控
master_not_discovered_exception与org.elasticsearch.cluster.coordination选举日志。 - 永久下线 Master 的流程必须文档化,包含 voting exclusions 与回滚条件。
- 滚动替换 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」。百分比告警是结果,增长率告警才是趋势。
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。
触发条件与关键参数
分配器在节点加入/离开、触达 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_sec | recovery 带宽上限 | 低峰可提到 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 才是上游阀门。
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 当主库强一致写入、把无限热数据当廉价对象存储,都属于模型错位,拧水位解决不了。
8应急 SOP、决策顺序与稳定性巡检检查表
框架层只解决「先查什么、后查什么」。把稳定性当作多回路耦合:Master 失联会暂停 allocation 变更; 磁盘 flood 触发 relocation;relocation 抬高负载;ILM delete 失败推高磁盘。决策顺序比单条命令更重要。
磁盘只读应急 SOP
- 确认范围:
GET _cat/nodes?v&h=name,disk.used_percent,disk.avail,定位触水节点与索引。 - 止血写入:上游限流或暂停非关键 ingest,避免解块后立即再打满。
- 释放空间:按优先级删过期索引、强制 ILM execute、或扩容磁盘。
- 解除只读:使用率稳定低于 flood 后,逐索引或批量解除 block。
- 预防闭环:补 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 稳定性治理要留下的工程习惯。