Organizations constantly work to process and analyze vast volumes of data to derive actionable insights. Effective data ingestion and search capabilities have become essential for use cases like log analytics, application search, and enterprise search. These use cases demand a robust pipeline that can handle high data volumes and enable efficient data exploration.
Apache Spark, an open source powerhouse for large-scale data processing, is widely recognized for its speed, scalability, and ease of use. Its ability to process and transform massive datasets has made it an indispensable tool in modern data engineering. Amazon OpenSearch Service—a community-driven search and analytics solution—empowers organizations to search, aggregate, visualize, and analyze data seamlessly. Together, Spark and OpenSearch Service offer a compelling solution for building powerful data pipelines. However, ingesting data from Spark into OpenSearch Service can present challenges, especially with diverse data sources.
This post showcases how to use Spark on AWS Glue to seamlessly ingest data into OpenSearch Service. We cover batch ingestion methods, share practical examples, and discuss best practices to help you build optimized and scalable data pipelines on AWS.
Overview of solution
AWS Glue is a serverless data integration service that simplifies data preparation and integration tasks for analytics, machine learning, and application development. In this post, we focus on batch data ingestion into OpenSearch Service using Spark on AWS Glue.
AWS Glue offers multiple integration options with OpenSearch Service using various open source and AWS managed libraries, including:
In the following sections, we explore each integration method in detail, guiding you through the setup and implementation. As we progress, we incrementally build the architecture diagram shown in the following figure, providing a clear path for creating robust data pipelines on AWS. Each implementation is independent of the others. We chose to showcase them separately, because in a real-world scenario, only one of the three integration methods is likely to be used.
You can find the code base in the accompanying GitHub repo. In the following sections, we walk through the steps to implement the solution.
Prerequisites
Before you deploy this solution, make sure the following prerequisites are in place:
Clone the repository to your local machine
Clone the repository to your local machine and set the BLOG_DIR
environment variable. All the relative paths assume BLOG_DIR
is set to the repository location in your machine. If BLOG_DIR
is not being used, adjust the path accordingly.
Deploy the AWS CloudFormation template to create the necessary infrastructure
The main focus of this post is to demonstrate how to use the mentioned libraries in Spark on AWS Glue to ingest data into OpenSearch Service. Though we center on this core topic, several key AWS components will need to be pre-provisioned for the integration examples, such as a Amazon Virtual Private Cloud (Amazon VPC), multiple Subnets, an AWS Key Management Service (AWS KMS) key, an Amazon Simple Storage Service (Amazon S3) bucket, an AWS Glue role, and an OpenSearch Service cluster with domains for OpenSearch Service and Elasticsearch. To simplify the setup, we’ve automated the provisioning of this core infrastructure using the cloudformation/opensearch-glue-infrastructure.yaml
AWS CloudFormation template.
- Run the following commands
The CloudFormation template will deploy the necessary networking components (such as VPC and subnets), Amazon CloudWatch logging, AWS Glue role, and OpenSearch Service and Elasticsearch domains required to implement the proposed architecture. Use a strong password (8–128 characters, three of which are lowercase, uppercase, numbers, or special characters, and no /, “, or spaces) and adhere to your organization’s security standards for ESMasterUserPassword
and OSMasterUserPassword
in the following command:
You should see a success message such as "Successfully created/updated stack – GlueOpenSearchStack"
after the resources have been provisioned successfully. Provisioning this CloudFormation stack typically takes approximately 30 minutes to complete.
- On the AWS CloudFormation console, locate the
GlueOpenSearchStack
stack, and confirm that its status is CREATE_COMPLETE.
You can review the deployed resources on the Resources tab, as shown in the following screenshot.The screenshot does not display all the created resources.
Additional setup steps
In this section, we collect essential information, including the S3 bucket name and the OpenSearch Service and Elasticsearch domain endpoints. These details are required for executing the code in subsequent sections.
Capture the details of the provisioned resources
Use the following AWS CLI command to extract and save the output values from the CloudFormation stack to a file named GlueOpenSearchStack_outputs.txt
. We refer to the values in this file in upcoming steps.
Download NY Green Taxi December 2022 dataset and copy to S3 bucket
The purpose of this post is to demonstrate the technical implementation of ingesting data into OpenSearch Service using AWS Glue. Understanding the dataset itself is not essential, aside from its data format, which we discuss in AWS Glue notebooks in later sections. To learn more about the dataset, you can find additional information on the NYC Taxi and Limousine Commission website.
We specifically request that you download the December 2022 dataset, because we have tested the solution using this particular dataset:
Download the required JARs from the Maven repository and copy to S3 bucket
We’ve specified a particular JAR file version to ensure stable deployment experience. However, we recommend adhering to your organization’s security best practices and reviewing any known vulnerabilities in the version of the JAR files before deployment. AWS does not guarantee the security of any open-source code used here. Additionally, please verify the downloaded JAR file’s checksum against the published value to confirm its integrity and authenticity.
In the following sections, we implement the individual data ingestion methods as outlined in the architecture diagram.
Ingest data into OpenSearch Service using the OpenSearch Spark library
In this section, we load an OpenSearch Service index using Spark and the OpenSearch Spark library. We demonstrate this implementation by using AWS Glue notebooks, employing basic authentication using user name and password.
To demonstrate the ingestion mechanisms, we have provided the Spark-and-OpenSearch-Code-Steps.ipynb
notebook with detailed instructions. Follow the steps in this section in conjunction with the instructions in the notebook.
Set up the AWS Glue Studio notebook
Complete the following steps:
- On the AWS Glue console, choose ETL jobs in the navigation pane.
- Under Create job, choose Notebook.
- Upload the notebook file located at
${BLOG_DIR}/glue_jobs/Spark-and-OpenSearch-Code-Steps.ipynb
. - For IAM role, choose the AWS Glue job IAM role that begins with
GlueOpenSearchStack-GlueRole-*
.
- Enter a name for the notebook (for example,
Spark-and-OpenSearch-Code-Steps
) and choose Save.
Replace the placeholder values in the notebook
Complete the following steps to update the placeholders in the notebook:
- In Step 1 in the notebook, replace the placeholder
with the AWS Glue interactive session connection name. You can get the name of the interactive session by executing the following command:
- In Step 1 in the notebook, replace the placeholder
and populate the variable s3_bucket
with the bucket name. You can get the name of the S3 bucket by executing the following command:
- In Step 4 in the notebook, replace
with the OpenSearch Service domain name. You can get the domain name by executing the following command:
Run the notebook
Run each cell of the notebook to load data into the OpenSearch Service domain and read it back to verify the successful load. Refer to the detailed instructions within the notebook for execution-specific guidance.
Spark write modes (append vs. overwrite)
It is recommended to write data incrementally into OpenSearch Service indexes using the append
mode, as demonstrated in Step 8 in the notebook. However, in certain cases, you may need to refresh the entire dataset in the OpenSearch Service index. In these scenarios, you can use the overwrite
mode, though it is not advised for large indexes. When using overwrite
mode, the Spark library deletes rows from the OpenSearch Service index one by one and then rewrites the data, which can be inefficient for large datasets. To avoid this, you can implement a preprocessing step in Spark to identify insertions and updates, and then write the data into OpenSearch Service using append
mode.
Ingest data into Elasticsearch using the Elasticsearch Hadoop library
In this section, we load an Elasticsearch index using Spark and the Elasticsearch Hadoop Library. We demonstrate this implementation by using AWS Glue as the engine for Spark.
Set up the AWS Glue Studio notebook
Complete the following steps to set up the notebook:
- On the AWS Glue console, choose ETL jobs in the navigation pane.
- Under Create job, choose Notebook.
- Upload the notebook file located at
${BLOG_DIR}/glue_jobs/Spark-and-Elasticsearch-Code-Steps.ipynb
. - For IAM role, choose the AWS Glue job IAM role that begins with
GlueOpenSearchStack-GlueRole-*
.
- Enter a name for the notebook (for example,
Spark-and-ElasticSearch-Code-Steps
) and choose Save.
Replace the placeholder values in the notebook
Complete the following steps:
- In Step 1 in the notebook, replace the placeholder
with the AWS Glue interactive session connection name. You can get the name of the interactive session by executing the following command:
- In Step 1 in the notebook, replace the placeholder
and populate the variable s3_bucket
with the bucket name. You can get the name of the S3 bucket by executing the following command:
- In Step 4 in the notebook, replace
with the Elasticsearch domain name. You can get the domain name by executing the following command:
Run the notebook
Run each cell in the notebook to load data to the Elasticsearch domain and read it back to verify the successful load. Refer to the detailed instructions within the notebook for execution-specific guidance.
Ingest data into OpenSearch Service using the AWS Glue OpenSearch Service connection
In this section, we load an OpenSearch Service index using Spark and the AWS Glue OpenSearch Service connection.
Create the AWS Glue job
Complete the following steps to create an AWS Glue Visual ETL job:
- On the AWS Glue console, choose ETL jobs in the navigation pane.
- Under Create job, choose Visual ETL
This will open the AWS Glue job visual editor.
- Choose the plus sign, and under Sources, choose Amazon S3.
- In the visual editor, choose the Data Source – S3 bucket node.
- In the Data source properties – S3 pane, configure the data source as follows:
-
- For S3 source type, select S3 location.
- For S3 URL, choose Browse S3, and choose the
green_tripdata_2022-12.parquet
file from the designated S3 bucket. - For Data format, choose Parquet.
- Choose Infer schema to let AWS Glue detect the schema of the data.
This will set up your data source from the specified S3 bucket.
- Choose the plus sign again to add a new node.
- For Transforms, choose Drop Fields to include this transformation step.
This will allow you to remove any unnecessary fields from your dataset before loading it into OpenSearch Service.
- Choose the Drop Fields transform node, then select the following fields to drop from the dataset:
-
payment_type
trip_type
congestion_surcharge
This will remove these fields from the data before it is loaded into OpenSearch Service.
- Choose the plus sign again to add a new node.
- For Targets, choose Amazon OpenSearch Service.
This will configure OpenSearch Service as the destination for the data being processed.
- Choose the Data target – Amazon OpenSearch Service node and configure it as follows:
-
- For Amazon OpenSearch Service connection, choose the connection
GlueOpenSearchServiceConnec-*
from the drop down. - For Index, enter
green_taxi
. Thegreen_taxi
index was created earlier in the “Ingest data into OpenSearch Service using the OpenSearch Spark library” section.
- For Amazon OpenSearch Service connection, choose the connection
This configures the OpenSearch Service to write the processed data to the specified index.
- On the Job details tab, update the job details as follows:
-
- For Name, enter a name (for example,
Spark-and-Glue-OpenSearch-Connection
). - For Description, enter an optional description (for example,
AWS Glue job using Glue OpenSearch Connection to load data into Amazon OpenSearch Service
). - For IAM role, choose the role starting with
GlueOpenSearchStack-GlueRole-*
. - For the Glue version, choose
Glue 4.0 – Supports spark 3.3, Scala 2, Python 3
- Leave the rest of the fields as default.
- Choose Save to save the changes.
- For Name, enter a name (for example,
- To run the AWS Glue job Spark-and-Glue-OpenSearch-Connector, choose Run.
This will initiate the job execution.
- Choose the Runs tab and wait for the AWS Glue job to complete successfully.
You will see the status change to Succeeded when the job is complete.
Clean up
To clean up your resources, complete the following steps:
- Delete the CloudFormation stack:
- Delete the AWS Glue jobs:
-
- On the AWS Glue console, under ETL jobs in the navigation pane, choose Visual ETL.
- Select the jobs you created (
Spark-and-Glue-OpenSearch-Connector
,Spark-and-ElasticSearch-Code-Steps
, andSpark-and-OpenSearch-Code-Steps
) and on the Actions menu, choose Delete.
Conclusion
In this post, we explored several ways to ingest data into OpenSearch Service using Spark on AWS Glue. We demonstrated the use of three key libraries: the AWS Glue OpenSearch Service connection, the OpenSearch Spark Library, and the Elasticsearch Hadoop Library. The methods outlined in this post can help you streamline your data ingestion into OpenSearch Service.
If you’re interested in learning more and getting hands-on experience, we’ve created a workshop that walks you through the entire process in detail. You can explore the full setup for ingesting data into OpenSearch Service, handling both batch and real-time streams, and building dashboards. Check out the workshop Unified Real-Time Data Processing and Analytics Using Amazon OpenSearch and Apache Spark to deepen your understanding and apply these techniques step by step.
About the Authors
Ravikiran Rao is a Data Architect at Amazon Web Services and is passionate about solving complex data challenges for various customers. Outside of work, he is a theater enthusiast and amateur tennis player.
Vishwa Gupta is a Senior Data Architect with the AWS Professional Services Analytics Practice. He helps customers implement big data and analytics solutions. Outside of work, he enjoys spending time with family, traveling, and trying new food.
Suvojit Dasgupta is a Principal Data Architect at Amazon Web Services. He leads a team of skilled engineers in designing and building scalable data solutions for AWS customers. He specializes in developing and implementing innovative data architectures to address complex business challenges.