Process data
Create the ods_user_info_d_spark and ods_raw_log_d_spark external tables to access user and log data in a private Object Storage Service (OSS) bucket, and then use EMR Spark SQL nodes in DataWorks to process the data and generate user profiles.
Prerequisite
First, complete the steps described in Synchronize data.
Step 1: Build a data processing workflow
After the data is loaded in the Synchronize data stage, the next step is to process it into user profile data.
-
In the Data Studio left-side navigation pane, click the
icon. In the Project Directory section, find and click the User_profile_analysis_Sparkworkflow you created to open its canvas. -
From the component list on the left, drag EMR Spark SQL nodes onto the canvas and name them as described below.
This tutorial uses the following nodes:
Node type
Node name
Description
EMR Spark SQLdwd_log_info_di_sparkProcesses data from the
ods_raw_log_d_sparktable using Spark SQL and writes the result to thedwd_log_info_di_sparktable.
EMR Spark SQLdws_user_info_all_di_sparkJoins the detail log table
dwd_log_info_di_sparkand the user tableods_user_info_d_sparkon the uid column to generate an aggregated user log table.Aggregates data from the user information table (
ods_user_info_d_spark) and the processed log data table (dwd_log_info_di_spark), and writes the result to thedws_user_info_all_di_sparktable.
EMR Spark SQLads_user_info_1d_sparkFurther processes data from the
dws_user_info_all_di_sparktable and writes the result to theads_user_info_1d_sparktable to generate basic user profiles. -
Manually drag to connect the nodes and configure the upstream node for each node. The final result is as follows:
NoteYou can set upstream and downstream dependencies between nodes by manually connecting them in the workflow, or use code parsing to automatically identify node dependencies within internal nodes. This tutorial uses the manual connection method. For more information about code parsing, see Automatic parsing mechanism.
Step 2: Configure data processing nodes
Use EMR Spark SQL nodes to process the user information table and the detail log table, and generate the user profile table ads_user_info_1d_spark.
Configure the dwd_log_info_di_spark node
This node uses Spark functions to process columns from the ods_raw_log_d_spark table and writes the result to the dwd_log_info_di_spark table.
-
On the workflow canvas, hover over the
dwd_log_info_di_sparknode and click Open Node. -
Paste the following code into the SQL editor.
Paimon table (DLF)
-- Scenario: The following Spark SQL splits the data loaded into Spark from the ods_raw_log_d_spark table by "##@@" to generate multiple columns, and writes the result to the new table dwd_log_info_di_spark. CREATE TABLE IF NOT EXISTS dwd_log_info_di_spark ( ip STRING COMMENT 'IP address', uid STRING COMMENT 'User ID', tm STRING COMMENT 'Time yyyymmddhh:mi:ss', status STRING COMMENT 'Server response status code', bytes STRING COMMENT 'Bytes returned to client', method STRING COMMENT 'Request method', url STRING COMMENT 'URL', protocol STRING COMMENT 'Protocol', referer STRING, device STRING, identity STRING, dt STRING COMMENT 'Partition column' -- Best practice: include the partition key as a table column ) PARTITIONED BY (dt) TBLPROPERTIES ( 'format' = 'paimon' -- Core: declare as a Paimon table ); INSERT OVERWRITE TABLE dwd_log_info_di_spark PARTITION (dt = '${bizdate}') SELECT ip, uid, tm, status, bytes, regexp_extract(request, '(^[^ ]+) .*', 1) AS method, regexp_extract(request, '^[^ ]+ (.*) [^ ]+$', 1) AS url, regexp_extract(request, '.* ([^ ]+$)', 1) AS protocol, regexp_extract(referer, '^[^/]+://([^/]+){1}', 1) AS referer, CASE WHEN lower(agent) RLIKE 'android' THEN 'android' WHEN lower(agent) RLIKE 'iphone' THEN 'iphone' WHEN lower(agent) RLIKE 'ipad' THEN 'ipad' WHEN lower(agent) RLIKE 'macintosh' THEN 'macintosh' WHEN lower(agent) RLIKE 'windows phone' THEN 'windows_phone' WHEN lower(agent) RLIKE 'windows' THEN 'windows_pc' ELSE 'unknown' END AS device, CASE WHEN lower(agent) RLIKE '(bot|spider|crawler|slurp)' THEN 'crawler' WHEN lower(agent) RLIKE 'feed' OR regexp_extract(request, '^[^ ]+ (.*) [^ ]+$', 1) RLIKE 'feed' THEN 'feed' WHEN lower(agent) NOT RLIKE '(bot|spider|crawler|feed|slurp)' AND agent RLIKE '^(Mozilla|Opera)' AND regexp_extract(request, '^[^ ]+ (.*) [^ ]+$', 1) NOT RLIKE 'feed' THEN 'user' ELSE 'unknown' END AS identity FROM ( SELECT SPLIT(col, '##@@')[0] AS ip, SPLIT(col, '##@@')[1] AS uid, SPLIT(col, '##@@')[2] AS tm, SPLIT(col, '##@@')[3] AS request, SPLIT(col, '##@@')[4] AS status, SPLIT(col, '##@@')[5] AS bytes, SPLIT(col, '##@@')[6] AS referer, SPLIT(col, '##@@')[7] AS agent FROM ods_raw_log_d_spark WHERE dt = '${bizdate}' ) a;Hive table (DLF-Legacy)
-- Scenario: The following Spark SQL splits the data loaded into Spark from the ods_raw_log_d_spark table by "##@@" to generate multiple columns, and writes the result to the new table dwd_log_info_di_spark. CREATE TABLE IF NOT EXISTS dwd_log_info_di_spark ( ip STRING COMMENT 'IP address', uid STRING COMMENT 'User ID', tm STRING COMMENT 'Time yyyymmddhh:mi:ss', status STRING COMMENT 'Server response status code', bytes STRING COMMENT 'Bytes returned to client', method STRING COMMENT 'Request method', url STRING COMMENT 'URL', protocol STRING COMMENT 'Protocol', referer STRING, device STRING, identity STRING ) PARTITIONED BY (dt STRING) LOCATION 'oss://dw-spark-demo.oss-cn-shanghai-internal.aliyuncs.com/dwd_log_info_di_spark/log_${bizdate}/'; ALTER TABLE dwd_log_info_di_spark ADD IF NOT EXISTS PARTITION (dt = '${bizdate}'); INSERT OVERWRITE TABLE dwd_log_info_di_spark PARTITION (dt = '${bizdate}') SELECT ip, uid, tm, status, bytes, regexp_extract(request, '(^[^ ]+) .*', 1) AS method, regexp_extract(request, '^[^ ]+ (.*) [^ ]+$', 1) AS url, regexp_extract(request, '.* ([^ ]+$)', 1) AS protocol, regexp_extract(referer, '^[^/]+://([^/]+){1}', 1) AS referer, CASE WHEN lower(agent) RLIKE 'android' THEN 'android' WHEN lower(agent) RLIKE 'iphone' THEN 'iphone' WHEN lower(agent) RLIKE 'ipad' THEN 'ipad' WHEN lower(agent) RLIKE 'macintosh' THEN 'macintosh' WHEN lower(agent) RLIKE 'windows phone' THEN 'windows_phone' WHEN lower(agent) RLIKE 'windows' THEN 'windows_pc' ELSE 'unknown' END AS device, CASE WHEN lower(agent) RLIKE '(bot|spider|crawler|slurp)' THEN 'crawler' WHEN lower(agent) RLIKE 'feed' OR regexp_extract(request, '^[^ ]+ (.*) [^ ]+$', 1) RLIKE 'feed' THEN 'feed' WHEN lower(agent) NOT RLIKE '(bot|spider|crawler|feed|slurp)' AND agent RLIKE '^(Mozilla|Opera)' AND regexp_extract(request, '^[^ ]+ (.*) [^ ]+$', 1) NOT RLIKE 'feed' THEN 'user' ELSE 'unknown' END AS identity FROM ( SELECT SPLIT(col, '##@@')[0] AS ip, SPLIT(col, '##@@')[1] AS uid, SPLIT(col, '##@@')[2] AS tm, SPLIT(col, '##@@')[3] AS request, SPLIT(col, '##@@')[4] AS status, SPLIT(col, '##@@')[5] AS bytes, SPLIT(col, '##@@')[6] AS referer, SPLIT(col, '##@@')[7] AS agent FROM ods_raw_log_d_spark WHERE dt = '${bizdate}' ) a;NoteReplace the location address in the preceding code based on your actual environment.
dw-spark-demois the name of the OSS bucket that you created when you prepared the environment. -
On the right side of the EMR Spark SQL editor, click Run Configuration and configure the following parameters. These parameters are used for debugging in Step 5 with the Run Configuration parameters for test runs.
Configuration item
Description
Computing Resources
Select the Spark compute resource associated in the Prepare the environment stage.
Resource Group
Select the serverless resource group purchased in the Prepare the environment stage.
Script Parameters
Click Add parameter and set bizdate to a value in
yyyymmddformat (for example,bizdate=20250223). During debugging, Data Studio uses this constant to replace the variable defined in the task. -
(Optional) Configure scheduling properties.
In this tutorial, retain the default values for the schedule settings. On the right side of the node editing page, click Scheduling Configuration. For more information about the parameters, see Schedule settings.
-
Scheduling Parameters: In this tutorial, scheduling parameters are configured at the workflow level. You do not need to configure them for individual nodes within the workflow. The parameters can be used directly in tasks or code.
-
Scheduling Policy: You can specify the Delayed execution time parameter to define how long a child node waits before it starts running after the workflow starts. This parameter is not configured in this tutorial.
-
-
Click Save on the top toolbar to save the node.
Configure the dws_user_info_all_di_spark node
This node aggregates data from the user information table (ods_user_info_d_spark) and the processed log data table (dwd_log_info_di_spark), and writes the result to the dws_user_info_all_di_spark table.
-
On the workflow canvas, hover over the
dws_user_info_all_di_sparknode and click Open Node. -
Paste the following code into the SQL editor.
Paimon table (DLF)
-- Scenario: The following Spark SQL joins dwd_log_info_di_spark and ods_user_info_d_spark on uid, and writes the result to the corresponding dt partition. CREATE TABLE IF NOT EXISTS dws_user_info_all_di_spark ( uid STRING COMMENT 'User ID', gender STRING COMMENT 'Gender', age_range STRING COMMENT 'Age range', zodiac STRING COMMENT 'Zodiac sign', device STRING COMMENT 'Device type', method STRING COMMENT 'HTTP request method', url STRING COMMENT 'URL', `time` STRING COMMENT 'Time yyyymmddhh:mi:ss', dt STRING COMMENT 'Partition column' -- Best practice: include the partition key as a table column ) PARTITIONED BY (dt) TBLPROPERTIES ( 'format' = 'paimon' -- Core: declare as a Paimon table ); -- Insert data from the user table and log table INSERT OVERWRITE TABLE dws_user_info_all_di_spark PARTITION (dt = '${bizdate}') SELECT COALESCE(a.uid, b.uid) AS uid, b.gender AS gender, b.age_range AS age_range, b.zodiac AS zodiac, a.device AS device, a.method AS method, a.url AS url, a.tm FROM ( SELECT * FROM dwd_log_info_di_spark WHERE dt='${bizdate}' ) a LEFT OUTER JOIN ( SELECT * FROM ods_user_info_d_spark WHERE dt='${bizdate}' ) b ON a.uid = b.uid;Hive table (DLF-Legacy)
-- Scenario: The following Spark SQL joins dwd_log_info_di_spark and ods_user_info_d_spark on uid, and writes the result to the corresponding dt partition. CREATE TABLE IF NOT EXISTS dws_user_info_all_di_spark ( uid STRING COMMENT 'User ID', gender STRING COMMENT 'Gender', age_range STRING COMMENT 'Age range', zodiac STRING COMMENT 'Zodiac sign', device STRING COMMENT 'Device type', method STRING COMMENT 'HTTP request method', url STRING COMMENT 'URL', `time` STRING COMMENT 'Time yyyymmddhh:mi:ss' ) PARTITIONED BY (dt STRING) LOCATION 'oss://dw-spark-demo.oss-cn-shanghai-internal.aliyuncs.com/dws_user_info_all_di_spark/log_${bizdate}/'; -- Add partition ALTER TABLE dws_user_info_all_di_spark ADD IF NOT EXISTS PARTITION (dt = '${bizdate}'); -- Insert data from the user table and log table INSERT OVERWRITE TABLE dws_user_info_all_di_spark PARTITION (dt = '${bizdate}') SELECT COALESCE(a.uid, b.uid) AS uid, b.gender AS gender, b.age_range AS age_range, b.zodiac AS zodiac, a.device AS device, a.method AS method, a.url AS url, a.tm FROM ( SELECT * FROM dwd_log_info_di_spark WHERE dt='${bizdate}' ) a LEFT OUTER JOIN ( SELECT * FROM ods_user_info_d_spark WHERE dt='${bizdate}' ) b ON a.uid = b.uid;NoteReplace the location address in the preceding code based on your actual environment.
dw-spark-demois the name of the OSS bucket that you created when you prepared the environment. -
On the right side of the EMR Spark SQL editor, click Run Configuration and configure the following parameters. These parameters are used for debugging in Step 5 with the Run Configuration parameters for test runs.
Configuration item
Description
Computing Resources
Select the Spark compute resource associated in the Prepare the environment stage.
Resource Group
Select the serverless resource group purchased in the Prepare the environment stage.
Script Parameters
Click Add parameter and set bizdate to a value in
yyyymmddformat (for example,bizdate=20250223). During debugging, Data Studio uses this constant to replace the variable defined in the task. -
(Optional) Configure scheduling properties.
In this tutorial, retain the default values for the schedule settings. On the right side of the node editing page, click Scheduling Configuration. For more information about the parameters, see Schedule settings.
-
Scheduling Parameters: In this tutorial, scheduling parameters are configured at the workflow level. You do not need to configure them for individual nodes within the workflow. The parameters can be used directly in tasks or code.
-
Scheduling Policy: You can specify the Delayed execution time parameter to define how long a child node waits before it starts running after the workflow starts. This parameter is not configured in this tutorial.
-
-
Click Save on the top toolbar to save the node.
Configure the ads_user_info_1d_spark node
This node further processes data from the dws_user_info_all_di_spark table and writes the result to the ads_user_info_1d_spark table to generate basic user profiles.
-
On the workflow canvas, hover over the
ads_user_info_1d_sparknode and click Open Node. -
Paste the following code into the SQL editor.
Paimon table (DLF)
-- Scenario: The following Spark SQL further processes the dws_user_info_all_di_spark table in Spark and writes the result to the new table ads_user_info_1d_spark. CREATE TABLE IF NOT EXISTS ads_user_info_1d_spark ( uid STRING COMMENT 'User ID', device STRING COMMENT 'Device type', pv BIGINT COMMENT 'PV', gender STRING COMMENT 'Gender', age_range STRING COMMENT 'Age range', zodiac STRING COMMENT 'Zodiac sign', dt STRING COMMENT 'Partition column' -- Best practice: include the partition key as a table column ) PARTITIONED BY (dt) TBLPROPERTIES ( 'format' = 'paimon' -- Core: declare as a Paimon table ); INSERT OVERWRITE TABLE ads_user_info_1d_spark PARTITION (dt='${bizdate}') SELECT uid , MAX(device) , COUNT(0) AS pv , MAX(gender) , MAX(age_range) , MAX(zodiac) FROM dws_user_info_all_di_spark WHERE dt = '${bizdate}' GROUP BY uid;Hive table (DLF-Legacy)
-- Scenario: The following Spark SQL further processes the dws_user_info_all_di_spark table in Spark and writes the result to the new table ads_user_info_1d_spark. CREATE TABLE IF NOT EXISTS ads_user_info_1d_spark ( uid STRING COMMENT 'User ID', device STRING COMMENT 'Device type', pv BIGINT COMMENT 'PV', gender STRING COMMENT 'Gender', age_range STRING COMMENT 'Age range', zodiac STRING COMMENT 'Zodiac sign' ) PARTITIONED BY ( dt STRING ) LOCATION 'oss://dw-spark-demo.oss-cn-shanghai-internal.aliyuncs.com/ads_user_info_1d_spark/log_${bizdate}/'; ALTER TABLE ads_user_info_1d_spark ADD IF NOT EXISTS PARTITION (dt='${bizdate}'); INSERT OVERWRITE TABLE ads_user_info_1d_spark PARTITION (dt='${bizdate}') SELECT uid , MAX(device) , COUNT(0) AS pv , MAX(gender) , MAX(age_range) , MAX(zodiac) FROM dws_user_info_all_di_spark WHERE dt = '${bizdate}' GROUP BY uid;NoteReplace the location address in the preceding code based on your actual environment.
dw-spark-demois the name of the OSS bucket that you created when you prepared the environment.NoteReplace the location address in the preceding code based on your actual environment.
dw-spark-demois the name of the OSS bucket that you created when you prepared the environment. -
On the right side of the EMR Spark SQL editor, click Run Configuration and configure the following parameters. These parameters are used for debugging in Step 5 with the Run Configuration parameters for test runs.
Configuration item
Description
Computing Resources
Select the Spark compute resource associated in the Prepare the environment stage.
Resource Group
Select the serverless resource group purchased in the Prepare the environment stage.
Script Parameters
Click Add parameter and set bizdate to a value in
yyyymmddformat (for example,bizdate=20250223). During debugging, Data Studio uses this constant to replace the variable defined in the task. -
(Optional) Configure scheduling properties.
In this tutorial, retain the default values for the schedule settings. On the right side of the node editing page, click Scheduling Configuration. For more information about the parameters, see Schedule settings.
-
Scheduling Parameters: In this tutorial, scheduling parameters are configured at the workflow level. You do not need to configure them for individual nodes within the workflow. The parameters can be used directly in tasks or code.
-
Scheduling Policy: You can specify the Delayed execution time parameter to define how long a child node waits before it starts running after the workflow starts. This parameter is not configured in this tutorial.
-
-
Click Save on the top toolbar to save the node.
Step 3: Process data
-
Process the data.
On the workflow toolbar, click Run. Set the values for the parameter variables defined in each node for this run (this tutorial uses
20250223; you can modify as needed). Click OK and wait for the run to complete. -
Query the data processing result.
After all nodes run successfully, run the following SQL queries to verify that the tables contain the expected data.
-
Verify the result of the dwd_log_info_di_spark table.
-- You need to update the partition filter condition to the actual business date of your current operation. For example, if the task runs on 20250223, the business date is 20250222, i.e., the day before the task run date. SELECT * FROM dwd_log_info_di_spark WHERE dt='${bizdate}'; -
Verify the result of the dws_user_info_all_di_spark table.
-- You need to update the partition filter condition to the actual business date of your current operation. For example, if the task runs on 20250223, the business date is 20250222, i.e., the day before the task run date. SELECT * FROM dws_user_info_all_di_spark WHERE dt='${bizdate}'; -
Verify the result of the ads_user_info_1d_spark table.
-- You need to update the partition filter condition to the actual business date of your current operation. For example, if the task runs on 20250223, the business date is 20250222, i.e., the day before the task run date. SELECT * FROM ads_user_info_1d_spark WHERE dt='${bizdate}';
-
Step 4: Deploy the workflow
Deploy the workflow to the production environment so that tasks can be automatically scheduled.
In this tutorial, the scheduling parameters have been configured in Workflow schedule settings. You do not need to configure scheduling parameters individually for each node before deployment.
-
In the left navigation bar of Data Studio, click
to go to the DataStudio page. Then, in the Project Directory area, find the created workflow and click the workflow to open the workflow orchestration page. -
Click Publish in the node toolbar to open the Publish panel.
-
Click Start Release Production. In the confirmation dialog box that appears, select a deployment method based on your requirements:
-
Full deployment: Deploys the current workflow and all its internal task nodes.
-
Incremental deployment: Deploys only the current workflow and the internal task nodes that have been modified since the last deployment. This is suitable for iterative optimizations and minor updates.
-
-
After you confirm the deployment method, the system automatically executes the deployment process, deploying the workflow and selected task nodes to the development and production environments in sequence. To complete the deployment to the production environment, you must click Confirm Release.
Step 5: Run tasks in the production environment
After a task is deployed, an instance is generated to run on the next day. You can use Supplementary data to backfill data for the deployed workflow and check whether the task can run in the production environment. For more information, see Data Backfill Instance O&M.
-
After the tasks are deployed, click Operation and Maintenance Center in the upper-right corner.
Alternatively, click the
icon in the upper-left corner and choose . -
In the left-side navigation pane, click to go to the Auto Triggered Node page, and click the
workshop_start_sparkvirtual node. -
In the DAG on the right, right-click the
workshop_start_sparknode and choose . -
Select the tasks for which you want to backfill data, set the business date, and click Submit and Redirect.
-
On the backfill data page, click Refresh until all SQL tasks have run successfully.
After you complete the tutorial, to avoid incurring further costs, you can set the validity period for the nodes or Freeze the virtual node workshop_start_spark in the workflow.
Next steps
-
Analyze data: Visualize the processed data in charts by using the Data Analysis module to extract key insights and identify business trends.
-
Monitor data quality: Configure data quality monitoring for the tables generated during data processing to proactively identify and block dirty data before it spreads.
-
Manage data assets: View the tables created during this workflow in the Data Map module and use lineage to explore the relationships between them.
-
Create data services: Share and consume the processed data through standardized API endpoints by using the Data Service module.