syncer: isolate flow-only updates from full sync - #11058
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughChangesRegion syncer update flow
Estimated code review effort: 3 (Moderate) | ~25 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
pkg/syncer/metrics.go (1)
212-248: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick winUnchecked map lookups in metric helpers can panic on an unregistered key.
incHistoryBufferMissMetrics/incStreamEventMetrics(and theregionSyncerFullSyncLastDurationGauges[result]lookup inobserveFullSyncMetrics) index their maps directly and call.Inc()/.Set()without an existence check. All current call sites use the pre-registered constants, so there's no live bug today, but any future new label value added at a call site without a matching entry ininitRegionSyncerMetricswould return a nilprometheus.Counter/Gaugeand panic, crashing PD from a hot heartbeat/sync path.observeFullSyncMetrics's own counter lookup already demonstrates the safer comma-ok + fallback pattern used elsewhere in this same function.🛡️ Proposed defensive guard
func incHistoryBufferMissMetrics(phase string) { - regionSyncerHistoryBufferMissCounters[phase].Inc() + if counter, ok := regionSyncerHistoryBufferMissCounters[phase]; ok { + counter.Inc() + } } func incStreamEventMetrics(event string) { - regionSyncerStreamEventCounters[event].Inc() + if counter, ok := regionSyncerStreamEventCounters[event]; ok { + counter.Inc() + } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@pkg/syncer/metrics.go` around lines 212 - 248, Guard metric map lookups before calling methods: update observeFullSyncMetrics for regionSyncerFullSyncLastDurationGauges[result], incHistoryBufferMissMetrics for regionSyncerHistoryBufferMissCounters[phase], and incStreamEventMetrics for regionSyncerStreamEventCounters[event] to use comma-ok checks and skip updates when keys are unregistered. Preserve the existing registered-key behavior and full-sync counter fallback.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@pkg/syncer/metrics.go`:
- Around line 212-248: Guard metric map lookups before calling methods: update
observeFullSyncMetrics for regionSyncerFullSyncLastDurationGauges[result],
incHistoryBufferMissMetrics for regionSyncerHistoryBufferMissCounters[phase],
and incStreamEventMetrics for regionSyncerStreamEventCounters[event] to use
comma-ok checks and skip updates when keys are unregistered. Preserve the
existing registered-key behavior and full-sync counter fallback.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 397875fe-1ba9-424a-904a-978669a11c6f
📒 Files selected for processing (9)
metrics/grafana/pd.jsonpkg/syncer/client.gopkg/syncer/history_buffer.gopkg/syncer/history_buffer_test.gopkg/syncer/metrics.gopkg/syncer/server.gopkg/syncer/server_test.goserver/cluster/cluster.goserver/cluster/cluster_test.go
Classify RegionSyncer updates so full synchronization retains only correctness-critical changes. Skip flow-only updates in scheduling microservice mode, where the scheduling service already receives complete heartbeats. Signed-off-by: Ryan Leung <rleungx@gmail.com>
b3d1663 to
fed054d
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #11058 +/- ##
==========================================
+ Coverage 79.23% 79.26% +0.03%
==========================================
Files 540 541 +1
Lines 76010 76404 +394
==========================================
+ Hits 60226 60563 +337
- Misses 11533 11567 +34
- Partials 4251 4274 +23
Flags with carried forward coverage won't be shown. Click here to find out more. 🚀 New features to boost your workflow:
|
|
Potential correctness regression during full sync:
The follower then receives the critical change from neither the snapshot nor catch-up history. Before this PR, the coalesced latest Could we make criticality sticky when tasks are coalesced, or classify against the last state actually enqueued/recorded rather than the current cache? A regression test covering |
Signed-off-by: Ryan Leung <rleungx@gmail.com>
|
@rleungx: The following test failed, say
Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
|
The separate task names fix the original
The resulting execution order is I reproduced the Could we keep a single ordering/coalescing domain and merge pending updates using the latest full |
What problem does this PR solve?
Issue Number: ref #10719
RegionSyncer retains live Region updates while sending a full snapshot. In
clusters with millions of Regions, high-rate flow-only updates can exhaust the
bounded catch-up history and repeatedly restart full sync.
This supersedes #10914.
What is changed and how does it work?
Check List
Tests
Release note
Summary by CodeRabbit