Merged in experimentation/schedPolicySwitcher (pull request #1)
Experimentation/schedPolicySwitcher 1. Initial commit for consolidated loggers using observer pattern. 2. class factory for schedulers. 3. Using the scheduling policy class factory in schedulers/store.go and the scheduler builder helpers in schedulers/helpers.go, feature to be able to be able to plug a scheduling policy of your choice from the command line (right now only first-fit and bin-packing are possible. Will be updating the class factory to include other scheduling policies as well. 4. Removed TODO for using generic task sorters. Modified TODO for a config file input to run electron. 5. Added other schedulers to the factory 6. Partially retrofitted the other scheduling policies to use the logging library. 7. Retrofitted extrema and progressive to use the consolidated logging library. Fixed parameter issue with s.base.Disconnected(). Formatted project 8. Move statusUpdate(...) into base.go to remove redundant code. 9. Converted the baseScheduler into a state machine where the state is a scheduling policy that defines an approach to consume resource offers. 10. Added another command line argument to be used to enable switching of scheduling policies. Retrofitted scheduling policies to switch only if the particular feature has been enabled. changed argument to coLocated(...) to take base type rather than ElectronScheduler type. Also, prepended the prefix to the directory of the logs so that it would be easier to determine what the files in a directory correspond to without viewing the contents of the directory. Defined methods in ElectronScheduler. Each of these methods corresponds to a type of log that an ElectronScheduler would make. Each of these methods would need to be implemented by the scheduling policy. Electron has only one scheduler that implements the mesos scheduler interface. All the scheduling policies are just different implementations of ways to consume mesos resource offers. Retrofitted scheduling policies to now embed SchedPolicyState instead of baseScheduler. Approved-by: Pradyumna Kaushik <pkaushi1@binghamton.edu>
This commit is contained in:
parent
cb71153362
commit
065705d480
24 changed files with 1392 additions and 917 deletions
97
scheduler.go
97
scheduler.go
|
@ -4,6 +4,7 @@ import (
|
|||
"bitbucket.org/sunybingcloud/elektron/def"
|
||||
"bitbucket.org/sunybingcloud/elektron/pcp"
|
||||
"bitbucket.org/sunybingcloud/elektron/schedulers"
|
||||
elecLogDef "bitbucket.org/sunybingcloud/elektron/logging/def"
|
||||
"flag"
|
||||
"fmt"
|
||||
"github.com/golang/protobuf/proto"
|
||||
|
@ -12,44 +13,39 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var master = flag.String("master", "", "Location of leading Mesos master -- <mesos-master>:<port>")
|
||||
var tasksFile = flag.String("workload", "", "JSON file containing task definitions")
|
||||
var wattsAsAResource = flag.Bool("wattsAsAResource", false, "Enable Watts as a Resource. "+
|
||||
"This allows the usage of the Watts attribute (if present) in the workload definition during offer matching.")
|
||||
var pcplogPrefix = flag.String("logPrefix", "", "Prefix for PCP log file")
|
||||
var hiThreshold = flag.Float64("hiThreshold", 0.0, "Upperbound for Cluster average historical power consumption, "+
|
||||
"beyond which extrema/progressive-extrema would start power-capping")
|
||||
var loThreshold = flag.Float64("loThreshold", 0.0, "Lowerbound for Cluster average historical power consumption, "+
|
||||
"below which extrema/progressive-extrema would stop power-capping")
|
||||
var classMapWatts = flag.Bool("classMapWatts", false, "Enable mapping of watts to powerClass of node")
|
||||
var schedPolicyName = flag.String("schedPolicy", "first-fit", "Name of the scheduling policy to be used (default = first-fit).\n "+
|
||||
"Use option -listSchedPolicies to get the names of available scheduling policies")
|
||||
var listSchedPolicies = flag.Bool("listSchedPolicies", false, "Names of the pluaggable scheduling policies.")
|
||||
var wattsAsAResource = flag.Bool("wattsAsAResource", false, "Enable Watts as a Resource")
|
||||
var pcplogPrefix = flag.String("logPrefix", "", "Prefix for pcplog")
|
||||
var hiThreshold = flag.Float64("hiThreshold", 0.0, "Upperbound for when we should start capping")
|
||||
var loThreshold = flag.Float64("loThreshold", 0.0, "Lowerbound for when we should start uncapping")
|
||||
var classMapWatts = flag.Bool("classMapWatts", false, "Enable mapping of watts to power class of node")
|
||||
var schedPolicyName = flag.String("schedPolicy", "first-fit", "Name of the scheduling policy to be used.\n\tUse option -listSchedPolicies to get the names of available scheduling policies")
|
||||
var listSchedPolicies = flag.Bool("listSchedPolicies", false, "List the names of the pluaggable scheduling policies.")
|
||||
var enableSchedPolicySwitch = flag.Bool("switchSchedPolicy", false, "Enable switching of scheduling policies at runtime.")
|
||||
|
||||
// Short hand args.
|
||||
// Short hand args
|
||||
func init() {
|
||||
flag.StringVar(master, "m", "", "Location of leading Mesos master (shorthand)")
|
||||
flag.StringVar(tasksFile, "w", "", "JSON file containing task definitions (shorthand)")
|
||||
flag.BoolVar(wattsAsAResource, "waar", false, "Enable Watts as a Resource. "+
|
||||
"This allows the usage of the Watts attribute (if present) in the workload definition during offer matching. (shorthand)")
|
||||
flag.StringVar(pcplogPrefix, "p", "", "Prefix for PCP log file (shorthand)")
|
||||
flag.Float64Var(hiThreshold, "ht", 700.0, "Upperbound for Cluster average historical power consumption, "+
|
||||
"beyond which extrema/progressive-extrema would start power-capping (shorthand)")
|
||||
flag.Float64Var(loThreshold, "lt", 400.0, "Lowerbound for Cluster average historical power consumption, "+
|
||||
"below which extrema/progressive-extrema would stop power-capping (shorthand)")
|
||||
flag.BoolVar(classMapWatts, "cmw", false, "Enable mapping of watts to powerClass of node (shorthand)")
|
||||
flag.StringVar(schedPolicyName, "sp", "first-fit", "Name of the scheduling policy to be used (default = first-fit).\n "+
|
||||
"Use option -listSchedPolicies to get the names of available scheduling policies (shorthand)")
|
||||
flag.BoolVar(wattsAsAResource, "waar", false, "Enable Watts as a Resource (shorthand)")
|
||||
flag.StringVar(pcplogPrefix, "p", "", "Prefix for pcplog (shorthand)")
|
||||
flag.Float64Var(hiThreshold, "ht", 700.0, "Upperbound for when we should start capping (shorthand)")
|
||||
flag.Float64Var(loThreshold, "lt", 400.0, "Lowerbound for when we should start uncapping (shorthand)")
|
||||
flag.BoolVar(classMapWatts, "cmw", false, "Enable mapping of watts to power class of node (shorthand)")
|
||||
flag.StringVar(schedPolicyName, "sp", "first-fit", "Name of the scheduling policy to be used.\n Use option -listSchedPolicies to get the names of available scheduling policies (shorthand)")
|
||||
flag.BoolVar(listSchedPolicies, "lsp", false, "Names of the pluaggable scheduling policies. (shorthand)")
|
||||
flag.BoolVar(enableSchedPolicySwitch, "ssp", false, "Enable switching of scheduling policies at runtime.")
|
||||
}
|
||||
|
||||
func listAllSchedulingPolicies() {
|
||||
fmt.Println("Scheduling Policies")
|
||||
fmt.Println("-------------------")
|
||||
for policyName, _ := range schedulers.Schedulers {
|
||||
for policyName, _ := range schedulers.SchedPolicies {
|
||||
fmt.Println(policyName)
|
||||
}
|
||||
}
|
||||
|
@ -57,17 +53,32 @@ func listAllSchedulingPolicies() {
|
|||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
// Checking to see if we need to just list the pluggable scheduling policies.
|
||||
// checking to see if we need to just list the pluggable scheduling policies
|
||||
if *listSchedPolicies {
|
||||
listAllSchedulingPolicies()
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
startTime := time.Now()
|
||||
formattedStartTime := startTime.Format("20060102150405")
|
||||
// Checking if prefix contains any special characters
|
||||
if strings.Contains(*pcplogPrefix, "/") {
|
||||
log.Fatal("log file prefix should not contain '/'.")
|
||||
}
|
||||
logPrefix := *pcplogPrefix + "_" + formattedStartTime
|
||||
|
||||
// creating logger and attaching different logging platforms
|
||||
logger := elecLogDef.BuildLogger(startTime, logPrefix)
|
||||
// logging channels
|
||||
logMType := make(chan elecLogDef.LogMessageType)
|
||||
logMsg := make(chan string)
|
||||
go logger.Listen(logMType, logMsg)
|
||||
|
||||
// If non-default scheduling policy given,
|
||||
// checking if scheduling policyName exists.
|
||||
// checking if scheduling policyName exists
|
||||
if *schedPolicyName != "first-fit" {
|
||||
if _, ok := schedulers.Schedulers[*schedPolicyName]; !ok {
|
||||
// Invalid scheduling policy.
|
||||
if _, ok := schedulers.SchedPolicies[*schedPolicyName]; !ok {
|
||||
// invalid scheduling policy
|
||||
log.Println("Invalid scheduling policy given. The possible scheduling policies are:")
|
||||
listAllSchedulingPolicies()
|
||||
os.Exit(1)
|
||||
|
@ -75,41 +86,45 @@ func main() {
|
|||
}
|
||||
|
||||
if *tasksFile == "" {
|
||||
fmt.Println("No file containing tasks specifiction provided.")
|
||||
//fmt.Println("No file containing tasks specifiction provided.")
|
||||
logger.WriteLog(elecLogDef.ERROR, "No file containing tasks specification provided")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if *hiThreshold < *loThreshold {
|
||||
fmt.Println("High threshold is of a lower value than low threshold.")
|
||||
//fmt.Println("High threshold is of a lower value than low threshold.")
|
||||
logger.WriteLog(elecLogDef.ERROR, "High threshold is of a lower value than low threshold")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
tasks, err := def.TasksFromJSON(*tasksFile)
|
||||
if err != nil || len(tasks) == 0 {
|
||||
fmt.Println("Invalid tasks specification file provided")
|
||||
//fmt.Println("Invalid tasks specification file provided")
|
||||
logger.WriteLog(elecLogDef.ERROR, "Invalid tasks specification file provided")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
log.Println("Scheduling the following tasks:")
|
||||
//log.Println("Scheduling the following tasks:")
|
||||
logger.WriteLog(elecLogDef.GENERAL, "Scheduling the following tasks:")
|
||||
for _, task := range tasks {
|
||||
fmt.Println(task)
|
||||
}
|
||||
startTime := time.Now().Format("20060102150405")
|
||||
logPrefix := *pcplogPrefix + "_" + startTime
|
||||
|
||||
shutdown := make(chan struct{})
|
||||
done := make(chan struct{})
|
||||
pcpLog := make(chan struct{})
|
||||
recordPCP := false
|
||||
scheduler := schedulers.SchedFactory(*schedPolicyName,
|
||||
scheduler := schedulers.SchedFactory(
|
||||
schedulers.WithSchedPolicy(*schedPolicyName),
|
||||
schedulers.WithTasks(tasks),
|
||||
schedulers.WithWattsAsAResource(*wattsAsAResource),
|
||||
schedulers.WithClassMapWatts(*classMapWatts),
|
||||
schedulers.WithSchedTracePrefix(logPrefix),
|
||||
schedulers.WithRecordPCP(&recordPCP),
|
||||
schedulers.WithShutdown(shutdown),
|
||||
schedulers.WithDone(done),
|
||||
schedulers.WithPCPLog(pcpLog))
|
||||
schedulers.WithPCPLog(pcpLog),
|
||||
schedulers.WithLoggingChannels(logMType, logMsg),
|
||||
schedulers.WithSchedPolSwitchEnabled(*enableSchedPolicySwitch))
|
||||
driver, err := sched.NewMesosSchedulerDriver(sched.DriverConfig{
|
||||
Master: *master,
|
||||
Framework: &mesos.FrameworkInfo{
|
||||
|
@ -123,10 +138,10 @@ func main() {
|
|||
return
|
||||
}
|
||||
|
||||
go pcp.Start(pcpLog, &recordPCP, logPrefix)
|
||||
//go pcp.StartPCPLogAndExtremaDynamicCap(pcpLog, &recordPCP, logPrefix, *hiThreshold, *loThreshold)
|
||||
//go pcp.StartPCPLogAndProgressiveExtremaCap(pcpLog, &recordPCP, logPrefix, *hiThreshold, *loThreshold)
|
||||
time.Sleep(1 * time.Second) // Take a second between starting PCP log and continuing.
|
||||
go pcp.Start(pcpLog, &recordPCP, logMType, logMsg)
|
||||
//go pcp.StartPCPLogAndExtremaDynamicCap(pcpLog, &recordPCP, *hiThreshold, *loThreshold, logMType, logMsg)
|
||||
//go pcp.StartPCPLogAndProgressiveExtremaCap(pcpLog, &recordPCP, *hiThreshold, *loThreshold, logMType, logMsg)
|
||||
time.Sleep(1 * time.Second) // Take a second between starting PCP log and continuing
|
||||
|
||||
// Attempt to handle SIGINT to not leave pmdumptext running.
|
||||
// Catch interrupt.
|
||||
|
@ -156,6 +171,8 @@ func main() {
|
|||
case <-done:
|
||||
close(pcpLog)
|
||||
time.Sleep(5 * time.Second) //Wait for PCP to log a few more seconds
|
||||
close(logMType)
|
||||
close(logMsg)
|
||||
//case <-time.After(shutdownTimeout):
|
||||
}
|
||||
|
||||
|
|
Reference in a new issue