feat: Define clone sync criteria in CoordinatorDynamicConfig - #20247
feat: Define clone sync criteria in CoordinatorDynamicConfig#20247kfaraz wants to merge 5 commits into
Conversation
FrankChen021
left a comment
There was a problem hiding this comment.
| Severity | Findings |
|---|---|
| P0 | 0 |
| P1 | 2 |
| P2 | 1 |
| P3 | 0 |
| Total | 3 |
Reviewed 14 of 14 changed files.
This is an automated review by Codex GPT-5.6-Luna(max)
| private boolean isSynced(CloningStats stats, CloneSyncCriteria criteria) | ||
| { | ||
| return stats.segmentsPendingSync <= criteria.getMaxSegmentsPendingSync() | ||
| && stats.percentPendingSync() <= criteria.getMaxPercentPendingSync(); |
There was a problem hiding this comment.
[P1] Allow either sync threshold to qualify
The two configured limits are intersected here, so maxSegmentsPendingSync cannot independently make a clone SYNCED. The new test configures (maxSegmentsPendingSync=1, maxPercentPendingSync=10.0) with nine source segments and one pending segment: the absolute limit is met, but the calculated percentage is 11.11%, leaving the status IN_PROGRESS and contradicting the test's expected SYNCED state. Combine the thresholds according to the documented number-or-percentage semantics (or change the public contract and test).
|
|
||
| private final Set<String> turboLoadingNodes; | ||
| private final Map<String, String> cloneServers; | ||
| private final CloneSyncCriteria cloneSyncCriteria; |
There was a problem hiding this comment.
[P1] Include clone criteria in config equality
The new cloneSyncCriteria field is not included in CoordinatorDynamicConfig.equals() or hashCode(). The existing CoordinatorDynamicConfigTest uses EqualsVerifier without ignoring this field, so the test will reject the class; in production, BaseDynamicConfigSyncer also treats a threshold-only update as unchanged and does not invalidate its inSyncBrokers snapshot. Add value-based equality for the criteria and include it in both config methods.
| final ServerCloneStatus oldStatus = cloneStatusManager.getStatusForServer(targetServerName); | ||
|
|
||
| if (newStatus.state() == ServerCloneStatus.State.SYNCED | ||
| && oldStatus != null && oldStatus.state() != ServerCloneStatus.State.SYNCED) { |
There was a problem hiding this comment.
[P2] Emit the initial SYNCED transition metric
A coordinator starts with no entry in CloneStatusManager, so a clone that already satisfies the criteria on its first run has oldStatus == null. This condition then suppresses Stats.Segments.PENDING_SYNC even though the new state is SYNCED; the added simulation test expects that metric on its initial run. Treat the absent status as a transition (or otherwise emit the metric for the initial qualifying run).
|
cc @maytasm |
FrankChen021
left a comment
There was a problem hiding this comment.
| Severity | Findings |
|---|---|
| P0 | 0 |
| P1 | 0 |
| P2 | 2 |
| P3 | 1 |
| Total | 3 |
| Severity | Findings |
|---|---|
| P0 | 0 |
| P1 | 0 |
| P2 | 2 |
| P3 | 1 |
| Total | 3 |
Reviewed 16 of 16 changed files.
This is an automated review by Codex GPT-5.6-Luna(max)
|
|
||
| stats.add( | ||
| Stats.Segments.PENDING_SYNC_ON_CLONE, | ||
| RowKey.of(Dimension.SERVER, targetServerName), |
There was a problem hiding this comment.
[P2] Include tier in pending-sync metric
segment/clone/pendingSync/count is documented with server,tier dimensions, and the other clone metrics now include the target tier, but this row key is still server-only. In a multi-tier deployment the emitted event cannot be filtered or grouped by tier and does not match the documented metric contract. Include Dimension.TIER for the target in this row key.
| final PartialLoadProfile sourceProfile = sourceServer.getProjectedProfile(segment); | ||
| if (shouldLoadSegmentOnTargetServer(segment, sourceProfile, targetServer, targetProjectedSegments)) { | ||
| loadSegmentOnTargetServer(segment, sourceProfile, targetServer, params); | ||
| cloningStats.incrementMissingSegmentCount(sourceServer.isServingSegment(segment)); |
There was a problem hiding this comment.
[P2] Do not count skipped segments as pending
getLoadableSegment explicitly returns null for unused segments, so this call can queue no load. The counter is incremented unconditionally after the call whenever the source still serves the segment. An unused segment that remains in the source inventory therefore contributes to segmentsPendingSync and its percentage until it is unloaded, and can keep a clone IN_PROGRESS even though the clone duty intentionally skips that segment. Count it only when the segment is eligible for reconciliation, and cover a served-but-unused source segment.
| |`segment/moveSkipped/count`|Number of segments that were chosen for balancing but could not be moved. This can occur when segments are already optimally placed.|`dataSource`, `server`, `tier`, `description`|Varies| | ||
| |`segment/dropSkipped/count`|Number of segments that could not be dropped from any server.|`dataSource`, `server`, `tier`, `description`|Varies| | ||
| |`segment/clone/assigned/count`|Number of segments assigned to be loaded on a historical clone.|`dataSource`, `server`, `tier`|Varies| | ||
| |`segment/clone/dropped/count`|Number of segments assigned to be loaded on a historical clone.|`dataSource`, `server`, `tier`|Varies| |
There was a problem hiding this comment.
[P3] Correct dropped-clone metric description
This is the description for segment/clone/dropped/count, but it says segments are assigned to be loaded. The stat is emitted from DROPPED_FROM_CLONE when a drop is queued, so the description should say that segments are assigned to be dropped; otherwise operators will interpret this new metric backwards.
Description
When cloning historicals for a blue-green deployment using
CoordinatorDynamicConfig.cloneServers, it can often be difficult to determine if the clones are already synced and can be safely terminated. This is primarily because the source server keeps getting assigned new segments and the clone target is always playing catch up.The metric that has been used so far to determine if a clone is sufficiently "synced" is the
segmentLoadsRemainingreturned by the/cloneStatusAPI, but that number often fails to fall below any reasonable threshold thereby slowing down the deployment.Changes
CloneSyncCriteriatoCoordinatorDynamicConfigSYNCEDand emit a metricIN_PROGRESSif the clone starts lagging behind againThis PR has: