jihuayu opened a new issue, #398:
URL: https://github.com/apache/kvrocks-controller/issues/398

   ## Background
   
   The controller's current health decision path is still based on a single 
active leader's local memory. Standby controller instances do not contribute 
probe observations, and failure state is lost when the leader process restarts 
or leadership changes.
   
   ## Current behavior
   
   - Only the elected leader starts cluster checkers. When a controller loses 
leadership, it closes all local `ClusterChecker` instances.
     - `controller/controller.go`: `resume`, `suspend`, `syncLoop`
   - Probe failure counts are stored only in `ClusterChecker.failureCounts 
map[string]int64`.
     - `controller/cluster.go`: `failureCounts`, `increaseFailureCount`, 
`resetFailureCount`
   - When the local failure count reaches `maxFailureCount`, the leader 
directly calls `PromoteNewMaster` and writes the updated cluster topology.
     - `controller/cluster.go`: `increaseFailureCount` -> 
`cluster.PromoteNewMaster` -> `clusterStore.UpdateCluster`
   - The store interface has no persisted probe report, health decision, CAS, 
fencing token, or per-decision lease abstraction.
     - `store/store.go`: `Store`, `UpdateCluster`, `SetCluster`
   
   ## Why this is risky
   
   - A controller restart or leader change clears all accumulated failure 
observations.
   - A network issue visible only from the current leader can become an 
automatic failover decision.
   - There is no durable audit trail showing which controller instances 
observed the failure and when.
   - There is no quorum-style distinction between a local subjective failure 
observation and an objective cluster decision.
   - The final topology update is not tied to an expected cluster version plus 
a decision lease/fencing token.
   
   ## Expected direction
   
   Introduce a persisted, multi-instance health decision layer before automatic 
failover:
   
   1. Add durable `HealthReport` records keyed by namespace, cluster, shard, 
node, and controller instance ID.
   2. Include at least: `observed_at`, `expires_at` or TTL, probe result, error 
class, observed cluster version/epoch, role, sequence, and controller ID.
   3. Add a `HealthDecision` or `FailoverDecision` object that represents the 
computed objective state, for example `Healthy`, `Suspect`, `ObjectivelyDown`, 
`FailoverPending`, `FailoverCommitted`, `Blocked`.
   4. Require quorum or configurable agreement before automatic master failover.
   5. Commit failover only with a store-level CAS/transaction or lease/fencing 
token against the expected cluster version.
   6. Keep the behavior idempotent across controller restart and leader 
transfer.
   
   ## Acceptance criteria
   
   - Failure observations survive controller leader changes until their TTL 
expires.
   - Multiple controller instances can report independent health observations 
while only one instance commits the final decision.
   - Automatic master failover requires a persisted objective decision, not 
only one leader's in-memory counter.
   - Stale leaders or stale decisions cannot overwrite a newer cluster topology.
   - Tests cover leader restart, leader handoff, asymmetric probe failure, 
stale decision rejection, and successful quorum-backed failover.
   
   ## Related follow-up areas
   
   - Add health/failover Prometheus metrics.
   - Expose health decision state in API/UI.
   - Define conflict rules with manual failover, node offline/online, and slot 
migration.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to