diff --git a/nomad/leader.go b/nomad/leader.go index 88a62802f..077a2cad5 100644 --- a/nomad/leader.go +++ b/nomad/leader.go @@ -101,8 +101,9 @@ func (s *Server) establishLeadership(stopCh chan struct{}) error { // Disable workers to free half the cores for use in the plan queue and // evaluation broker if numWorkers := len(s.workers); numWorkers > 1 { - // Disabling half the workers frees half the CPUs. - for i := 0; i < numWorkers/2; i++ { + // Disabling 3/4 of the workers frees CPU for raft and the + // plan applier which uses 1/2 the cores. + for i := 0; i < (3 * numWorkers / 4); i++ { s.workers[i].SetPause(true) } } diff --git a/nomad/plan_apply.go b/nomad/plan_apply.go index 384689bee..ac5ba3656 100644 --- a/nomad/plan_apply.go +++ b/nomad/plan_apply.go @@ -2,6 +2,7 @@ package nomad import ( "fmt" + "runtime" "time" "github.com/armon/go-metrics" @@ -42,7 +43,13 @@ func (s *Server) planApply() { // holds an optimistic state which includes that plan application. var waitCh chan struct{} var snap *state.StateSnapshot - pool := NewEvaluatePool(workerPoolSize, workerPoolBufferSize) + + // Setup a worker pool with half the cores, with at least 1 + poolSize := runtime.NumCPU() / 2 + if poolSize == 0 { + poolSize = 1 + } + pool := NewEvaluatePool(poolSize, workerPoolBufferSize) defer pool.Shutdown() for { diff --git a/nomad/plan_apply_pool.go b/nomad/plan_apply_pool.go index 934991ee4..bd9d7d7ce 100644 --- a/nomad/plan_apply_pool.go +++ b/nomad/plan_apply_pool.go @@ -6,9 +6,6 @@ import ( ) const ( - // workerPoolSize is the size of the worker pool - workerPoolSize = 2 - // workerPoolBufferSize is the size of the buffers used to push // request to the workers and to collect the responses. It should // be large enough just to keep things busy diff --git a/nomad/plan_apply_test.go b/nomad/plan_apply_test.go index 92141ab58..2156a47cc 100644 --- a/nomad/plan_apply_test.go +++ b/nomad/plan_apply_test.go @@ -10,6 +10,11 @@ import ( "github.com/hashicorp/raft" ) +const ( + // workerPoolSize is the size of the worker pool + workerPoolSize = 2 +) + // planWaitFuture is used to wait for the Raft future to complete func planWaitFuture(future raft.ApplyFuture) (uint64, error) { if err := future.Error(); err != nil {