Skip to content

Commit

Permalink
Default GOMAXPROCS to 1
Browse files Browse the repository at this point in the history
Avoid running on all CPUs by limiting the Go runtime to one CPU by
default. Avoids having Go routines schedule on every CPU, driving up the
visible run queue length on high CPU count systems.

This also helps workaround a kernel deadlock issue with reading from
sysfs concurrently.

See:
* #1880
* #2500

Signed-off-by: Ben Kochie <superq@gmail.com>
  • Loading branch information
SuperQ committed Nov 29, 2022
1 parent 956a3f8 commit 1552553
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 0 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
* [ENHANCEMENT]
* [BUGFIX]

NOTE: This changes the Go runtime "GOMAXPROCS" to 1. This is done to limit the
concurrency of the exporter to 1 CPU thread at a time in order to avoid a
race condition problem in the Linux kernel (#2500) and parallel IO issues
on nodes with high numbers of CPUs/CPU threads (#1880).

* [CHANGE] Default GOMAXPROCS to 1

## 1.4.0 / 2022-09-24

* [CHANGE] Merge metrics descriptions in textfile collector #2475
Expand Down
6 changes: 6 additions & 0 deletions node_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
_ "net/http/pprof"
"os"
"os/user"
"runtime"
"sort"

"github.com/prometheus/common/promlog"
Expand Down Expand Up @@ -159,6 +160,9 @@ func main() {
"collector.disable-defaults",
"Set all collectors to disabled by default.",
).Default("false").Bool()
maxProcs = kingpin.Flag(
"runtime.gomaxprocs", "The target number of CPUs Go will run on (GOMAXPROCS)",
).Envar("GOMAXPROCS").Default("1").Int()
toolkitFlags = kingpinflag.AddFlags(kingpin.CommandLine, ":9100")
)

Expand All @@ -178,6 +182,8 @@ func main() {
if user, err := user.Current(); err == nil && user.Uid == "0" {
level.Warn(logger).Log("msg", "Node Exporter is running as root user. This exporter is designed to run as unprivileged user, root is not required.")
}
runtime.GOMAXPROCS(*maxProcs)
level.Debug(logger).Log("msg", "Go MAXPROCS", "procs", *maxProcs)

http.Handle(*metricsPath, newHandler(!*disableExporterMetrics, *maxRequests, logger))
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
Expand Down

0 comments on commit 1552553

Please sign in to comment.