Storage Controller 自动故障切换机制Storage Controller 是自动完成故障切换的。1. 心跳检测 → 标记离线// storage_controller/src/heartbeater.rs:281 if now - *last_seen_at self.max_offline_interval { // 超过 30 秒无心跳 →标记为 Offline deltas.push((*node_id, ps_state.clone())); }默认配置心跳间隔HEARTBEAT_INTERVAL_DEFAULT 5 秒离线判定MAX_OFFLINE_INTERVAL_DEFAULT 30 秒时间线T0s心跳正常T5s心跳正常T10s心跳正常...T35s主节点故障无心跳T40sStorage Controller 检测到离线30秒超时触发故障切换流程2. 自动提升 Secondary 为主// storage_controller/src/tenant_shard.rs:678-682 if let Some(promote_secondary) self.preferred_secondary(scheduler) { // 自动从 Secondary 中选择一个提升到 Attached self.intent.promote_attached(scheduler, promote_secondary); Ok((true, promote_secondary)) }提升逻辑检测主位置节点离线从 Secondary 列表中选择一个可用节点调用 promote_attached()从 secondary 列表移除设置为新的 attached原主节点降级为 secondary如果恢复3. 完整的故障切换流程主位置Node A故障主位置Node A故障 │ ▼ ┌─────────────────────────────────────────────────────┐ │ Storage Controller 自动检测 │ │ │ │ 1. 心跳超时30秒→标记 Node A 为 Offline │ │ 2. 触发 Reconciler 重新规划 │ │ 3. 发现 Attached 为空Secondary 列表非空 │ │ 4. 调用 promote_attached(Node B) │ │ │ └─────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────┐ │ 故障切换执行 │ │ │ │ Node A原主位置 │ │ →降级为 Secondarywarmtrue │ │ →继续缓存层文件等待恢复后重新加入 │ │ │ │ Node B原次级位置 │ │ →升级为 Attachedgeneration1 │ │ →从 S3 加载缓存的层文件 │ │ →从 Safekeeper 追 WALLSN X →current │ │ →服务查询 │ │ │ │ Compute 连接 │ │ →Storage Controller 通知 Compute 切换 Pageserver │ │ →客户端重连到新 Pageserver │ └─────────────────────────────────────────────────────┘关键代码位置功能文件函数心跳检测storage_controller/src/heartbeater.rs:281heartbeat_loop()离线判定storage_controller/src/service.rs:127max_offline_interval自动提升storage_controller/src/tenant_shard.rs:678schedule()切换执行storage_controller/src/tenant_shard.rs:226promote_attached()重新规划storage_controller/src/reconciler.rs:79reconcile_tenant_shard()总结问题答案是否自动故障切换✅ 是Storage Controller 自动完成检测延迟多久默认 30 秒心跳间隔 5 秒 ×6 次超时切换方式自动将 Secondary 提升为 Attached原主节点恢复后降级为 Secondary重新预热缓存是否需要人工干预❌ 不需要完全自动化