Spark
Executing individual steps on Spark
The spark
integration brings two different step operators:
Step Operator: The
SparkStepOperator
serves as the base class for all the Spark-related step operators.Step Operator: The
KubernetesSparkStepOperator
is responsible for launching ZenML steps as Spark applications with Kubernetes as a cluster manager.
Step Operators: SparkStepOperator
SparkStepOperator
A summarized version of the implementation can be summarized in two parts. First, the configuration:
and then the implementation:
Under the base configuration, you will see the main configuration parameters:
master
is the master URL for the cluster where Spark will run. You might see different schemes for this URL with varying cluster managers such as Mesos, YARN, or Kubernetes.deploy_mode
can either be 'cluster' (default) or 'client' and it decides where the driver node of the application will run.submit_args
is the JSON string of a dictionary, which will be used to define additional parameters if required ( Spark has a wide variety of parameters, thus including them all in a single class was deemed unnecessary.).
In addition to this configuration, the launch
method of the step operator gets additional configuration parameters from the DockerSettings
and ResourceSettings
. As a result, the overall configuration happens in 4 base methods:
_resource_configuration
translates the ZenMLResourceSettings
object to Spark's own resource configuration._backend_configuration
is responsible for cluster-manager-specific configuration._io_configuration
is a critical method. Even though we have materializers, Spark might require additional packages and configuration to work with a specific filesystem. This method is used as an interface to provide this configuration._additional_configuration
takes thesubmit_args
, converts, and appends them to the overall configuration.
Once the configuration is completed, _launch_spark_job
comes into play. This takes the completed configuration and runs a Spark job on the given master
URL with the specified deploy_mode
. By default, this is achieved by creating and executing a spark-submit
command.
Warning
In its first iteration, the pre-configuration with _io_configuration
method is only effective when it is paired with an S3ArtifactStore
(which has an authentication secret). When used with other artifact store flavors, you might be required to provide additional configuration through the submit_args
.
Stack Component: KubernetesSparkStepOperator
KubernetesSparkStepOperator
The KubernetesSparkStepOperator
is implemented by subclassing the base SparkStepOperator
and uses the PipelineDockerImageBuilder
class to build and push the required Docker images.
For Kubernetes, there are also some additional important configuration parameters:
namespace
is the namespace under which the driver and executor pods will run.service_account
is the service account that will be used by various Spark components (to create and watch the pods).
Additionally, the _backend_configuration
method is adjusted to handle the Kubernetes-specific configuration.
When to use it
You should use the Spark step operator:
when you are dealing with large amounts of data.
when you are designing a step that can benefit from distributed computing paradigms in terms of time and resources.
How to deploy it
To use the KubernetesSparkStepOperator
you will need to setup a few things first:
Remote ZenML server: See the deployment guide for more information.
Kubernetes cluster: There are many ways to deploy a Kubernetes cluster using different cloud providers or on your custom infrastructure. For AWS, you can follow the Spark EKS Setup Guide below.
Spark EKS Setup Guide
The following guide will walk you through how to spin up and configure a Amazon Elastic Kubernetes Service with Spark on it:
EKS Kubernetes Cluster
Follow this guide to create an Amazon EKS cluster role.
Follow this guide to create an Amazon EC2 node role.
Go to the IAM website, and select
Roles
to edit both roles.Attach the
AmazonRDSFullAccess
andAmazonS3FullAccess
policies to both roles.Go to the EKS website.
Make sure the correct region is selected on the top right.
Click on
Add cluster
and selectCreate
.Enter a name and select the cluster role for
Cluster service role
.Keep the default values for the networking and logging steps and create the cluster.
Note down the cluster name and the API server endpoint:
After the cluster is created, select it and click on
Add node group
in theCompute
tab.Enter a name and select the node role.
For the instance type, we recommend
t3a.xlarge
, as it provides up to 4 vCPUs and 16 GB of memory.
Docker image for the Spark drivers and executors
When you want to run your steps on a Kubernetes cluster, Spark will require you to choose a base image for the driver and executor pods. Normally, for this purpose, you can either use one of the base images in Spark’s dockerhub or create an image using the docker-image-tool which will use your own Spark installation and build an image.
When using Spark in EKS, you need to use the latter and utilize the docker-image-tool
. However, before the build process, you also need to download the following packages
and put them in the jars
folder within your Spark installation. Once that is set up, you can build the image as follows:
If you are working on an M1 Mac, you will need to build the image for the amd64 architecture, by using the prefix -X
on the previous command. For example:
Configuring RBAC
Additionally, you may need to create the several resources in Kubernetes in order to give Spark access to edit/manage your driver executor pods.
To do so, create a file called rbac.yaml
with the following content:
And then execute the following command to create the resources:
Lastly, note down the namespace and the name of the service account since you will need them when registering the stack component in the next step.
How to use it
To use the KubernetesSparkStepOperator
, you need:
the ZenML
spark
integration. If you haven't installed it already, runDocker installed and running.
A remote artifact store as part of your stack.
A remote container registry as part of your stack.
A Kubernetes cluster deployed.
We can then register the step operator and use it in our active stack:
Once you added the step operator to your active stack, you can use it to execute individual steps of your pipeline by specifying it in the @step
decorator as follows:
After successfully running any step with a KubernetesSparkStepOperator
, you should be able to see that a Spark driver pod was created in your cluster for each pipeline step when running kubectl get pods -n $KUBERNETES_NAMESPACE
.
Instead of hardcoding a step operator name, you can also use the Client to dynamically use the step operator of your active stack:
Additional configuration
For additional configuration of the Spark step operator, you can pass SparkStepOperatorSettings
when defining or running your pipeline. Check out the SDK docs for a full list of available attributes and this docs page for more information on how to specify settings.
Last updated