feat(controller): add spec.flushOnFailover to flush a promoted master - #573
feat(controller): add spec.flushOnFailover to flush a promoted master#573nmass-betpawa wants to merge 2 commits into
Conversation
|
Hey @nmass-betpawa, can you elaborate more on the use case? Why do you need a replica if you don't want to retain the data? If you don't want to retain the data, you can just have a single master with no replica. |
The replica is there for availability, not for durability. Why not a single master: that is what we run today, and a node going down is full downtime and it leaves us with an empty cache anyway. A replica plus this flag gives the same empty cache without the outage. We are not trying to keep data across a failover, we are trying not to be down during one. Planned promotions should keep the data, which is why REPLTAKEOVER is left alone here: a takeover waits for full sync, so the dataset is valid. |
PR description
Summary
Adds an opt-in
spec.flushOnFailoverfield. When it is set, a replica promoted during an unplannedfailover is flushed right after
SLAVE OF NO ONEand before itsrole: masterlabel is patched.This is for cache workloads that must not serve data which is stale relative to the master that was
lost: the promoted pod can be behind the dead master, and today there is no way to have the new
master start empty.
The placement between those two calls is the point of doing this in the operator. The master
Service selects on
RoleLabelKey: Master(internal/resources/resources.go), so while the flushruns the promoted pod is not an endpoint of it yet and no client can read the stale dataset through
the Service.
This follows the discussion in dragonflydb/dragonfly#8051, where the conclusion was that the policy
belongs here rather than in a Dragonfly server flag.
Changes
DragonflySpec.FlushOnFailover, defaultfalse.replicaOfNoOne()issuesFLUSHALLafter a successfulSLAVE OF NO ONE, guarded by a check thatthe pod really was a replica before the call.
config/crd/bases,manifests/,charts/.Behavior
false— no change for existing deployments.replicaOfNoOne()also runs during initial master election, where the podis already a master and its dataset — for example one restored from a snapshot after a full
restart — must be preserved. Only a replica -> master transition flushes.
updatedMaster()->replTakeover(), acoordinated takeover that loses no data, so flushing there would mean a cold cache and a backend
load spike on every upgrade.
FLUSHALLreturns before the role label is patched, so the pod is never advertised asmaster with a stale dataset; the reconciler retries.
Testing
Manually, on a 3-replica instance with the field enabled: delete the master pod, then confirm the
promoted pod logs
flushing the promoted masterand reportsdbsize0, and that the remainingreplicas come back empty after they re-sync.