Process data

更新时间: 2026-07-17 20:57:39

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.

  1. In the Data Studio left-side navigation pane, click the image icon. In the Project Directory section, find and click the User_profile_analysis_Spark workflow you created to open its canvas.

  2. 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

    imageEMR Spark SQL

    dwd_log_info_di_spark

    Processes data from the ods_raw_log_d_spark table using Spark SQL and writes the result to the dwd_log_info_di_spark table.

    imageEMR Spark SQL

    dws_user_info_all_di_spark

    Joins the detail log table dwd_log_info_di_spark and the user table ods_user_info_d_spark on 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 the dws_user_info_all_di_spark table.

    imageEMR Spark SQL

    ads_user_info_1d_spark

    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.

  3. Manually drag to connect the nodes and configure the upstream node for each node. The final result is as follows:

    image
    Note

    You 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.

  1. On the workflow canvas, hover over the dwd_log_info_di_spark node and click Open Node.

  2. 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;
    Note

    Replace the location address in the preceding code based on your actual environment. dw-spark-demo is the name of the OSS bucket that you created when you prepared the environment.

  3. 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 yyyymmdd format (for example, bizdate=20250223). During debugging, Data Studio uses this constant to replace the variable defined in the task.

  4. (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.

  5. 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.

  1. On the workflow canvas, hover over the dws_user_info_all_di_spark node and click Open Node.

  2. 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;
    Note

    Replace the location address in the preceding code based on your actual environment. dw-spark-demo is the name of the OSS bucket that you created when you prepared the environment.

  3. 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 yyyymmdd format (for example, bizdate=20250223). During debugging, Data Studio uses this constant to replace the variable defined in the task.

  4. (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.

  5. 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.

  1. On the workflow canvas, hover over the ads_user_info_1d_spark node and click Open Node.

  2. 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; 
    Note

    Replace the location address in the preceding code based on your actual environment. dw-spark-demo is the name of the OSS bucket that you created when you prepared the environment.

    Note

    Replace the location address in the preceding code based on your actual environment. dw-spark-demo is the name of the OSS bucket that you created when you prepared the environment.

  3. 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 yyyymmdd format (for example, bizdate=20250223). During debugging, Data Studio uses this constant to replace the variable defined in the task.

  4. (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.

  5. Click Save on the top toolbar to save the node.

Step 3: Process data

  1. 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.

  2. Query the data processing result.

    After all nodes run successfully, run the following SQL queries to verify that the tables contain the expected data.

    1. 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}';

    2. 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}';

    3. 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.

Note

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.

  1. In the left navigation bar of Data Studio, click image 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.

  2. Click Publish in the node toolbar to open the Publish panel.

  3. 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.

  4. 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.

  1. After the tasks are deployed, click Operation and Maintenance Center in the upper-right corner.

    Alternatively, click the icon icon in the upper-left corner and choose All Products > Data Development and O&M > Operation and Maintenance Center (Workflow).

  2. In the left-side navigation pane, click Auto Triggered Task O&M > Auto Triggered Node to go to the Auto Triggered Node page, and click the workshop_start_spark virtual node.

  3. In the DAG on the right, right-click the workshop_start_spark node and choose Supplementary data > Current and Descendant Nodes Retroactively.

  4. Select the tasks for which you want to backfill data, set the business date, and click Submit and Redirect.

  5. On the backfill data page, click Refresh until all SQL tasks have run successfully.

Note

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.

上一篇: Synchronize data 下一篇: Monitor data quality
阿里云首页 大数据开发治理平台 DataWorks 相关技术圈