Add ShuffleTrackingEnabled to DynamicAllocation struct to allow disabling shuffle tracking (#2511)
* Add ShuffleTrackingEnabled *bool to DynamicAllocation struct to allow disabling shuffle tracking Signed-off-by: jbhalodia-slack <jbhalodia@salesforce.com> * Run make generate Signed-off-by: jbhalodia-slack <jbhalodia@salesforce.com> * make manifests Signed-off-by: jbhalodia-slack <jbhalodia@salesforce.com> * make update-crd && make build-api-docs Signed-off-by: jbhalodia-slack <jbhalodia@salesforce.com> * Update internal/controller/sparkapplication/submission.go Co-authored-by: Yi Chen <github@chenyicn.net> Signed-off-by: jbhalodia-slack <jbhalodia@salesforce.com> * Go fmt Signed-off-by: jbhalodia-slack <jbhalodia@salesforce.com> * Refactor defaultExecutorSpec func Signed-off-by: jbhalodia-slack <jbhalodia@salesforce.com> * Refactor dynamicAllocationOption func Signed-off-by: jbhalodia-slack <jbhalodia@salesforce.com> * Add IsDynamicAllocationEnabled func Signed-off-by: jbhalodia-slack <jbhalodia@salesforce.com> --------- Signed-off-by: jbhalodia-slack <jbhalodia@salesforce.com> Co-authored-by: Yi Chen <github@chenyicn.net>
This commit is contained in:
parent
0cb98f79cf
commit
ca37f6b7b3
|
@ -703,6 +703,12 @@ type DynamicAllocation struct {
|
||||||
// MaxExecutors is the upper bound for the number of executors if dynamic allocation is enabled.
|
// MaxExecutors is the upper bound for the number of executors if dynamic allocation is enabled.
|
||||||
// +optional
|
// +optional
|
||||||
MaxExecutors *int32 `json:"maxExecutors,omitempty"`
|
MaxExecutors *int32 `json:"maxExecutors,omitempty"`
|
||||||
|
// ShuffleTrackingEnabled enables shuffle file tracking for executors, which allows dynamic allocation without
|
||||||
|
// the need for an external shuffle service. This option will try to keep alive executors that are storing
|
||||||
|
// shuffle data for active jobs. If external shuffle service is enabled, set ShuffleTrackingEnabled to false.
|
||||||
|
// ShuffleTrackingEnabled is true by default if dynamicAllocation.enabled is true.
|
||||||
|
// +optional
|
||||||
|
ShuffleTrackingEnabled *bool `json:"shuffleTrackingEnabled,omitempty"`
|
||||||
// ShuffleTrackingTimeout controls the timeout in milliseconds for executors that are holding
|
// ShuffleTrackingTimeout controls the timeout in milliseconds for executors that are holding
|
||||||
// shuffle data if shuffle tracking is enabled (true by default if dynamic allocation is enabled).
|
// shuffle data if shuffle tracking is enabled (true by default if dynamic allocation is enabled).
|
||||||
// +optional
|
// +optional
|
||||||
|
|
|
@ -279,6 +279,11 @@ func (in *DynamicAllocation) DeepCopyInto(out *DynamicAllocation) {
|
||||||
*out = new(int32)
|
*out = new(int32)
|
||||||
**out = **in
|
**out = **in
|
||||||
}
|
}
|
||||||
|
if in.ShuffleTrackingEnabled != nil {
|
||||||
|
in, out := &in.ShuffleTrackingEnabled, &out.ShuffleTrackingEnabled
|
||||||
|
*out = new(bool)
|
||||||
|
**out = **in
|
||||||
|
}
|
||||||
if in.ShuffleTrackingTimeout != nil {
|
if in.ShuffleTrackingTimeout != nil {
|
||||||
in, out := &in.ShuffleTrackingTimeout, &out.ShuffleTrackingTimeout
|
in, out := &in.ShuffleTrackingTimeout, &out.ShuffleTrackingTimeout
|
||||||
*out = new(int64)
|
*out = new(int64)
|
||||||
|
|
|
@ -5296,6 +5296,13 @@ spec:
|
||||||
of executors if dynamic allocation is enabled.
|
of executors if dynamic allocation is enabled.
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
|
shuffleTrackingEnabled:
|
||||||
|
description: |-
|
||||||
|
ShuffleTrackingEnabled enables shuffle file tracking for executors, which allows dynamic allocation without
|
||||||
|
the need for an external shuffle service. This option will try to keep alive executors that are storing
|
||||||
|
shuffle data for active jobs. If external shuffle service is enabled, set ShuffleTrackingEnabled to false.
|
||||||
|
ShuffleTrackingEnabled is true by default if dynamicAllocation.enabled is true.
|
||||||
|
type: boolean
|
||||||
shuffleTrackingTimeout:
|
shuffleTrackingTimeout:
|
||||||
description: |-
|
description: |-
|
||||||
ShuffleTrackingTimeout controls the timeout in milliseconds for executors that are holding
|
ShuffleTrackingTimeout controls the timeout in milliseconds for executors that are holding
|
||||||
|
|
|
@ -5238,6 +5238,13 @@ spec:
|
||||||
executors if dynamic allocation is enabled.
|
executors if dynamic allocation is enabled.
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
|
shuffleTrackingEnabled:
|
||||||
|
description: |-
|
||||||
|
ShuffleTrackingEnabled enables shuffle file tracking for executors, which allows dynamic allocation without
|
||||||
|
the need for an external shuffle service. This option will try to keep alive executors that are storing
|
||||||
|
shuffle data for active jobs. If external shuffle service is enabled, set ShuffleTrackingEnabled to false.
|
||||||
|
ShuffleTrackingEnabled is true by default if dynamicAllocation.enabled is true.
|
||||||
|
type: boolean
|
||||||
shuffleTrackingTimeout:
|
shuffleTrackingTimeout:
|
||||||
description: |-
|
description: |-
|
||||||
ShuffleTrackingTimeout controls the timeout in milliseconds for executors that are holding
|
ShuffleTrackingTimeout controls the timeout in milliseconds for executors that are holding
|
||||||
|
|
|
@ -5296,6 +5296,13 @@ spec:
|
||||||
of executors if dynamic allocation is enabled.
|
of executors if dynamic allocation is enabled.
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
|
shuffleTrackingEnabled:
|
||||||
|
description: |-
|
||||||
|
ShuffleTrackingEnabled enables shuffle file tracking for executors, which allows dynamic allocation without
|
||||||
|
the need for an external shuffle service. This option will try to keep alive executors that are storing
|
||||||
|
shuffle data for active jobs. If external shuffle service is enabled, set ShuffleTrackingEnabled to false.
|
||||||
|
ShuffleTrackingEnabled is true by default if dynamicAllocation.enabled is true.
|
||||||
|
type: boolean
|
||||||
shuffleTrackingTimeout:
|
shuffleTrackingTimeout:
|
||||||
description: |-
|
description: |-
|
||||||
ShuffleTrackingTimeout controls the timeout in milliseconds for executors that are holding
|
ShuffleTrackingTimeout controls the timeout in milliseconds for executors that are holding
|
||||||
|
|
|
@ -5238,6 +5238,13 @@ spec:
|
||||||
executors if dynamic allocation is enabled.
|
executors if dynamic allocation is enabled.
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
|
shuffleTrackingEnabled:
|
||||||
|
description: |-
|
||||||
|
ShuffleTrackingEnabled enables shuffle file tracking for executors, which allows dynamic allocation without
|
||||||
|
the need for an external shuffle service. This option will try to keep alive executors that are storing
|
||||||
|
shuffle data for active jobs. If external shuffle service is enabled, set ShuffleTrackingEnabled to false.
|
||||||
|
ShuffleTrackingEnabled is true by default if dynamicAllocation.enabled is true.
|
||||||
|
type: boolean
|
||||||
shuffleTrackingTimeout:
|
shuffleTrackingTimeout:
|
||||||
description: |-
|
description: |-
|
||||||
ShuffleTrackingTimeout controls the timeout in milliseconds for executors that are holding
|
ShuffleTrackingTimeout controls the timeout in milliseconds for executors that are holding
|
||||||
|
|
|
@ -741,6 +741,21 @@ int32
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
|
<code>shuffleTrackingEnabled</code><br/>
|
||||||
|
<em>
|
||||||
|
bool
|
||||||
|
</em>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<em>(Optional)</em>
|
||||||
|
<p>ShuffleTrackingEnabled enables shuffle file tracking for executors, which allows dynamic allocation without
|
||||||
|
the need for an external shuffle service. This option will try to keep alive executors that are storing
|
||||||
|
shuffle data for active jobs. If external shuffle service is enabled, set ShuffleTrackingEnabled to false.
|
||||||
|
ShuffleTrackingEnabled is true by default if dynamicAllocation.enabled is true.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
<code>shuffleTrackingTimeout</code><br/>
|
<code>shuffleTrackingTimeout</code><br/>
|
||||||
<em>
|
<em>
|
||||||
int64
|
int64
|
||||||
|
|
|
@ -989,10 +989,6 @@ func dynamicAllocationOption(app *v1beta2.SparkApplication) ([]string, error) {
|
||||||
args = append(args, "--conf",
|
args = append(args, "--conf",
|
||||||
fmt.Sprintf("%s=true", common.SparkDynamicAllocationEnabled))
|
fmt.Sprintf("%s=true", common.SparkDynamicAllocationEnabled))
|
||||||
|
|
||||||
// Turn on shuffle tracking if dynamic allocation is enabled.
|
|
||||||
args = append(args, "--conf",
|
|
||||||
fmt.Sprintf("%s=true", common.SparkDynamicAllocationShuffleTrackingEnabled))
|
|
||||||
|
|
||||||
if dynamicAllocation.InitialExecutors != nil {
|
if dynamicAllocation.InitialExecutors != nil {
|
||||||
args = append(args, "--conf",
|
args = append(args, "--conf",
|
||||||
fmt.Sprintf("%s=%d", common.SparkDynamicAllocationInitialExecutors, *dynamicAllocation.InitialExecutors))
|
fmt.Sprintf("%s=%d", common.SparkDynamicAllocationInitialExecutors, *dynamicAllocation.InitialExecutors))
|
||||||
|
@ -1005,6 +1001,12 @@ func dynamicAllocationOption(app *v1beta2.SparkApplication) ([]string, error) {
|
||||||
args = append(args, "--conf",
|
args = append(args, "--conf",
|
||||||
fmt.Sprintf("%s=%d", common.SparkDynamicAllocationMaxExecutors, *dynamicAllocation.MaxExecutors))
|
fmt.Sprintf("%s=%d", common.SparkDynamicAllocationMaxExecutors, *dynamicAllocation.MaxExecutors))
|
||||||
}
|
}
|
||||||
|
shuffleTrackingEnabled := true
|
||||||
|
if dynamicAllocation.ShuffleTrackingEnabled != nil {
|
||||||
|
shuffleTrackingEnabled = *dynamicAllocation.ShuffleTrackingEnabled
|
||||||
|
}
|
||||||
|
args = append(args, "--conf",
|
||||||
|
fmt.Sprintf("%s=%t", common.SparkDynamicAllocationShuffleTrackingEnabled, shuffleTrackingEnabled))
|
||||||
if dynamicAllocation.ShuffleTrackingTimeout != nil {
|
if dynamicAllocation.ShuffleTrackingTimeout != nil {
|
||||||
args = append(args, "--conf",
|
args = append(args, "--conf",
|
||||||
fmt.Sprintf("%s=%d", common.SparkDynamicAllocationShuffleTrackingTimeout, *dynamicAllocation.ShuffleTrackingTimeout))
|
fmt.Sprintf("%s=%d", common.SparkDynamicAllocationShuffleTrackingTimeout, *dynamicAllocation.ShuffleTrackingTimeout))
|
||||||
|
|
|
@ -18,7 +18,6 @@ package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||||
|
@ -86,17 +85,21 @@ func defaultDriverSpec(app *v1beta2.SparkApplication) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func defaultExecutorSpec(app *v1beta2.SparkApplication) {
|
func defaultExecutorSpec(app *v1beta2.SparkApplication) {
|
||||||
if app.Spec.Executor.Instances == nil {
|
|
||||||
// Check whether dynamic allocation is enabled in application spec.
|
isDynamicAllocationEnabled := util.IsDynamicAllocationEnabled(app)
|
||||||
enableDynamicAllocation := app.Spec.DynamicAllocation != nil && app.Spec.DynamicAllocation.Enabled
|
|
||||||
// Check whether dynamic allocation is enabled in spark conf.
|
if app.Spec.Executor.Instances == nil &&
|
||||||
if !enableDynamicAllocation && app.Spec.SparkConf != nil {
|
app.Spec.SparkConf[common.SparkExecutorInstances] == "" &&
|
||||||
if dynamicConf, _ := strconv.ParseBool(app.Spec.SparkConf[common.SparkDynamicAllocationEnabled]); dynamicConf {
|
!isDynamicAllocationEnabled {
|
||||||
enableDynamicAllocation = true
|
app.Spec.Executor.Instances = util.Int32Ptr(1)
|
||||||
}
|
|
||||||
if !enableDynamicAllocation && app.Spec.SparkConf[common.SparkExecutorInstances] == "" {
|
|
||||||
app.Spec.Executor.Instances = util.Int32Ptr(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set default for ShuffleTrackingEnabled to true if DynamicAllocation.enabled is true and
|
||||||
|
// DynamicAllocation.ShuffleTrackingEnabled is nil.
|
||||||
|
if isDynamicAllocationEnabled &&
|
||||||
|
app.Spec.DynamicAllocation != nil &&
|
||||||
|
app.Spec.DynamicAllocation.ShuffleTrackingEnabled == nil {
|
||||||
|
app.Spec.DynamicAllocation.ShuffleTrackingEnabled = util.BoolPtr(true)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -495,3 +496,13 @@ func GetInitialExecutorNumber(app *v1beta2.SparkApplication) int32 {
|
||||||
|
|
||||||
return initialNumExecutors
|
return initialNumExecutors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsDynamicAllocationEnabled determines if Spark Dynamic Allocation is enabled in app.Spec.DynamicAllocation or in
|
||||||
|
// app.Spec.SparkConf. app.Spec.DynamicAllocation configs will take precedence over app.Spec.SparkConf configs.
|
||||||
|
func IsDynamicAllocationEnabled(app *v1beta2.SparkApplication) bool {
|
||||||
|
if app.Spec.DynamicAllocation != nil {
|
||||||
|
return app.Spec.DynamicAllocation.Enabled
|
||||||
|
}
|
||||||
|
dynamicAllocationConfVal, _ := strconv.ParseBool(app.Spec.SparkConf[common.SparkDynamicAllocationEnabled])
|
||||||
|
return dynamicAllocationConfVal
|
||||||
|
}
|
||||||
|
|
|
@ -356,3 +356,69 @@ var _ = Describe("DriverStateToApplicationState", func() {
|
||||||
Expect(util.DriverStateToApplicationState(v1beta2.DriverStateUnknown)).To(Equal(v1beta2.ApplicationStateUnknown))
|
Expect(util.DriverStateToApplicationState(v1beta2.DriverStateUnknown)).To(Equal(v1beta2.ApplicationStateUnknown))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
var _ = Describe("Check if IsDynamicAllocationEnabled", func() {
|
||||||
|
Context("when app.Spec.DynamicAllocation is True", func() {
|
||||||
|
app := &v1beta2.SparkApplication{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-app",
|
||||||
|
Namespace: "test-namespace",
|
||||||
|
},
|
||||||
|
Spec: v1beta2.SparkApplicationSpec{
|
||||||
|
DynamicAllocation: &v1beta2.DynamicAllocation{
|
||||||
|
Enabled: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
It("Should return true", func() {
|
||||||
|
Expect(util.IsDynamicAllocationEnabled(app)).To(BeTrue())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Context("when app.Spec.DynamicAllocation is nil but True in app.Spec.SparkConf", func() {
|
||||||
|
app := &v1beta2.SparkApplication{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-app",
|
||||||
|
Namespace: "test-namespace",
|
||||||
|
},
|
||||||
|
Spec: v1beta2.SparkApplicationSpec{
|
||||||
|
SparkConf: map[string]string{
|
||||||
|
"spark.dynamicAllocation.enabled": "true",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
It("Should return true", func() {
|
||||||
|
Expect(util.IsDynamicAllocationEnabled(app)).To(BeTrue())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Context("when app.Spec.DynamicAllocation is nil and not set in app.Spec.SparkConf", func() {
|
||||||
|
app := &v1beta2.SparkApplication{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-app",
|
||||||
|
Namespace: "test-namespace",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
It("Should return false", func() {
|
||||||
|
Expect(util.IsDynamicAllocationEnabled(app)).To(BeFalse())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Context("when app.Spec.DynamicAllocation is True but false in app.Spec.SparkConf", func() {
|
||||||
|
app := &v1beta2.SparkApplication{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "test-app",
|
||||||
|
Namespace: "test-namespace",
|
||||||
|
},
|
||||||
|
Spec: v1beta2.SparkApplicationSpec{
|
||||||
|
DynamicAllocation: &v1beta2.DynamicAllocation{
|
||||||
|
Enabled: true,
|
||||||
|
},
|
||||||
|
SparkConf: map[string]string{
|
||||||
|
"spark.dynamicAllocation.enabled": "false",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
It("Should return true because app.Spec.DynamicAllocation configs will take precedence over "+
|
||||||
|
"app.Spec.SparkConf configs", func() {
|
||||||
|
Expect(util.IsDynamicAllocationEnabled(app)).To(BeTrue())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in New Issue