An external volume is a distributed file system and data storage solution provided by MaxCompute. It functions as an object in MaxCompute that maps to a path in Object Storage Service (OSS). You can create an external volume to mount an OSS path and use the MaxCompute permission management system for fine-grained access control. You can also use MaxCompute compute engines to process files in the external volume. Each project can contain multiple external volumes. This topic describes how to use MaxCompute external volumes to process unstructured data.
Prerequisites
The external volume feature is enabled. For more information, see Apply for trial use of new features.
MaxCompute client v0.43.0 or later is installed. For more information, see Connect using the local client (odpscmd).
If you use an SDK, the Java SDK must be v0.43.0 or later. For more information, see Release notes.
Activate OSS, create a bucket, and grant your MaxCompute project permissions to access OSS. For more information, see STS mode authorization.
NoteData in an external volume is stored in OSS. MaxCompute does not charge separate storage fees for data in an external volume. You are charged computing fees when you use MaxCompute compute engines, such as Spark on MaxCompute and MapReduce jobs, to read and process data in an external volume. The results generated by MaxCompute compute engines, such as index data created by Proxima CE, are also stored in the external volume, and OSS charges for this storage.
Quick start
Grant permissions.
NoteTo use an external volume, you need the following permissions: CreateInstance, CreateVolume, List, Read, and Write. For more information, see MaxCompute permissions.
Run the following command to check whether the current user has the
CreateVolumepermission.SHOW grants FOR <user_name>;If the user does not have the CreateVolume permission, run the following command to grant it.
GRANT CreateVolume ON project <project_name> TO USER <user_name>;To revoke the permission, run the following command.
REVOKE CreateVolume ON project <project_name> FROM USER <user_name>;Run the
SHOW GRANTScommand again to confirm that the user has theCreateVolumepermission.
Create an external volume.
Run the following command to create an external volume.
vfs -create <volume_name> -storage_provider oss -url <oss://oss_endpoint/bucket_name/directory_name> [-acd <true|false>] -role_arn <arn:aliyun:xxx/aliyunodpsdefaultrole>For parameter descriptions and more operations, see External volume operations.
After you create an external volume, its path in MaxCompute is
odps://[project_name]/[volume_name]. In this path, project_name is the name of your MaxCompute project and volume_name is the name of the external volume. Compute engines such as Spark and MapReduce jobs can use this path.View the created external volumes.
Run the following command to view the created external volumes.
vfs -ls /;
Use cases
Use Spark on MaxCompute with external volumes
Spark on MaxCompute is a computing service provided by MaxCompute that is compatible with open source Spark. It provides a Spark computing framework on top of a unified system for computing resources, datasets, and permissions. This allows you to submit and run Spark jobs using familiar development methods to meet a wide range of data processing and analysis needs. If you require fine-grained permission control, use an external volume to manage access through the data warehouse's permission system. For more information, see Access OSS from Spark on MaxCompute.
Reference resources from an external volume
When a Spark job starts, you can directly reference resources from an external volume. These resources, specified using parameters, are automatically downloaded to the working directory.
File: A file can be of any type, such as
jarorpy.Archive: A compressed file in one of the following formats:
zip,tar.gz, ortar.
The difference is that a file is downloaded directly to the job's current working directory. An archive is downloaded and then automatically extracted in the current working directory. Use the following two parameters to enable your Spark program to process data in the external volume:
Configure the following parameters in the Parameters section of an ODPS Spark node in DataWorks or in the spark-defaults.conf file. Do not configure them in the code.
Parameter | Description |
spark.hadoop.odps.cupid.volume.files | Specifies the file resources required for the job. Separate multiple files with commas. These files are downloaded to the Spark job's working directory.
|
spark.hadoop.odps.cupid.volume.archives | Specifies the archive files required for the job. Separate multiple archive files with commas. The files are downloaded to the current working directory of the Spark job and extracted.
|
Process OSS resources in an external volume
To access resources in an external volume from your code during job execution, configure the following parameters in your Spark job.
Parameter | Description |
spark.hadoop.odps.volume.common.filesystem | Enables Spark on MaxCompute to recognize an external volume. Set the value to The default value is |
spark.hadoop.odps.cupid.volume.paths | Specifies the path of the external volume to access.
|
spark.hadoop.fs.odps.impl | The implementation class for Spark on MaxCompute to access OSS. The value is fixed: |
spark.hadoop.fs.AbstractFileSystem.odps.impl | The implementation class for Spark on MaxCompute to access OSS. The value is fixed: |
Example code: This example uses the K-means algorithm to generate a model from training data (odps://ms_proj1_dev/volume_yyy1/kmeans_data.txt) and saves it to the odps://ms_proj1_dev/volume_yyy1/target/PythonKMeansExample/KMeansModel path. It then uses the model to classify target data and stores the results in the odps://ms_proj1_dev/volume_yyy1/target/PythonKMeansExample/KMeansModel/data path.
-- Configurations
spark.hadoop.odps.cupid.volume.paths=odps://ms_proj1_dev/volume_yyy1/
spark.hadoop.odps.volume.common.filesystem=true
spark.hadoop.fs.odps.impl=org.apache.hadoop.fs.aliyun.volume.OdpsVolumeFileSystem
spark.hadoop.fs.AbstractFileSystem.odps.impl=org.apache.hadoop.fs.aliyun.volume.abstractfsimpl.OdpsVolumeFs
spark.hadoop.odps.access.id=xxxxxxxxx
spark.hadoop.odps.access.key=xxxxxxxxx
spark.hadoop.fs.oss.endpoint=oss-cn-beijing-internal.aliyuncs.com
spark.hadoop.odps.cupid.resources=ms_proj1_dev.jindofs-sdk-3.8.0.jar
spark.hadoop.fs.oss.impl=com.aliyun.emr.fs.oss.JindoOssFileSystem
spark.hadoop.odps.cupid.resources=public.python-2.7.13-ucs4.tar.gz
spark.pyspark.python=./public.python-2.7.13-ucs4.tar.gz/python-2.7.13-ucs4/bin/python
spark.hadoop.odps.spark.version=spark-2.4.5-odps0.34.0
-- Code
from numpy import array
from math import sqrt
from pyspark import SparkContext
from pyspark.mllib.clustering import KMeans, KMeansModel
if __name__ == "__main__":
sc = SparkContext(appName="KMeansExample") # SparkContext
# Load and parse the data
data = sc.textFile("odps://ms_proj1_dev/volume_yyy1/kmeans_data.txt")
parsedData = data.map(lambda line: array([float(x) for x in line.split(' ')]))
# Build the model (cluster the data)
clusters = KMeans.train(parsedData, 2, maxIterations=10, initializationMode="random")
# Evaluate clustering by computing Within Set Sum of Squared Errors
def error(point):
center = clusters.centers[clusters.predict(point)]
return sqrt(sum([x**2 for x in (point - center)]))
WSSSE = parsedData.map(lambda point: error(point)).reduce(lambda x, y: x + y)
print("Within Set Sum of Squared Error = " + str(WSSSE))
# Save and load model
clusters.save(sc, "odps://ms_proj1_dev/volume_yyy1/target/PythonKMeansExample/KMeansModel")
print(parsedData.map(lambda feature: clusters.predict(feature)).collect())
sameModel = KMeansModel.load(sc, "odps://ms_proj1_dev/volume_yyy1/target/PythonKMeansExample/KMeansModel")
print(parsedData.map(lambda feature: sameModel.predict(feature)).collect())
sc.stop()After execution, you can view the result data in the OSS directory mapped to the external volume.
Use Proxima CE for vector computing
This section provides instructions and an example of how to use Proxima CE for vectorization in MaxCompute.
Install the Proxima CE resource package.
For more information, see Installation and execution.
Run a job.
Limitations:
The Proxima SDK for Java currently only supports running task commands on a MaxCompute client that runs on Linux or macOS.
NoteProxima CE jobs consist of two parts: local tasks and MaxCompute tasks. Local tasks are functional modules that do not involve MaxCompute SQL, MapReduce, or Graph jobs. MaxCompute tasks are jobs executed by MaxCompute engines such as SQL, MapReduce, and Graph. These two types of tasks are executed alternately. When a Proxima CE job starts, it first attempts to load the Proxima kernel on the local machine where the job is run by using the MaxCompute client. If the kernel loads successfully, certain modules run locally and call functions based on the Proxima kernel. If the kernel fails to load, an error is reported, but subsequent operations are not affected, and the modules call fallback functions instead. Because the job's JAR package contains Linux-related dependencies, it cannot be run on a MaxCompute client in a Windows operating system.
Running jobs from DataWorks MapReduce nodes is not currently supported. The underlying MaxCompute client version integrated into the MapReduce node is being upgraded, which causes jobs to fail. For now, submit jobs using the MaxCompute client.
Prepare data:
-- Create input tables. CREATE TABLE doc_table_float_smoke(pk STRING, vector STRING) PARTITIONED BY (pt STRING); CREATE TABLE query_table_float_smoke(pk STRING, vector STRING) PARTITIONED BY (pt STRING); -- Insert data into the doc table (base table). ALTER TABLE doc_table_float_smoke add PARTITION(pt='20230116'); INSERT OVERWRITE TABLE doc_table_float_smoke PARTITION (pt='20230116') VALUES ('1.nid','1~1~1~1~1~1~1~1'), ('2.nid','2~2~2~2~2~2~2~2'), ('3.nid','3~3~3~3~3~3~3~3'), ('4.nid','4~4~4~4~4~4~4~4'), ('5.nid','5~5~5~5~5~5~5~5'), ('6.nid','6~6~6~6~6~6~6~6'), ('7.nid','7~7~7~7~7~7~7~7'), ('8.nid','8~8~8~8~8~8~8~8'), ('9.nid','9~9~9~9~9~9~9~9'), ('10.nid','10~10~10~10~10~10~10~10'); -- Insert data into the query table. ALTER TABLE query_table_float_smoke add PARTITION(pt='20230116'); INSERT OVERWRITE TABLE query_table_float_smoke PARTITION (pt='20230116') VALUES ('q1.nid','1~1~1~1~2~2~2~2'), ('q2.nid','4~4~4~4~3~3~3~3'), ('q3.nid','9~9~9~9~5~5~5~5');Sample job code:
jar -libjars proxima-ce-aliyun-1.0.0.jar -classpath proxima-ce-aliyun-1.0.0.jar com.alibaba.proxima2.ce.ProximaCERunner -doc_table doc_table_float_smoke -doc_table_partition 20230116 -query_table query_table_float_smoke -query_table_partition 20230116 -output_table output_table_float_smoke -output_table_partition 20230116 -data_type float -dimension 8 -topk 1 -job_mode train:build:seek:recall -external_volume shanghai_vol_ceshi -owner_id 1248953xxx ;Sample result: Run the
select * from output_table_float_smoke where pt='20230116';command to query the result table.+------------+------------+------------+------------+ | pk | knn_result | score | pt | +------------+------------+------------+------------+ | q1.nid | 2.nid | 4.0 | 20230116 | | q1.nid | 1.nid | 4.0 | 20230116 | | q1.nid | 3.nid | 20.0 | 20230116 | | q2.nid | 4.nid | 4.0 | 20230116 | | q2.nid | 3.nid | 4.0 | 20230116 | | q2.nid | 2.nid | 20.0 | 20230116 | | q3.nid | 7.nid | 32.0 | 20230116 | | q3.nid | 8.nid | 40.0 | 20230116 | | q3.nid | 6.nid | 40.0 | 20230116 | +------------+------------+------------+------------+