diff --git a/go.mod b/go.mod index 1c18b645243..62a63ff534c 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/spf13/cobra v1.6.1 github.com/stretchr/testify v1.8.2 go.opencensus.io v0.23.0 - go.uber.org/automaxprocs v1.5.1 + go.uber.org/automaxprocs v1.5.2 go.uber.org/zap v1.24.0 golang.org/x/net v0.8.0 golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783 diff --git a/go.sum b/go.sum index 92ea764a7ee..142cebcfba7 100644 --- a/go.sum +++ b/go.sum @@ -1280,8 +1280,9 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/automaxprocs v1.5.1 h1:e1YG66Lrk73dn4qhg8WFSvhF0JuFQF0ERIp4rpuV8Qk= go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66vU6XU= +go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME= +go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= diff --git a/vendor/go.uber.org/automaxprocs/CHANGELOG.md b/vendor/go.uber.org/automaxprocs/CHANGELOG.md index a831bc71e5c..ab89421850e 100644 --- a/vendor/go.uber.org/automaxprocs/CHANGELOG.md +++ b/vendor/go.uber.org/automaxprocs/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v1.5.2 (2023-03-16) + +- Support child control cgroups +- Fix file descriptor leak +- Update dependencies + ## v1.5.1 (2022-04-06) - Fix cgroups v2 mountpoint detection. diff --git a/vendor/go.uber.org/automaxprocs/Makefile b/vendor/go.uber.org/automaxprocs/Makefile index c54677208c6..1642b714801 100644 --- a/vendor/go.uber.org/automaxprocs/Makefile +++ b/vendor/go.uber.org/automaxprocs/Makefile @@ -28,7 +28,7 @@ $(GOLINT): tools/go.mod cd tools && go install golang.org/x/lint/golint $(STATICCHECK): tools/go.mod - cd tools && go install honnef.co/go/tools/cmd/staticcheck + cd tools && go install honnef.co/go/tools/cmd/staticcheck@2023.1.2 .PHONY: lint lint: $(GOLINT) $(STATICCHECK) diff --git a/vendor/go.uber.org/automaxprocs/README.md b/vendor/go.uber.org/automaxprocs/README.md index ab4b33becf8..bfed32adae8 100644 --- a/vendor/go.uber.org/automaxprocs/README.md +++ b/vendor/go.uber.org/automaxprocs/README.md @@ -16,6 +16,31 @@ func main() { } ``` +# Performance +Data measured from Uber's internal load balancer. We ran the load balancer with 200% CPU quota (i.e., 2 cores): + +| GOMAXPROCS | RPS | P50 (ms) | P99.9 (ms) | +| ------------------ | --------- | -------- | ---------- | +| 1 | 28,893.18 | 1.46 | 19.70 | +| 2 (equal to quota) | 44,715.07 | 0.84 | 26.38 | +| 3 | 44,212.93 | 0.66 | 30.07 | +| 4 | 41,071.15 | 0.57 | 42.94 | +| 8 | 33,111.69 | 0.43 | 64.32 | +| Default (24) | 22,191.40 | 0.45 | 76.19 | + +When `GOMAXPROCS` is increased above the CPU quota, we see P50 decrease slightly, but see significant increases to P99. We also see that the total RPS handled also decreases. + +When `GOMAXPROCS` is higher than the CPU quota allocated, we also saw significant throttling: + +``` +$ cat /sys/fs/cgroup/cpu,cpuacct/system.slice/[...]/cpu.stat +nr_periods 42227334 +nr_throttled 131923 +throttled_time 88613212216618 +``` + +Once `GOMAXPROCS` was reduced to match the CPU quota, we saw no CPU throttling. + ## Development Status: Stable All APIs are finalized, and no breaking changes will be made in the 1.x series diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go b/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go index 66930d0ac75..3ac10c8b6fc 100644 --- a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go +++ b/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go @@ -59,6 +59,7 @@ var ErrNotV2 = errors.New("not using cgroups2") // CGroups2 provides access to cgroups data for systems using cgroups2. type CGroups2 struct { mountPoint string + groupPath string cpuMaxFile string } @@ -66,10 +67,10 @@ type CGroups2 struct { // // This returns ErrNotV2 if the system is not using cgroups2. func NewCGroups2ForCurrentProcess() (*CGroups2, error) { - return newCGroups2FromMountInfo(_procPathMountInfo) + return newCGroups2From(_procPathMountInfo, _procPathCGroup) } -func newCGroups2FromMountInfo(mountInfoPath string) (*CGroups2, error) { +func newCGroups2From(mountInfoPath, procPathCGroup string) (*CGroups2, error) { isV2, err := isCGroupV2(mountInfoPath) if err != nil { return nil, err @@ -79,8 +80,27 @@ func newCGroups2FromMountInfo(mountInfoPath string) (*CGroups2, error) { return nil, ErrNotV2 } + subsystems, err := parseCGroupSubsystems(procPathCGroup) + if err != nil { + return nil, err + } + + // Find v2 subsystem by looking for the `0` id + var v2subsys *CGroupSubsys + for _, subsys := range subsystems { + if subsys.ID == 0 { + v2subsys = subsys + break + } + } + + if v2subsys == nil { + return nil, ErrNotV2 + } + return &CGroups2{ mountPoint: _cgroupv2MountPoint, + groupPath: v2subsys.Name, cpuMaxFile: _cgroupv2CPUMax, }, nil } @@ -106,13 +126,14 @@ func isCGroupV2(procPathMountInfo string) (bool, error) { // It will return `cpu.max / cpu.period`. If cpu.max is set to max, it returns // (-1, false, nil) func (cg *CGroups2) CPUQuota() (float64, bool, error) { - cpuMaxParams, err := os.Open(path.Join(cg.mountPoint, cg.cpuMaxFile)) + cpuMaxParams, err := os.Open(path.Join(cg.mountPoint, cg.groupPath, cg.cpuMaxFile)) if err != nil { if os.IsNotExist(err) { return -1, false, nil } return -1, false, err } + defer cpuMaxParams.Close() scanner := bufio.NewScanner(cpuMaxParams) if scanner.Scan() { diff --git a/vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go b/vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go index 3a751564915..df6eacf0530 100644 --- a/vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go +++ b/vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go @@ -28,6 +28,6 @@ const ( CPUQuotaUndefined CPUQuotaStatus = iota // CPUQuotaUsed is returned when a valid CPU quota can be used CPUQuotaUsed - // CPUQuotaMinUsed is return when CPU quota is smaller than the min value + // CPUQuotaMinUsed is returned when CPU quota is smaller than the min value CPUQuotaMinUsed ) diff --git a/vendor/go.uber.org/automaxprocs/maxprocs/version.go b/vendor/go.uber.org/automaxprocs/maxprocs/version.go index 15b156c99e5..108a95535e5 100644 --- a/vendor/go.uber.org/automaxprocs/maxprocs/version.go +++ b/vendor/go.uber.org/automaxprocs/maxprocs/version.go @@ -21,4 +21,4 @@ package maxprocs // Version is the current package version. -const Version = "1.5.1" +const Version = "1.5.2" diff --git a/vendor/modules.txt b/vendor/modules.txt index f8f699c7318..7cd27173784 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -663,7 +663,7 @@ go.opentelemetry.io/proto/otlp/trace/v1 # go.uber.org/atomic v1.9.0 ## explicit; go 1.13 go.uber.org/atomic -# go.uber.org/automaxprocs v1.5.1 +# go.uber.org/automaxprocs v1.5.2 ## explicit; go 1.18 go.uber.org/automaxprocs go.uber.org/automaxprocs/internal/cgroups