This topic uses a code example to describe how to efficiently and securely mount and use Alibaba Cloud OSS as storage for distributed computing in MaxFrame. You can use the MaxFrame with_fs_mount decorator to perform an FS Mount, which provides stable and reliable access to external data for large-scale data processing.
Use cases
FS Mount is ideal for big data analytics in MaxFrame jobs that interact with persistent object storage such as OSS. For example, you can:
-
Load, clean, and process raw data from OSS.
-
Write intermediate results to OSS for downstream tasks to consume.
-
Share static resources, such as trained model files and configuration files.
Traditional read/write methods, such as pd.read_csv("oss://..."), are limited by SDK performance and network overhead, making them inefficient in a distributed environment. In contrast, with FS Mount, you can access OSS files in MaxCompute as if they were on a local disk, which significantly improves development efficiency.
Procedure
Activate services and grant permissions
-
Activate OSS and create a bucket.
-
Log in to the OSS console.
-
In the left-side navigation pane, click Buckets.
-
On the Buckets page, click Create Bucket.
In this example, the bucket name is
xxx-oss-test-sh.
-
-
Create a RAM role for MaxCompute and grant it access to the runtime environment.
-
Log in to the RAM console.
-
In the left navigation bar, select .
-
On the Roles page, click Create Role.
-
In the upper-right corner of the Create Role page, click Create Service Linked Role.
-
On the Create Role page, set Principal Type to Cloud Service.
-
For Principal Type, select MaxCompute.
-
On the Manage Permissions tab, click Create Authorization. In the Create Authorization panel that appears, select the policies to grant to the role, and click OK.
Select the following policies:
-
AliyunOSSFullAccess: Grants permissions to manage OSS.
-
AliyunMaxComputeFullAccess: Grants permissions to manage MaxCompute.
-
-
-
Use with_fs_mount to mount OSS
-
Recommended: Authenticate with a role ARN
from maxframe.udf import with_fs_mount @with_fs_mount( "oss://oss-cn-xxxx-internal.aliyuncs.com/xxx-oss-test-sh/test/", "/mnt/oss_data", storage_options={ "role_arn": "acs:ram::xxx:role/maxframe-oss" }, ) def _process(batch_df): import os if os.path.exists('/mnt/oss_data'): print(f"Mounted files: {os.listdir('/mnt/oss_data')}") else: print("/mnt/oss_data not mounted!") return batch_df * 2 -
Not recommended: Hard-code credentials
This method is for testing only and not recommended for production environments.
storage_options={ "access_key_id": "LTAI5t...", "access_key_secret": "Wp9H..." }ImportantAvoid hard-coding your AccessKey. You can use
role_arnto allow the system to automatically request a temporary STS token, preventing your AccessKey pair from being leaked.
Use with_running_options to control resource allocation
Use the with_running_options decorator to allocate appropriate CPU and memory resources for your task type:
from maxframe.udf import with_running_options
@with_running_options(engine="dpe", cpu=2, memory=16)
@with_fs_mount(...)
def _process(batch_df):
...
|
Parameter |
Recommended value |
Description |
|
|
Fixed |
FS Mount currently supports only the DPE engine. |
|
|
1–4 |
Increase this value for I/O-intensive or decompression-heavy tasks. |
|
|
Start with 8 GB |
For large file loads, 16 GB or more is recommended. |
Example
Recommended pattern: Process data in batches.
In large-scale data processing scenarios, you can use the MaxFrame apply_chunk feature to batch process input data.
Create a MaxFrame session
import os
from odps import ODPS
from maxframe import new_session
from maxframe.udf import with_fs_mount, with_running_options
# Initialize the ODPS client.
# We recommend setting the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET
# environment variables instead of hard-coding the AccessKey ID and AccessKey Secret strings.
o = ODPS(
os.getenv('ALIBABA_CLOUD_ACCESS_KEY_ID'),
os.getenv('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),
project='<your-project>',
endpoint='https://service.cn-<region>.maxcompute.aliyun.com/api',
)
# Set the runtime image.
# The `maxframe_service_dpe_runtime` image includes the required ossfs2 dependency.
# If you use a custom image, you must download the dependency and include it in your image.
# You can find the package at the link below this code block.
options.sql.settings = { "odps.session.image": "maxframe_service_dpe_runtime"}
# Start the session.
session = new_session(o)
print("LogView:", session.get_logview_address())
print("Session ID:", session.session_id)
@with_running_options(engine="dpe", cpu=2, memory=8)
@with_fs_mount(
"oss://oss-cn-<region>-internal.aliyuncs.com/wzy-oss-test-sh/test/",
"/mnt/oss_data",
storage_options={
"role_arn": "acs:ram::<uid>:role/maxframe-oss"
},
)
OSSFS dependency package: ossfs2_2.0.3.1_linux_x86_64.deb
Create a user-defined function (UDF)
def _process(batch_df):
import pandas as pd
import os
# Step 1: Check if the mount was successful.
mount_point = "/mnt/oss_data"
if not os.path.exists(mount_point):
raise RuntimeError("OSS mount failed!")
# Step 2: Load data, such as a mapping table or dictionary.
mapping_file = os.path.join(mount_point, "category_map.csv")
if os.path.isfile(mapping_file):
mapping_df = pd.read_csv(mapping_file)
# Step 3: Process the current chunk.
result = batch_df.copy()
result['F'] = result['A'] * 10
return result
Build a DataFrame and apply the UDF
import maxframe.dataframe as md
data = [[1.0, 2.0, 3.0, 4.0, 5.0], ...]
df = md.DataFrame(data, columns=['A', 'B', 'C', 'D', 'E'])
# Apply the UDF by using apply_chunk.
result_df = df.mf.apply_chunk(
_process,
skip_infer=True,
output_type="dataframe",
dtypes=df.dtypes,
index=df.index
)
# Execute the operation and fetch the result.
result = result_df.execute().fetch()
You can set skip_infer=True to skip type inference and improve execution speed. However, you must ensure that dtypes and index are passed correctly.
Troubleshooting
Verify the mount status
You can add debugging logs in the _process function:
import os
print("Mount path exists:", os.path.exists("/mnt/oss_data"))
print("Files in mount:", os.listdir("/mnt/oss_data") if os.path.exists("/mnt/oss_data") else [])
Check the LogView output to confirm that logs similar to the following are generated:
FS Mount successful! /mnt/oss_data: ['data.csv', 'config.json', 'model.pkl']
Processing batch with shape: (1000, 5)