Offline Spark consumption example
Use Spark to read Simple Log Service (SLS) data in batch (offline) mode—as a bounded dataset with a defined start and end time—rather than as a continuous stream. EMR supports two approaches: Spark RDD and Spark SQL.
Prerequisites
Before you begin, ensure that you have:
-
An EMR cluster with Spark installed
-
A Simple Log Service project and Logstore containing the data to read
-
An AccessKey ID and AccessKey secret for a RAM user with read access to the Logstore
-
(Spark SQL only) Access to the EMR cluster node where the JAR files are located
Use Spark RDD to read from Simple Log Service
Sample code
The following Scala program reads log data from a Logstore for a specified time range and saves the output to a file system path.
// TestBatchLoghub.scala
object TestBatchLoghub {
def main(args: Array[String]): Unit = {
if (args.length < 6) {
System.err.println(
"""Usage: TestBatchLoghub <sls project> <sls logstore> <sls endpoint>
| <access key id> <access key secret> <output path> <start time> <end time=now>
""".stripMargin)
System.exit(1)
}
val loghubProject = args(0)
val logStore = args(1)
val endpoint = args(2)
val accessKeyId = args(3) // Read from environment variable at submit time
val accessKeySecret = args(4) // Read from environment variable at submit time
val outputPath = args(5)
val startTime = args(6).toLong
val sc = new SparkContext(new SparkConf().setAppName("test batch loghub"))
var rdd: JavaRDD[String] = null
if (args.length > 7) {
// Read log data between startTime and endTime
rdd = LoghubUtils.createRDD(sc, loghubProject, logStore, accessKeyId, accessKeySecret, endpoint, startTime, args(7).toLong)
} else {
// Read log data from startTime to now
rdd = LoghubUtils.createRDD(sc, loghubProject, logStore, accessKeyId, accessKeySecret, endpoint, startTime)
}
rdd.saveAsTextFile(outputPath)
}
}
LoghubUtils.createRDD() returns a JavaRDD[String] where each element is a log entry. Pass seven arguments to read up to the current time, or eight arguments to specify an explicit end time.
For the Maven POM configuration, see aliyun-emapreduce-demo.
Connection parameters
| Parameter | Description | Example |
|---|---|---|
<sls project> |
SLS project name | my-project |
<sls logstore> |
Logstore name within the project | my-logstore |
<sls endpoint> |
SLS endpoint for your region | cn-hangzhou.log.aliyuncs.com |
<access key id> |
AccessKey ID of your RAM user | Use $ALIBABA_CLOUD_ACCESS_KEY_ID |
<access key secret> |
AccessKey secret of your RAM user | Use $ALIBABA_CLOUD_ACCESS_KEY_SECRET |
<output path> |
Output path for the RDD result | oss://my-bucket/output/ |
<start time> |
Start of the time range | 1700000000 |
<end time> |
(Optional) End of the time range. Defaults to current time. | 1700003600 |
Compile and run
Step 1: Compile the code.
mvn clean package -DskipTests
The compiled JAR is saved to the target/shaded/ directory.
Step 2: Submit the job.
Use a RAM user's AccessKey pair rather than your Alibaba Cloud account's AccessKey pair. An account-level AccessKey pair grants access to all API operations. For how to create a RAM user, see Create a RAM user. Store credentials as environment variables—do not hardcode them in your scripts.
Set the environment variables before submitting:
export ALIBABA_CLOUD_ACCESS_KEY_ID=<access_key_id>
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<access_key_secret>
Then submit the job:
spark-submit \
--master yarn-cluster \
--executor-cores 2 \
--executor-memory 1g \
--driver-memory 1g \
--num-executors 2 \
--class x.x.x.TestBatchLoghub xxx.jar \
<sls project> <sls logstore> <sls endpoint> \
$ALIBABA_CLOUD_ACCESS_KEY_ID $ALIBABA_CLOUD_ACCESS_KEY_SECRET \
<output path> <start time> [<end time>]
Replace x.x.x.TestBatchLoghub with the actual fully qualified class name and xxx.jar with the actual JAR path. Adjust --executor-cores, --executor-memory, and --num-executors based on your data volume and cluster capacity.
Use Spark SQL to read from Simple Log Service
Spark SQL uses the loghub data source, which is included in the EMR Spark extension JAR.
Launch spark-sql with the LogHub JAR
Use a RAM user's AccessKey pair rather than your Alibaba Cloud account's AccessKey pair. Store credentials as environment variables passed via --hiveconf—do not hardcode them in your scripts.
spark-sql \
--jars /opt/apps/SPARK-EXTENSION/spark-extension-current/spark3-emrsdk/* \
--hiveconf accessKeyId=$ALIBABA_CLOUD_ACCESS_KEY_ID \
--hiveconf accessKeySecret=$ALIBABA_CLOUD_ACCESS_KEY_SECRET
If your EMR cluster uses Spark 2, replace spark3 with spark2 in the JAR path:
/opt/apps/SPARK-EXTENSION/spark-extension-current/spark2-emrsdk/*
Create a table and query data
CREATE TABLE test_sls
USING loghub
OPTIONS (
endpoint = 'cn-hangzhou-intranet.log.aliyuncs.com',
access.key.id = '${hiveconf:accessKeyId}',
access.key.secret= '${hiveconf:accessKeySecret}',
sls.project = 'test_project',
sls.store = 'test_store',
startingoffsets = 'earliest'
);
SELECT * FROM test_sls;
Connection parameters
| Parameter | Required | Description | Example |
|---|---|---|---|
endpoint |
Yes | SLS endpoint for your region | cn-hangzhou-intranet.log.aliyuncs.com |
access.key.id |
Yes | AccessKey ID, passed via --hiveconf |
${hiveconf:accessKeyId} |
access.key.secret |
Yes | AccessKey secret, passed via --hiveconf |
${hiveconf:accessKeySecret} |
sls.project |
Yes | SLS project name | test_project |
sls.store |
Yes | Logstore name | test_store |
startingoffsets |
No | Starting read position. Use earliest to read all available data from the beginning of the Logstore. |
earliest |
Use the LogHub JAR in an on-premises development environment
To develop and test locally against Spark 3 (the steps are the same for Spark 2), install the EMR data source JAR to your local Maven repository.
Step 1: Download the JAR from your EMR cluster.
Copy the JAR from the following path on your cluster node to your local machine:
/opt/apps/SPARK-EXTENSION/spark-extension-current/spark3-emrsdk/emr-datasources_shaded_2.12
Step 2: Install the JAR to your local Maven repository.
mvn install:install-file \
-DgroupId=com.aliyun.emr \
-DartifactId=emr-datasources_shaded_2.12 \
-Dversion=3.0.2 \
-Dpackaging=jar \
-Dfile=<path-to-downloaded-jar>
Replace <path-to-downloaded-jar> with the local path where you saved the JAR.
Step 3: Add the dependency to your pom.xml.
<dependency>
<groupId>com.aliyun.emr</groupId>
<artifactId>emr-datasources_shaded_2.12</artifactId>
<version>3.0.2</version>
</dependency>
References
For more information about how to use Spark to access Kafka, see Structured Streaming + Kafka Integration Guide.