Monitor Apache Spark applications on Amazon EMR with Amazon Cloudwatch
To improve a Spark application’s efficiency, it’s essential to monitor its performance and behavior. In this post, we demonstrate how to publish detailed Spark metrics from Amazon EMR to Amazon CloudWatch. This will give you the ability to identify bottlenecks while optimizing resource utilization.
CloudWatch provides a robust, scalable, and cost-effective monitoring solution for AWS resources and applications, with powerful customization options and seamless integration with other AWS services. By default, Amazon EMR sends basic metrics to CloudWatch to track the activity and health of a cluster. Spark’s configurable metrics system allows metrics to be collected in a variety of sinks, including HTTP, JMX, and CSV files, but additional configuration is required to enable Spark to publish metrics to CloudWatch.
This solution includes Spark configuration to send metrics to a custom sink. The custom sink collects only the metrics defined in a Metricfilter.json file. It utilizes the CloudWatch agent to publish the metrics to a custom Cloudwatch namespace. The bootstrap action script included is responsible for installing and configuring the CloudWatch agent and the metric library on the Amazon Elastic Compute Cloud (Amazon EC2) EMR instances. A CloudWatch dashboard can provide instant insight into the performance of an application.
The following diagram illustrates the solution architecture and workflow.
The workflow includes the following steps:
- Users start a Spark EMR job, creating a step on the EMR cluster. With Apache Spark, the workload is distributed across the different nodes of the EMR cluster.
- In each node (EC2 instance) of the cluster, a Spark library captures and pushes metric data to a CloudWatch agent, which aggregates the metric data before pushing them to CloudWatch every 30 seconds.
- Users can view the metrics accessing the custom namespace on the CloudWatch console.
We provide an AWS CloudFormation template in this post as a general guide. The template demonstrates how to configure a CloudWatch agent on Amazon EMR to push Spark metrics to CloudWatch. You can review and customize it as needed to include your Amazon EMR security configurations. As a best practice, we recommend including your Amazon EMR security configurations in the template to encrypt data in transit.
You should also be aware that some of the resources deployed by this stack incur costs when they remain in use. Additionally, EMR metrics don’t incur CloudWatch costs. However, custom metrics incur charges based on CloudWatch metrics pricing. For more information, see Amazon CloudWatch Pricing.
In the next sections, we go through the following steps:
- Create and upload the metrics library, installation script, and filter definition to an Amazon Simple Storage Service (Amazon S3) bucket.
- Use the CloudFormation template to create the following resources:
- An AWS Identity and Access Management (IAM) instance profile role for Amazon EMR.
- An EMR cluster with Spark as an installed application.
- A Spark job.
- Monitor the Spark metrics on the CloudWatch console.
This post assumes that you have the following:
- An AWS account.
- An S3 bucket for storing the bootstrap script, library, and metric filter definition.
- A VPC created in Amazon Virtual Private Cloud (Amazon VPC), where your EMR cluster will be launched.
- Default IAM service roles for Amazon EMR permissions to AWS services and resources. You can create these roles with the aws emr create-default-roles command in the AWS Command Line Interface (AWS CLI).
- An optional EC2 key pair, if you plan to connect to your cluster through SSH rather than Session Manager, a capability of AWS Systems Manager.
Define the required metrics
To avoid sending unnecessary data to CloudWatch, our solution implements a metric filter. Review the Spark documentation to get acquainted with the namespaces and their associated metrics. Determine which metrics are relevant to your specific application and performance goals. Different applications may require different metrics to monitor, depending on the workload, data processing requirements, and optimization objectives. The metric names you’d like to monitor should be defined in the Metricfilter.json file, along with their associated namespaces.
We have created an example Metricfilter.json definition, which includes capturing metrics related to data I/O, garbage collection, memory and CPU pressure, and Spark job, stage, and task metrics.
Note that certain metrics are not available in all Spark release versions (for example, appStatus was introduced in Spark 3.0).
Create and upload the required files to an S3 bucket
For more information, see Uploading objects and Installing and running the CloudWatch agent on your servers.
To create and the upload the bootstrap script, complete the following steps:
- On the Amazon S3 console, choose your S3 bucket.
- On the Objects tab, choose Upload.
- Choose Add files, then choose the Metricfilter.json, installer.sh, and examplejob.sh files.
- Additionally, upload the
emr-custom-cw-sink-0.0.1.jarmetrics library file that corresponds to the Amazon EMR release version you will be using:
- Choose Upload, and take note of the S3 URIs for the files.
Provision resources with the CloudFormation template
Choose Launch Stack to launch a CloudFormation stack in your account and deploy the template:
This template creates an IAM role, IAM instance profile, EMR cluster, and CloudWatch dashboard. The cluster starts a basic Spark example application. You will be billed for the AWS resources used if you create a stack from this template.
The CloudFormation wizard will ask you to modify or provide these parameters:
- InstanceType – The type of instance for all instance groups. The default is m5.2xlarge.
- InstanceCountCore – The number of instances in the core instance group. The default is 4.
- EMRReleaseLabel – The Amazon EMR release label you want to use. The default is emr-6.9.0.
- BootstrapScriptPath – The S3 path of the installer.sh installation bootstrap script that you copied earlier.
- MetricFilterPath – The S3 path of your Metricfilter.json definition that you copied earlier.
- MetricsLibraryPath – The S3 path of your CloudWatch emr-custom-cw-sink-0.0.1.jar library that you copied earlier.
- CloudWatchNamespace – The name of the custom CloudWatch namespace to be used.
- SparkDemoApplicationPath – The S3 path of your examplejob.sh script that you copied earlier.
- Subnet – The EC2 subnet where the cluster launches. You must provide this parameter.
- EC2KeyPairName – An optional EC2 key pair for connecting to cluster nodes, as an alternative to Session Manager.
View the metrics
After the CloudFormation stack deploys successfully, the example job starts automatically and takes approximately 15 minutes to complete. On the CloudWatch console, choose Dashboards in the navigation pane. Then filter the list by the prefix SparkMonitoring.
The example dashboard includes information on the cluster and an overview of the Spark jobs, stages, and tasks. Metrics are also available under a custom namespace starting with
Memory, CPU, I/O, and additional task distribution metrics are also included.
Finally, detailed Java garbage collection metrics are available per executor.
To avoid future charges in your account, delete the resources you created in this walkthrough. The EMR cluster will incur charges as long as the cluster is active, so stop it when you’re done. Complete the following steps:
- On the CloudFormation console, in the navigation pane, choose Stacks.
- Choose the stack you launched (
EMR-CloudWatch-Demo), then choose Delete.
- Empty the S3 bucket you created.
- Delete the S3 bucket you created.
Now that you have completed the steps in this walkthrough, the CloudWatch agent is running on your cluster hosts and configured to push Spark metrics to CloudWatch. With this feature, you can effectively monitor the health and performance of your Spark jobs running on Amazon EMR, detecting critical issues in real time and identifying root causes quickly.
You can package and deploy this solution through a CloudFormation template like this example template, which creates the IAM instance profile role, CloudWatch dashboard, and EMR cluster. The source code for the library is available on GitHub for customization.
To take this further, consider using these metrics in CloudWatch alarms. You could collect them with other alarms into a composite alarm or configure alarm actions such as sending Amazon Simple Notification Service (Amazon SNS) notifications to trigger event-driven processes such as AWS Lambda functions.
About the Author
Le Clue Lubbe is a Principal Engineer at AWS. He works with our largest enterprise customers to solve some of their most complex technical problems. He drives broad solutions through innovation to impact and improve the life of our customers.