-
Notifications
You must be signed in to change notification settings - Fork 764
mcs: scheduling mcs support gctuner #10212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
d08b9c4
d429f2d
b3dac8b
484b9dc
d6b85a8
eb2a7be
81267f4
052746b
3457ebf
8cf8ae5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,7 @@ import ( | |
| "github.com/pingcap/log" | ||
|
|
||
| util "github.com/tikv/pd/pkg/gogc" | ||
| "github.com/tikv/pd/pkg/memory" | ||
| ) | ||
|
|
||
| var ( | ||
|
|
@@ -64,10 +65,12 @@ func init() { | |
| // When Tuning, the env GOGC will not be take effect. | ||
| // threshold: disable tuning if threshold == 0 | ||
| func Tuning(threshold uint64) { | ||
| // disable gc tuner if percent is zero | ||
| if t := globalTuner.Load(); t == nil { | ||
| t1 := newTuner(threshold) | ||
| globalTuner.CompareAndSwap(nil, &t1) | ||
| // init gc tuner only when threshold > 0, otherwise do nothing | ||
| if threshold > 0 { | ||
| t1 := newTuner(threshold) | ||
| globalTuner.CompareAndSwap(nil, &t1) | ||
| } | ||
| } else { | ||
| if threshold <= 0 { | ||
| (*t).stop() | ||
|
|
@@ -191,3 +194,95 @@ func calcGCPercent(inuse, threshold uint64) uint32 { | |
| } | ||
| return gcPercent | ||
| } | ||
|
|
||
| // Config holds the configuration for GC tuner initialization/update. | ||
| type Config struct { | ||
| EnableGOGCTuner bool | ||
| GCTunerThreshold float64 | ||
| ServerMemoryLimit float64 | ||
| ServerMemoryLimitGCTrigger float64 | ||
| } | ||
|
|
||
| // State holds the state for detecting config changes. | ||
| type State struct { | ||
| totalMem uint64 | ||
| EnableGCTuner bool | ||
| GCThresholdBytes uint64 | ||
| MemoryLimitBytes uint64 | ||
| MemoryLimitGCTriggerRatio float64 | ||
| MemoryLimitGCTriggerBytes uint64 | ||
| } | ||
|
|
||
| // InitGCTuner initializes the GC tuner with the given config and total memory. | ||
| // Returns the initial state that can be used for subsequent updates. | ||
| func InitGCTuner(totalMem uint64, cfg *Config) *State { | ||
| state := &State{totalMem: totalMem} | ||
| state.EnableGCTuner = cfg.EnableGOGCTuner | ||
| state.MemoryLimitBytes = uint64(float64(totalMem) * cfg.ServerMemoryLimit) | ||
| state.GCThresholdBytes = uint64(float64(state.MemoryLimitBytes) * cfg.GCTunerThreshold) | ||
| if state.MemoryLimitBytes == 0 { | ||
| state.GCThresholdBytes = uint64(float64(totalMem) * cfg.GCTunerThreshold) | ||
| } | ||
| state.MemoryLimitGCTriggerRatio = cfg.ServerMemoryLimitGCTrigger | ||
| state.MemoryLimitGCTriggerBytes = uint64(float64(state.MemoryLimitBytes) * state.MemoryLimitGCTriggerRatio) | ||
|
|
||
| // Initialize GC tuner | ||
| Tuning(state.GCThresholdBytes) | ||
| EnableGOGCTuner.Store(state.EnableGCTuner) | ||
| log.Info("initialize gc tuner", | ||
| zap.Bool("enable-gc-tuner", state.EnableGCTuner), | ||
| zap.Uint64("gc-threshold-bytes", state.GCThresholdBytes)) | ||
|
|
||
| // Initialize memory limit tuner | ||
| memory.ServerMemoryLimit.Store(state.MemoryLimitBytes) | ||
| GlobalMemoryLimitTuner.SetPercentage(state.MemoryLimitGCTriggerRatio) | ||
| GlobalMemoryLimitTuner.UpdateMemoryLimit() | ||
| log.Info("initialize gc memory limit", | ||
| zap.Uint64("memory-limit-bytes", state.MemoryLimitBytes), | ||
| zap.Float64("memory-limit-gc-trigger-ratio", state.MemoryLimitGCTriggerRatio)) | ||
|
|
||
| return state | ||
|
Comment on lines
+210
to
+248
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a shutdown hook for
Based on learnings: Avoid new global state; keep concurrency safe; close resources, and prevent goroutine leaks: pair with cancellation. 🤖 Prompt for AI Agents
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but we want keep the GC parameters still working even if the state has gc There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
On the goroutine-leak concern: since ( _( ✏️ Learnings added
🧠 Learnings used
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will it cause a leak? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bufferflies still have a comment unresolved.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done, add a close function to disable the tuner. |
||
| } | ||
|
|
||
| // UpdateIfNeeded checks if the config has changed and updates the GC tuner. | ||
| // Returns true if any updates were made. | ||
| func (s *State) UpdateIfNeeded(cfg *Config) bool { | ||
| updated := false | ||
|
|
||
| newEnableGCTuner := cfg.EnableGOGCTuner | ||
| newMemoryLimitBytes := uint64(float64(s.totalMem) * cfg.ServerMemoryLimit) | ||
| newGCThresholdBytes := uint64(float64(newMemoryLimitBytes) * cfg.GCTunerThreshold) | ||
| if newMemoryLimitBytes == 0 { | ||
| newGCThresholdBytes = uint64(float64(s.totalMem) * cfg.GCTunerThreshold) | ||
| } | ||
| newMemoryLimitGCTriggerRatio := cfg.ServerMemoryLimitGCTrigger | ||
| newMemoryLimitGCTriggerBytes := uint64(float64(newMemoryLimitBytes) * newMemoryLimitGCTriggerRatio) | ||
|
|
||
| // Check and update GC tuner | ||
| if newEnableGCTuner != s.EnableGCTuner || newGCThresholdBytes != s.GCThresholdBytes { | ||
| s.EnableGCTuner = newEnableGCTuner | ||
| s.GCThresholdBytes = newGCThresholdBytes | ||
| Tuning(s.GCThresholdBytes) | ||
| EnableGOGCTuner.Store(s.EnableGCTuner) | ||
| log.Info("update gc tuner", | ||
| zap.Bool("enable-gc-tuner", s.EnableGCTuner), | ||
| zap.Uint64("gc-threshold-bytes", s.GCThresholdBytes)) | ||
| updated = true | ||
| } | ||
|
|
||
| // Check and update memory limit tuner | ||
| if newMemoryLimitBytes != s.MemoryLimitBytes || newMemoryLimitGCTriggerRatio != s.MemoryLimitGCTriggerRatio { | ||
| s.MemoryLimitBytes = newMemoryLimitBytes | ||
| s.MemoryLimitGCTriggerRatio = newMemoryLimitGCTriggerRatio | ||
| s.MemoryLimitGCTriggerBytes = newMemoryLimitGCTriggerBytes | ||
| memory.ServerMemoryLimit.Store(s.MemoryLimitBytes) | ||
| GlobalMemoryLimitTuner.SetPercentage(s.MemoryLimitGCTriggerRatio) | ||
| GlobalMemoryLimitTuner.UpdateMemoryLimit() | ||
| log.Info("update gc memory limit", | ||
| zap.Uint64("memory-limit-bytes", s.MemoryLimitBytes), | ||
| zap.Float64("memory-limit-gc-trigger-ratio", s.MemoryLimitGCTriggerRatio)) | ||
| updated = true | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| return updated | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.