This topic describes how to use Spark SQL to create the external user information table ods_user_info_d_spark and the log table ods_raw_log_d_spark to access user and log data stored in a private Object Storage Service (OSS) bucket. You will then use EMR Spark SQL nodes in DataWorks to process the data and generate the target user profile data. This topic illustrates how to use Spark SQL to compute and analyze synchronized data in a simple data warehousing scenario.
Prerequisites
Before you begin, complete the steps in Synchronize data.
You have created the
ods_user_info_d_sparkexternal table using an EMR Spark SQL node to access basic user information synchronized to a private OSS bucket.You have created the
ods_raw_log_d_sparkexternal table using an EMR Spark SQL node to access log data synchronized to a private OSS bucket.
Usage notes
Because EMR Serverless Spark does not support function registration, you cannot use custom functions to parse log data or convert IP addresses to geographic locations. Instead, this tutorial uses built-in Spark SQL functions to parse the ods_raw_log_d_spark log table and generate the dwd_log_info_di_spark table for further user profile analysis.
Objectives
In this section, you will process the ods_user_info_d_spark and ods_raw_log_d_spark external tables to generate a basic user profile table.
Use Spark SQL to process the
ods_raw_log_d_sparktable and generate a new detailed log table nameddwd_log_info_di_spark.Join the detailed log table
dwd_log_info_di_sparkand the user tableods_user_info_d_sparkon the uid field to generate an aggregated user log table nameddws_user_info_all_di_spark.The
dws_user_info_all_di_sparktable is large and not optimized for direct data consumption. To improve performance, you will process it into theads_user_info_1d_sparktable.
I. Design the workflow
In the Synchronize data section, you completed the data synchronization workflow for user profile analysis. In the data processing stage, you will add a dwd_log_info_di_spark node to parse the log table, a dws_user_info_all_di_spark node to join the detailed log and user tables, and an ads_user_info_1d_spark node to produce the final user profile table.
Go to Data Development.
Log on to the DataWorks console. In the target region, click in the left-side navigation pane. Select a workspace from the drop-down list and click Go to Data Development.
In the Synchronize data stage, you used EMR Spark SQL nodes to create external tables for accessing data in a private OSS bucket. The next step is to process this data to generate basic user profile data.
Node layers and logic
On the workflow canvas, click New Node to create the following nodes for data processing.
Node category
Node type
Node name
Code logic
EMR
EMR Spark SQLdwd_log_info_di_spark
Parses the
ods_raw_log_d_sparklog table to create a new log table for downstream joins.EMR
EMR Spark SQLdws_user_info_all_di_spark
Aggregates basic user information and pre-processed log data into a single table.
EMR
EMR Spark SQLads_user_info_1d_spark
Further processes data to generate the basic user profile.
Workflow DAG
Drag the nodes onto the workflow canvas and connect them by drawing lines to define upstream and downstream dependencies for the data processing workflow.
II. Configure the EMR Spark SQL nodes
After you design the workflow, use Spark SQL functions in the EMR Spark SQL nodes to process the ods_raw_log_d_spark table. You will parse the log data, join it with the user table to create a new detailed table, and then perform further cleaning and processing to build user profiles.
dwd_log_info_di_spark
On the workflow panel, double-click the EMR Spark SQL node dwd_log_info_di_spark to open the edit page of the dwd_log_info_di_spark node. Write code to process the upstream ods_raw_log_d_spark table and write the detailed log data into the dwd_log_info_di_spark table.
Configure code
Double-click the
dwd_log_info_di_sparknode to open the configuration page and enter the following SQL statements.-- Scenario: This Spark SQL script uses Spark SQL functions to split the ods_raw_log_d_spark table by "##@@" into multiple fields and writes the results to a new table named dwd_log_info_di_spark. -- Note: -- DataWorks provides scheduling parameters to write daily incremental data to the corresponding business partition of the target table. -- In a real-world development scenario, you can define code variables by using the ${variable_name} format and assign scheduling parameters to them on the scheduling configuration page to enable dynamic parameter passing. CREATE TABLE IF NOT EXISTS dwd_log_info_di_spark ( ip STRING COMMENT 'IP address', uid STRING COMMENT 'User ID', tm STRING COMMENT 'Time in yyyymmddhh:mi:ss format', status STRING COMMENT 'Status code returned by the server', bytes STRING COMMENT 'Bytes returned to the client', method STRING COMMENT'Request method', url STRING COMMENT 'URL', protocol STRING COMMENT 'Protocol', referer STRING , device STRING, identity STRING ) PARTITIONED BY ( dt STRING ); 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;Configure scheduling properties
Parameter
Description
Example
Add parameter
In the Scheduling Parameters section, click Add Parameter and configure the following:
Parameter Name:
bizdateParameter Value:
$[yyyymmdd-1]
For more information, see Configure scheduling parameters.
On the parameter configuration page, set Parameter Name to
bizdateand Parameter Value to$[yyyymmdd-1].Scheduling dependency
In the Scheduling Dependency section, confirm that the output table is specified as the output of this node.
The format is
worksspacename.nodename.For more information, see Configure scheduling dependencies.
The output list for this node should contain the manually added output
User_portraits.dwd_log_info_di_emr.NoteSet the Scheduling period to Daily. You do not need to separately configure the Scheduling Time for the current node. The daily start time of the current node is controlled by the scheduled time of the workflow virtual node workshop_start_spark. This means the node is scheduled only after 00:30 every day.
Save the configuration
Configure other required parameters as needed. When you are finished, click the
icon in the toolbar of the node configuration tab to save the settings.Verify the log table splitting
After the upstream nodes and the current node have run successfully, create an EMR Spark SQL Ad Hoc Query task to verify that the table was created correctly.
-- You must update the partition filter to your actual business date. For example, if the task runs on 2023-02-22, the business date is 2023-02-21 (the day before the task run date). SELECT * FROM dwd_log_info_di_spark WHERE dt = 'your_business_date';NoteIn this tutorial, the scheduling parameter
${bizdate}is configured in SQL and set toT-1. In an offline computing scenario, bizdate is the date on which business transactions occur, and is also known as the business date. For example, if you calculate the previous day's sales revenue today, the previous day refers to the date on which the transactions occurred, which is the business date.
dws_user_info_all_di_spark
This node joins the dwd_log_info_di_spark log table and the ods_user_info_d_spark user table on the uid field to generate a new detailed user log table named dws_user_info_all_di_spark.
Edit code
Double-click the dws_user_info_all_di_spark node to open the node configuration page. Enter the following SQL statements.
-- Scenario: This Spark SQL script joins the dwd_log_info_di_spark and ods_user_info_d_spark tables on the uid field and writes the result to the corresponding dt partition. -- Note: -- DataWorks provides scheduling parameters to write daily incremental data to the corresponding business partition of the target table. -- In a real-world development scenario, you can define code variables by using the ${variable_name} format and assign scheduling parameters to them on the scheduling configuration page to enable dynamic parameter passing. 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 'Terminal type', method STRING COMMENT 'HTTP request type', url STRING COMMENT 'URL', `time` STRING COMMENT 'Time in yyyymmddhh:mi:ss format' ) PARTITIONED BY (dt STRING); -- Add a partition. ALTER TABLE dws_user_info_all_di_spark ADD IF NOT EXISTS PARTITION (dt = '${bizdate}'); -- Insert data from the user and log tables. 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;Configure scheduling properties
Parameter
Description
Example
Add parameter
In the Scheduling Parameters section, click Add Parameter and configure the following:
Parameter Name:
bizdateParameter Value:
$[yyyymmdd-1]
For more information, see Configure scheduling parameters.
Scheduling dependency
In the Scheduling Dependency section, confirm that the output table is specified as the output of this node.
The format is
worksspacename.nodename.For more information, see Configure scheduling dependencies.
In This Node's Output, verify that the output name
User_portraits.dws_user_infor_all_di_spark(manually added) is in the output list.NoteSet the Scheduling period to Daily. You do not need to separately configure the Scheduling Time for the current node. The daily start time of the current node is controlled by the scheduled time of the workflow virtual node workshop_start_spark. This means the node is scheduled only after 00:30 every day.
Save the configuration
Configure other required parameters as needed. When you are finished, click the
icon in the toolbar of the node configuration tab to save the settings.Verify the detailed user log table data
After the upstream nodes and the current node have run successfully, create an EMR Spark SQL Ad Hoc Query task to verify that the table was created correctly.
-- You must update the partition filter to your actual business date. For example, if the task runs on 2024-08-08, the business date is 2024-08-07 (the day before the task run date). SELECT * FROM dws_user_info_all_di_spark WHERE dt = 'your_business_date';NoteIn this tutorial, the scheduling parameter
${bizdate}is configured in SQL and set toT-1. In an offline computing scenario, bizdate is the date on which business transactions occur, and is also known as the business date. For example, if you calculate the previous day's sales revenue today, the previous day refers to the date on which the transactions occurred, which is the business date.
ads_user_info_1d_spark
Based on the dws_user_info_all_di_spark table, this node performs MAX and COUNT calculations to generate the ads_user_info_1d_spark table, which serves as the final user profile table for consumption.
Edit code
Double-click the ads_user_info_1d_spark node to open the node configuration page. Enter the following SQL statements.
-- Scenario: This Spark SQL script further processes the dws_user_info_all_di_spark table by using Spark SQL functions and writes the result to a new table named ads_user_info_1d_spark. -- Note: -- DataWorks provides scheduling parameters to write daily incremental data to the corresponding business partition of the target table. -- In a real-world development scenario, you can define code variables by using the ${variable_name} format and assign scheduling parameters to them on the scheduling configuration page to enable dynamic parameter passing. CREATE TABLE IF NOT EXISTS ads_user_info_1d_spark ( uid STRING COMMENT 'User ID', device STRING COMMENT 'Terminal type', pv BIGINT COMMENT 'PV', gender STRING COMMENT 'Gender', age_range STRING COMMENT 'Age range', zodiac STRING COMMENT 'Zodiac sign' ) PARTITIONED BY ( dt STRING ); 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;Configure scheduling properties
Parameter
Description
Example
Add parameter
In the Scheduling Parameters section, click Add Parameter and configure the following:
Parameter Name:
bizdateParameter Value:
$[yyyymmdd-1]
For more information, see Configure scheduling parameters.
In the parameter configuration section, enter
bizdatefor the parameter name and$[yyyymmdd-1]for the parameter value.Scheduling dependency
In the Scheduling Dependency section, confirm that the output table is specified as the output of this node.
The format is
worksspacename.nodeName.For more information, see Configure scheduling dependencies.
In the Output of This Node area, confirm that the output name
User_portrait_s.ads_user_info_o_1d_sparkhas been added to the output list by using Manual Add.NoteSet the Scheduling period to Daily. You do not need to separately configure the Scheduling Time for the current node. The daily start time of the current node is controlled by the scheduled time of the workflow virtual node workshop_start_spark. This means the node is scheduled only after 00:30 every day.
Save the configuration
Configure other required parameters as needed. When you are finished, click the
icon in the toolbar of the node configuration tab to save the settings.Verify the user profile table data
After the upstream nodes and the current node have run successfully, create an EMR Spark SQL Ad Hoc Query task to verify that the table was created correctly.
-- You must update the partition filter to your actual business date. For example, if the task runs on 2023-02-22, the business date is 2023-02-21 (the day before the task run date). SELECT * FROM ads_user_info_1d_spark WHERE dt = 'your_business_date';NoteIn this tutorial, the scheduling parameter
${bizdate}is configured in SQL and set toT-1. In an offline computing scenario, bizdate is the date on which business transactions occur, and is also known as the business date. For example, if you calculate the previous day's sales revenue today, the previous day refers to the date on which the transactions occurred, which is the business date.
III. Commit the workflow
After configuring the workflow, test it to ensure it runs correctly. After a successful test, commit the workflow for deployment.
-
On the workflow configuration tab, click the
icon to run the workflow. -
After the
icon appears on all nodes in the workflow, click the
icon to commit the workflow. -
In the Submit dialog box, select the nodes to commit, select Ignore I/O Inconsistency Alerts, and then click Confirm.
-
After the commit is successful, deploy the workflow nodes.
-
On the right side of the page, click Publish to open the Create Deploy Task page.
-
Select the nodes to deploy, click Deploy, and in the Confirm Release dialog box, click Publish.
-
IV. Run tasks in production
After a task is deployed, an instance is automatically generated and run on the next day. To verify that the task runs as expected in the production environment, you can run a Supplementary data for the deployed workflow. For more information, see Manage data backfill instances.
After the task is successfully deployed, click Operation and Maintenance Center in the upper-right corner.
You can also go to the workflow editor page and click Go to operations in the toolbar to go to the Operation and Maintenance Center page.
In the left-side navigation pane, choose . On the Auto Triggered Node page, click the workshop_start_spark zero load node.
In the DAG on the right, right-click the workshop_start_spark node and choose .
Select the tasks to backfill, enter the business date, and click OK. You are automatically redirected to the Retroactive Instances page.
Click Refresh until all SQL tasks are run successfully.