Making the scheduler use LocalDisk instead of Resources.DiskMB

This commit is contained in:
Diptanu Choudhury 2016-08-25 12:27:19 -05:00
parent d156f32f94
commit ec73c768f1
7 changed files with 315 additions and 42 deletions

View File

@ -79,6 +79,9 @@ func Job() *structs.Job {
&structs.TaskGroup{
Name: "web",
Count: 10,
LocalDisk: &structs.LocalDisk{
DiskMB: 150,
},
RestartPolicy: &structs.RestartPolicy{
Attempts: 3,
Interval: 10 * time.Minute,
@ -120,7 +123,6 @@ func Job() *structs.Job {
Resources: &structs.Resources{
CPU: 500,
MemoryMB: 256,
DiskMB: 150,
Networks: []*structs.NetworkResource{
&structs.NetworkResource{
MBits: 50,
@ -178,6 +180,7 @@ func SystemJob() *structs.Job {
Delay: 1 * time.Minute,
Mode: structs.RestartPolicyModeDelay,
},
LocalDisk: structs.DefaultLocalDisk(),
Tasks: []*structs.Task{
&structs.Task{
Name: "web",

243
scheduler/foo Normal file
View File

@ -0,0 +1,243 @@
=== RUN TestAnnotateTaskGroup_Updates
--- PASS: TestAnnotateTaskGroup_Updates (0.00s)
=== RUN TestAnnotateCountChange_NonEdited
--- PASS: TestAnnotateCountChange_NonEdited (0.00s)
=== RUN TestAnnotateCountChange
--- PASS: TestAnnotateCountChange (0.00s)
=== RUN TestAnnotateTask_NonEdited
--- PASS: TestAnnotateTask_NonEdited (0.00s)
=== RUN TestAnnotateTask
--- PASS: TestAnnotateTask (0.00s)
=== RUN TestEvalContext_ProposedAlloc
--- PASS: TestEvalContext_ProposedAlloc (0.00s)
=== RUN TestEvalEligibility_JobStatus
false
--- PASS: TestEvalEligibility_JobStatus (0.00s)
=== RUN TestEvalEligibility_TaskGroupStatus
--- PASS: TestEvalEligibility_TaskGroupStatus (0.00s)
=== RUN TestEvalEligibility_SetJob
--- PASS: TestEvalEligibility_SetJob (0.00s)
=== RUN TestEvalEligibility_GetClasses
--- PASS: TestEvalEligibility_GetClasses (0.00s)
=== RUN TestStaticIterator_Reset
--- PASS: TestStaticIterator_Reset (0.00s)
=== RUN TestStaticIterator_SetNodes
--- PASS: TestStaticIterator_SetNodes (0.00s)
=== RUN TestRandomIterator
--- PASS: TestRandomIterator (0.00s)
=== RUN TestDriverChecker
--- PASS: TestDriverChecker (0.00s)
=== RUN TestConstraintChecker
--- PASS: TestConstraintChecker (0.00s)
=== RUN TestResolveConstraintTarget
--- PASS: TestResolveConstraintTarget (0.00s)
=== RUN TestCheckConstraint
--- PASS: TestCheckConstraint (0.00s)
=== RUN TestCheckLexicalOrder
--- PASS: TestCheckLexicalOrder (0.00s)
=== RUN TestCheckVersionConstraint
--- PASS: TestCheckVersionConstraint (0.00s)
=== RUN TestCheckRegexpConstraint
--- PASS: TestCheckRegexpConstraint (0.00s)
=== RUN TestProposedAllocConstraint_JobDistinctHosts
--- PASS: TestProposedAllocConstraint_JobDistinctHosts (0.00s)
=== RUN TestProposedAllocConstraint_JobDistinctHosts_Infeasible
--- PASS: TestProposedAllocConstraint_JobDistinctHosts_Infeasible (0.00s)
=== RUN TestProposedAllocConstraint_JobDistinctHosts_InfeasibleCount
--- PASS: TestProposedAllocConstraint_JobDistinctHosts_InfeasibleCount (0.00s)
=== RUN TestProposedAllocConstraint_TaskGroupDistinctHosts
--- PASS: TestProposedAllocConstraint_TaskGroupDistinctHosts (0.00s)
=== RUN TestFeasibilityWrapper_JobIneligible
--- PASS: TestFeasibilityWrapper_JobIneligible (0.00s)
=== RUN TestFeasibilityWrapper_JobEscapes
--- PASS: TestFeasibilityWrapper_JobEscapes (0.00s)
=== RUN TestFeasibilityWrapper_JobAndTg_Eligible
--- PASS: TestFeasibilityWrapper_JobAndTg_Eligible (0.00s)
=== RUN TestFeasibilityWrapper_JobEligible_TgIneligible
--- PASS: TestFeasibilityWrapper_JobEligible_TgIneligible (0.00s)
=== RUN TestFeasibilityWrapper_JobEligible_TgEscaped
--- PASS: TestFeasibilityWrapper_JobEligible_TgEscaped (0.00s)
=== RUN TestServiceSched_JobRegister
--- PASS: TestServiceSched_JobRegister (0.00s)
=== RUN TestServiceSched_JobRegister_Annotate
--- PASS: TestServiceSched_JobRegister_Annotate (0.00s)
=== RUN TestServiceSched_JobRegister_CountZero
--- PASS: TestServiceSched_JobRegister_CountZero (0.00s)
=== RUN TestServiceSched_JobRegister_AllocFail
--- PASS: TestServiceSched_JobRegister_AllocFail (0.00s)
=== RUN TestServiceSched_JobRegister_CreateBlockedEval
--- PASS: TestServiceSched_JobRegister_CreateBlockedEval (0.00s)
=== RUN TestServiceSched_JobRegister_FeasibleAndInfeasibleTG
--- PASS: TestServiceSched_JobRegister_FeasibleAndInfeasibleTG (0.00s)
=== RUN TestServiceSched_EvaluateMaxPlanEval
--- PASS: TestServiceSched_EvaluateMaxPlanEval (0.00s)
=== RUN TestServiceSched_Plan_Partial_Progress
--- PASS: TestServiceSched_Plan_Partial_Progress (0.00s)
=== RUN TestServiceSched_EvaluateBlockedEval
--- PASS: TestServiceSched_EvaluateBlockedEval (0.00s)
=== RUN TestServiceSched_EvaluateBlockedEval_Finished
--- PASS: TestServiceSched_EvaluateBlockedEval_Finished (0.00s)
=== RUN TestServiceSched_JobModify
--- PASS: TestServiceSched_JobModify (0.00s)
=== RUN TestServiceSched_JobModify_IncrCount_NodeLimit
--- PASS: TestServiceSched_JobModify_IncrCount_NodeLimit (0.00s)
=== RUN TestServiceSched_JobModify_CountZero
--- PASS: TestServiceSched_JobModify_CountZero (0.00s)
=== RUN TestServiceSched_JobModify_Rolling
--- PASS: TestServiceSched_JobModify_Rolling (0.00s)
=== RUN TestServiceSched_JobModify_InPlace
--- PASS: TestServiceSched_JobModify_InPlace (0.00s)
=== RUN TestServiceSched_JobDeregister
--- PASS: TestServiceSched_JobDeregister (0.00s)
=== RUN TestServiceSched_NodeDown
--- PASS: TestServiceSched_NodeDown (0.00s)
=== RUN TestServiceSched_NodeUpdate
--- PASS: TestServiceSched_NodeUpdate (0.00s)
=== RUN TestServiceSched_NodeDrain
--- PASS: TestServiceSched_NodeDrain (0.00s)
=== RUN TestServiceSched_NodeDrain_Down
--- PASS: TestServiceSched_NodeDrain_Down (0.00s)
=== RUN TestServiceSched_NodeDrain_Queued_Allocations
--- PASS: TestServiceSched_NodeDrain_Queued_Allocations (0.00s)
=== RUN TestServiceSched_NodeDrain_UpdateStrategy
--- PASS: TestServiceSched_NodeDrain_UpdateStrategy (0.00s)
=== RUN TestServiceSched_RetryLimit
--- PASS: TestServiceSched_RetryLimit (0.00s)
=== RUN TestBatchSched_Run_CompleteAlloc
--- PASS: TestBatchSched_Run_CompleteAlloc (0.00s)
=== RUN TestBatchSched_Run_DrainedAlloc
--- PASS: TestBatchSched_Run_DrainedAlloc (0.00s)
=== RUN TestBatchSched_Run_FailedAlloc
--- PASS: TestBatchSched_Run_FailedAlloc (0.00s)
=== RUN TestBatchSched_Run_FailedAllocQueuedAllocations
--- PASS: TestBatchSched_Run_FailedAllocQueuedAllocations (0.00s)
=== RUN TestBatchSched_ReRun_SuccessfullyFinishedAlloc
--- PASS: TestBatchSched_ReRun_SuccessfullyFinishedAlloc (0.00s)
=== RUN TestGenericSched_FilterCompleteAllocs
--- PASS: TestGenericSched_FilterCompleteAllocs (0.00s)
=== RUN TestGenericSched_ChainedAlloc
--- PASS: TestGenericSched_ChainedAlloc (0.00s)
=== RUN TestFeasibleRankIterator
--- PASS: TestFeasibleRankIterator (0.00s)
=== RUN TestBinPackIterator_NoExistingAlloc
--- FAIL: TestBinPackIterator_NoExistingAlloc (0.00s)
rank_test.go:88: Bad: []
=== RUN TestBinPackIterator_PlannedAlloc
--- FAIL: TestBinPackIterator_PlannedAlloc (0.00s)
rank_test.go:167: Bad: []*scheduler.RankedNode(nil)
=== RUN TestBinPackIterator_ExistingAlloc
--- FAIL: TestBinPackIterator_ExistingAlloc (0.00s)
rank_test.go:252: Bad: []*scheduler.RankedNode(nil)
=== RUN TestBinPackIterator_ExistingAlloc_PlannedEvict
--- FAIL: TestBinPackIterator_ExistingAlloc_PlannedEvict (0.00s)
rank_test.go:341: Bad: []*scheduler.RankedNode(nil)
=== RUN TestJobAntiAffinity_PlannedAlloc
--- PASS: TestJobAntiAffinity_PlannedAlloc (0.00s)
=== RUN TestLimitIterator
--- PASS: TestLimitIterator (0.00s)
=== RUN TestMaxScoreIterator
--- PASS: TestMaxScoreIterator (0.00s)
=== RUN TestServiceStack_SetNodes
--- PASS: TestServiceStack_SetNodes (0.00s)
=== RUN TestServiceStack_SetJob
--- PASS: TestServiceStack_SetJob (0.00s)
=== RUN TestServiceStack_Select_Size
--- PASS: TestServiceStack_Select_Size (0.00s)
=== RUN TestServiceStack_Select_MetricsReset
--- PASS: TestServiceStack_Select_MetricsReset (0.00s)
=== RUN TestServiceStack_Select_DriverFilter
--- PASS: TestServiceStack_Select_DriverFilter (0.00s)
=== RUN TestServiceStack_Select_ConstraintFilter
--- PASS: TestServiceStack_Select_ConstraintFilter (0.00s)
=== RUN TestServiceStack_Select_BinPack_Overflow
--- PASS: TestServiceStack_Select_BinPack_Overflow (0.00s)
=== RUN TestSystemStack_SetNodes
--- PASS: TestSystemStack_SetNodes (0.00s)
=== RUN TestSystemStack_SetJob
--- PASS: TestSystemStack_SetJob (0.00s)
=== RUN TestSystemStack_Select_Size
--- PASS: TestSystemStack_Select_Size (0.00s)
=== RUN TestSystemStack_Select_MetricsReset
--- PASS: TestSystemStack_Select_MetricsReset (0.00s)
=== RUN TestSystemStack_Select_DriverFilter
--- PASS: TestSystemStack_Select_DriverFilter (0.00s)
=== RUN TestSystemStack_Select_ConstraintFilter
--- PASS: TestSystemStack_Select_ConstraintFilter (0.00s)
=== RUN TestSystemStack_Select_BinPack_Overflow
--- PASS: TestSystemStack_Select_BinPack_Overflow (0.00s)
=== RUN TestSystemSched_JobRegister
--- PASS: TestSystemSched_JobRegister (0.00s)
=== RUN TestSystemSched_ExhaustResources
--- PASS: TestSystemSched_ExhaustResources (0.00s)
=== RUN TestSystemSched_JobRegister_Annotate
--- PASS: TestSystemSched_JobRegister_Annotate (0.00s)
=== RUN TestSystemSched_JobRegister_AddNode
--- PASS: TestSystemSched_JobRegister_AddNode (0.00s)
=== RUN TestSystemSched_JobRegister_AllocFail
--- PASS: TestSystemSched_JobRegister_AllocFail (0.00s)
=== RUN TestSystemSched_JobModify
--- PASS: TestSystemSched_JobModify (0.00s)
=== RUN TestSystemSched_JobModify_Rolling
--- PASS: TestSystemSched_JobModify_Rolling (0.00s)
=== RUN TestSystemSched_JobModify_InPlace
--- PASS: TestSystemSched_JobModify_InPlace (0.00s)
=== RUN TestSystemSched_JobDeregister
--- PASS: TestSystemSched_JobDeregister (0.00s)
=== RUN TestSystemSched_NodeDown
--- PASS: TestSystemSched_NodeDown (0.00s)
=== RUN TestSystemSched_NodeDrain_Down
--- PASS: TestSystemSched_NodeDrain_Down (0.00s)
=== RUN TestSystemSched_NodeDrain
--- PASS: TestSystemSched_NodeDrain (0.00s)
=== RUN TestSystemSched_NodeUpdate
--- PASS: TestSystemSched_NodeUpdate (0.00s)
=== RUN TestSystemSched_RetryLimit
--- PASS: TestSystemSched_RetryLimit (0.00s)
=== RUN TestSystemSched_Queued_With_Constraints
--- PASS: TestSystemSched_Queued_With_Constraints (0.00s)
=== RUN TestSystemSched_ChainedAlloc
--- PASS: TestSystemSched_ChainedAlloc (0.00s)
=== RUN TestMaterializeTaskGroups
--- PASS: TestMaterializeTaskGroups (0.00s)
=== RUN TestDiffAllocs
--- PASS: TestDiffAllocs (0.00s)
=== RUN TestDiffSystemAllocs
--- PASS: TestDiffSystemAllocs (0.00s)
=== RUN TestReadyNodesInDCs
--- PASS: TestReadyNodesInDCs (0.00s)
=== RUN TestRetryMax
--- PASS: TestRetryMax (0.00s)
=== RUN TestTaintedNodes
--- PASS: TestTaintedNodes (0.00s)
=== RUN TestShuffleNodes
--- PASS: TestShuffleNodes (0.00s)
=== RUN TestTasksUpdated
--- PASS: TestTasksUpdated (0.00s)
=== RUN TestEvictAndPlace_LimitLessThanAllocs
--- PASS: TestEvictAndPlace_LimitLessThanAllocs (0.00s)
=== RUN TestEvictAndPlace_LimitEqualToAllocs
--- PASS: TestEvictAndPlace_LimitEqualToAllocs (0.00s)
=== RUN TestSetStatus
--- PASS: TestSetStatus (0.00s)
=== RUN TestInplaceUpdate_ChangedTaskGroup
--- PASS: TestInplaceUpdate_ChangedTaskGroup (0.00s)
=== RUN TestInplaceUpdate_NoMatch
--- PASS: TestInplaceUpdate_NoMatch (0.00s)
=== RUN TestInplaceUpdate_Success
--- PASS: TestInplaceUpdate_Success (0.00s)
=== RUN TestEvictAndPlace_LimitGreaterThanAllocs
--- PASS: TestEvictAndPlace_LimitGreaterThanAllocs (0.00s)
=== RUN TestTaskGroupConstraints
--- FAIL: TestTaskGroupConstraints (0.00s)
util_test.go:886: taskGroupConstraints(&{web 10 [ bar] <nil> [0xc4201624d0 0xc420162580] 0xc4202c6650 map[]}) returned &{1000 512 300 0 []}; want &{1000 512 0 0 []}
=== RUN TestProgressMade
--- PASS: TestProgressMade (0.00s)
=== RUN TestDesiredUpdates
--- PASS: TestDesiredUpdates (0.00s)
=== RUN TestUtil_AdjustQueuedAllocations
--- PASS: TestUtil_AdjustQueuedAllocations (0.00s)
=== RUN TestUtil_UpdateNonTerminalAllocsToLost
--- PASS: TestUtil_UpdateNonTerminalAllocsToLost (0.00s)
FAIL
exit status 1
FAIL github.com/hashicorp/nomad/scheduler 0.070s

View File

@ -10,9 +10,10 @@ import (
// along with a node when iterating. This state can be modified as
// various rank methods are applied.
type RankedNode struct {
Node *structs.Node
Score float64
TaskResources map[string]*structs.Resources
Node *structs.Node
Score float64
TaskResources map[string]*structs.Resources
AllocResources *structs.Resources
// Allocs is used to cache the proposed allocations on the
// node. This can be shared between iterators that require it.
@ -44,6 +45,10 @@ func (r *RankedNode) SetTaskResources(task *structs.Task,
r.TaskResources[task.Name] = resource
}
func (r *RankedNode) SetAllocResources(resources *structs.Resources) {
r.AllocResources = resources
}
// RankFeasibleIterator is used to iteratively yield nodes along
// with ranking metadata. The iterators may manage some state for
// performance optimizations.
@ -131,11 +136,11 @@ func (iter *StaticRankIterator) Reset() {
// BinPackIterator is a RankIterator that scores potential options
// based on a bin-packing algorithm.
type BinPackIterator struct {
ctx Context
source RankIterator
evict bool
priority int
tasks []*structs.Task
ctx Context
source RankIterator
evict bool
priority int
taskGroup *structs.TaskGroup
}
// NewBinPackIterator returns a BinPackIterator which tries to fit tasks
@ -154,8 +159,8 @@ func (iter *BinPackIterator) SetPriority(p int) {
iter.priority = p
}
func (iter *BinPackIterator) SetTasks(tasks []*structs.Task) {
iter.tasks = tasks
func (iter *BinPackIterator) SetTaskGroup(taskGroup *structs.TaskGroup) {
iter.taskGroup = taskGroup
}
func (iter *BinPackIterator) Next() *RankedNode {
@ -182,8 +187,10 @@ OUTER:
netIdx.AddAllocs(proposed)
// Assign the resources for each task
total := new(structs.Resources)
for _, task := range iter.tasks {
total := &structs.Resources{
DiskMB: iter.taskGroup.LocalDisk.DiskMB,
}
for _, task := range iter.taskGroup.Tasks {
taskResources := task.Resources.Copy()
// Check if we need a network resource
@ -210,6 +217,7 @@ OUTER:
// Accumulate the total resource requirement
total.Add(taskResources)
}
option.AllocResources = total
// Add the resources we are trying to fit
proposed = append(proposed, &structs.Allocation{Resources: total})

View File

@ -68,16 +68,20 @@ func TestBinPackIterator_NoExistingAlloc(t *testing.T) {
}
static := NewStaticRankIterator(ctx, nodes)
task := &structs.Task{
Name: "web",
Resources: &structs.Resources{
CPU: 1024,
MemoryMB: 1024,
taskGroup := &structs.TaskGroup{
LocalDisk: &structs.LocalDisk{},
Tasks: []*structs.Task{
{
Name: "web",
Resources: &structs.Resources{
CPU: 1024,
MemoryMB: 1024,
},
},
},
}
binp := NewBinPackIterator(ctx, static, false, 0)
binp.SetTasks([]*structs.Task{task})
binp.SetTaskGroup(taskGroup)
out := collectRanked(binp)
if len(out) != 2 {
@ -142,16 +146,21 @@ func TestBinPackIterator_PlannedAlloc(t *testing.T) {
},
}
task := &structs.Task{
Name: "web",
Resources: &structs.Resources{
CPU: 1024,
MemoryMB: 1024,
taskGroup := &structs.TaskGroup{
LocalDisk: &structs.LocalDisk{},
Tasks: []*structs.Task{
{
Name: "web",
Resources: &structs.Resources{
CPU: 1024,
MemoryMB: 1024,
},
},
},
}
binp := NewBinPackIterator(ctx, static, false, 0)
binp.SetTasks([]*structs.Task{task})
binp.SetTaskGroup(taskGroup)
out := collectRanked(binp)
if len(out) != 1 {
@ -223,16 +232,20 @@ func TestBinPackIterator_ExistingAlloc(t *testing.T) {
noErr(t, state.UpsertJobSummary(999, mock.JobSummary(alloc2.JobID)))
noErr(t, state.UpsertAllocs(1000, []*structs.Allocation{alloc1, alloc2}))
task := &structs.Task{
Name: "web",
Resources: &structs.Resources{
CPU: 1024,
MemoryMB: 1024,
taskGroup := &structs.TaskGroup{
LocalDisk: &structs.LocalDisk{},
Tasks: []*structs.Task{
{
Name: "web",
Resources: &structs.Resources{
CPU: 1024,
MemoryMB: 1024,
},
},
},
}
binp := NewBinPackIterator(ctx, static, false, 0)
binp.SetTasks([]*structs.Task{task})
binp.SetTaskGroup(taskGroup)
out := collectRanked(binp)
if len(out) != 1 {
@ -307,16 +320,21 @@ func TestBinPackIterator_ExistingAlloc_PlannedEvict(t *testing.T) {
plan := ctx.Plan()
plan.NodeUpdate[nodes[0].Node.ID] = []*structs.Allocation{alloc1}
task := &structs.Task{
Name: "web",
Resources: &structs.Resources{
CPU: 1024,
MemoryMB: 1024,
taskGroup := &structs.TaskGroup{
LocalDisk: &structs.LocalDisk{},
Tasks: []*structs.Task{
{
Name: "web",
Resources: &structs.Resources{
CPU: 1024,
MemoryMB: 1024,
},
},
},
}
binp := NewBinPackIterator(ctx, static, false, 0)
binp.SetTasks([]*structs.Task{task})
binp.SetTaskGroup(taskGroup)
out := collectRanked(binp)
if len(out) != 2 {

View File

@ -154,7 +154,7 @@ func (s *GenericStack) Select(tg *structs.TaskGroup) (*RankedNode, *structs.Reso
s.taskGroupConstraint.SetConstraints(tgConstr.constraints)
s.proposedAllocConstraint.SetTaskGroup(tg)
s.wrappedChecks.SetTaskGroup(tg.Name)
s.binPack.SetTasks(tg.Tasks)
s.binPack.SetTaskGroup(tg)
// Find the node with the max score
option := s.maxScore.Next()
@ -242,7 +242,7 @@ func (s *SystemStack) Select(tg *structs.TaskGroup) (*RankedNode, *structs.Resou
// Update the parameters of iterators
s.taskGroupDrivers.SetDrivers(tgConstr.drivers)
s.taskGroupConstraint.SetConstraints(tgConstr.constraints)
s.binPack.SetTasks(tg.Tasks)
s.binPack.SetTaskGroup(tg)
s.wrappedChecks.SetTaskGroup(tg.Name)
// Get the next option that satisfies the constraints.

View File

@ -540,7 +540,7 @@ func taskGroupConstraints(tg *structs.TaskGroup) tgConstrainTuple {
c := tgConstrainTuple{
constraints: make([]*structs.Constraint, 0, len(tg.Constraints)),
drivers: make(map[string]struct{}),
size: new(structs.Resources),
size: &structs.Resources{DiskMB: tg.LocalDisk.DiskMB},
}
c.constraints = append(c.constraints, tg.Constraints...)

View File

@ -846,6 +846,7 @@ func TestTaskGroupConstraints(t *testing.T) {
Name: "web",
Count: 10,
Constraints: []*structs.Constraint{constr},
LocalDisk: &structs.LocalDisk{},
Tasks: []*structs.Task{
&structs.Task{
Driver: "exec",