PHOENIX-7787 Make CCF HAGroupStore ZK Updates backward compatible with existing ZK based client#2476
Open
ritegarg wants to merge 1 commit into
Open
Conversation
…h existing ZK based client Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changes were proposed in this pull request?
Adds an opt-in sync from
/phoenix/consistentHA/<G>to the legacy/phoenix/ha/<G>znode in each region server'sHAGroupStoreClient. Each client derives a combinedClusterRoleRecord(local role + peer role) and writes it to its local/phoenix/havia ZK stat-version CAS, so pre-consistentHA ZK-registry clients keep reading a current view of the HA group.New config keys (in
QueryServices/QueryServicesOptions):phoenix.ha.legacy.crr.sync.enabled— master switch (defaultfalse).phoenix.ha.legacy.crr.reconciliation.interval.seconds— periodic reconciliation cadence (default60;0disables only the periodic loop, the event-driven path still runs).Convergence model:
CHILD_ADDED/CHILD_UPDATED(LOCAL or PEER).NodeCachewatcher on the legacy znode itself, so per-sync reads are in-memory rather than a ZK round-trip.BadVersion: log and bail. The NodeCache watch + next event/periodic cycle reconverges. No inline retry.Code-level changes:
ClusterRoleRecord: new explicit-RegistryTypector;@JsonCreatornow round-tripsregistryType(legacy znode is always written withRegistryType.ZKfor backward compatibility, and must read back as ZK). NewisLogicallyEqualIgnoringVersionAndRegistryhelper.PhoenixHAAdmin: three new helpers on the legacy namespace (getClusterRoleRecordAndStatInZooKeeper,createOrUpdateClusterRoleRecordWithCAS); atomic-read fix on the existinggetHAGroupStoreRecordInZooKeeper(replaces a pre-existing 2-RPC pattern that could return a stat version not matching its data bytes). Named CAS sentinels:CREATE_NEW_RECORD_STAT_VERSION = -2,ZK_MATCH_ANY_VERSION = -1. The-1value is only used as ZK's wildcard, never as our create marker — using it for create would silently bypass CAS.HAGroupStoreClient:legacyHaAdmin+legacyCrrNodeCache+ privatelegacyCrrSyncLock+ dedicated periodic executor. Listener hooks forCHILD_ADDED/CHILD_UPDATED.CHILD_REMOVEDis intentionally a no-op — operator owns the legacy znode lifecycle.StaleClusterRoleRecordVersionException(CRR-specific analog ofStaleHAGroupStoreRecordVersionException).Why are the changes needed?
The Consistent Cluster Failover work moved HA group state from
/phoenix/ha(which held aClusterRoleRecord) to/phoenix/consistentHA(which holds anHAGroupStoreRecordand uses an RPC-registry view of CRRs). Existing Phoenix clients built against the older ZK-registry contract still read/phoenix/ha/<G>and expect:registryTypeto beZK.Without this patch, after a CCF rollout the
/phoenix/haznode goes stale or absent, and old ZK-registry clients break. This change keeps/phoenix/hain sync with the new authoritative/phoenix/consistentHArecords on a per-RS basis, gated by an opt-in flag so it only runs where the operator needs it.Does this PR introduce any user-facing change?
Yes, but the new behavior is gated entirely behind the new master switch (
phoenix.ha.legacy.crr.sync.enabled), which defaults tofalse.When the flag is enabled:
HAGroupStoreClientwrites to (and maintains) the legacy/phoenix/ha/<G>znode on its local ZK./phoenix/hawill see fresh records again.One incidental visible change independent of the flag:
ClusterRoleRecordJSON deserialization now respects the persistedregistryTypefield. Previously it was hard-coded toRPCregardless of JSON content. Existing JSON without aregistryTypefield still defaults toRPC, so deployments not exposed to legacy-sync writes see no behavior change.How was this patch tested?
HAGroupStoreClientITcovering: feature-off no-op, initial create, role-changing transition, state-only transition (no rewrite), peer-driven role flip, peer-absent →role2=UNKNOWN→ recovery, pre-existing stale znode overwrite, two-writer CAS race + invalid-sentinel rejection, LOCAL/PEERCHILD_REMOVED(znode preserved),registryTypestays ZK across multiple role cycles, reconciliation interval=0(event-driven still works), and periodic-loop recovery after an external divergence.HAGroupStoreClientIT: 39/39 pass.ClusterRoleRecordTest(unit): 12/12 pass.mvn spotless:checkclean across the repo.Was this patch authored or co-authored using generative AI tooling?
Generated-by: Claude (Anthropic).