Broker Load

Updated at:
Copy as MD

Broker Load is an asynchronous import method that uses broker processes to read data from Apache Hadoop Distributed File System (HDFS) or Alibaba Cloud Object Storage Service (OSS) and load it into EMR Serverless StarRocks. It is suited for large-scale batch imports of tens to hundreds of GB at a time.

Supported data sources and file formats

Broker Load supports the following storage systems:

  • HDFS

  • OSS

Broker Load supports CSV, ORC, and Parquet files. If you do not set FORMAT AS, StarRocks infers the format from the file extension (.csv, .parquet, .orc).

Prerequisites

Before you begin, ensure that you have:

When you create an EMR StarRocks instance, brokers are automatically built and started. To verify, run:

SHOW PROC "/brokers";

Load data from OSS

Step 1: Create a table

CREATE DATABASE IF NOT EXISTS load_test;
USE load_test;
CREATE TABLE IF NOT EXISTS customer (
  c_customer_sk         BIGINT,
  c_customer_id         CHAR(16),
  c_current_cdemo_sk    BIGINT,
  c_current_hdemo_sk    BIGINT,
  c_current_addr_sk     BIGINT,
  c_first_shipto_date_sk BIGINT,
  c_first_sales_date_sk  BIGINT,
  c_salutation          CHAR(10),
  c_first_name          CHAR(20),
  c_last_name           CHAR(30),
  c_preferred_cust_flag CHAR(1),
  c_birth_day           INT,
  c_birth_month         INT,
  c_birth_year          INT,
  c_birth_country       VARCHAR(20),
  c_login               CHAR(13),
  c_email_address       CHAR(50),
  c_last_review_date_sk  BIGINT
)
DUPLICATE KEY (c_customer_sk)
DISTRIBUTED BY HASH(c_customer_sk) BUCKETS 5
PROPERTIES (
  "replication_num" = "1"
);

Step 2: Submit a load job

Download customer.orc and upload it to your OSS bucket. Then submit the load job:

LOAD LABEL load_test.customer_label
(
  DATA INFILE("<file_path>")
  INTO TABLE customer
  FORMAT AS "orc"
)
WITH BROKER
(
  "fs.oss.accessKeyId"     = "<your_access_key_id>",
  "fs.oss.accessKeySecret" = "<your_access_key_secret>",
  "fs.oss.endpoint"        = "oss-cn-<region>-internal.aliyuncs.com"
);

Replace the placeholders with your actual values:

PlaceholderDescription
<file_path>Full OSS path to the data file. Example: oss://<your_bucket>/data/customer.orc
<your_access_key_id>AccessKey ID of your Alibaba Cloud account or RAM user. Get it from the AccessKey Pair page
<your_access_key_secret>AccessKey Secret that corresponds to the AccessKey ID
<region>OSS region where your bucket resides. Use the virtual private cloud (VPC) endpoint if EMR Serverless StarRocks and OSS are in the same region (for example, oss-cn-hangzhou-internal.aliyuncs.com); otherwise use the public endpoint. See Regions and endpoints

Step 3: Check the job status

USE load_test;
SHOW LOAD WHERE LABEL = 'customer_label'\G

For a description of all fields, see Monitor a load job.

Step 4: Verify the imported data

-- Count total rows
SELECT COUNT(1) FROM load_test.customer;

-- Preview the first two rows
SELECT * FROM load_test.customer LIMIT 2;

Load data from HDFS

Prerequisites

  • The HDFS cluster and the StarRocks instance must be in the same VPC and the same zone.

  • Enable the DataNode ports in the security group to allow HDFS data access. For details, see Manage security groups.

Note

This example uses a DataLake cluster created on the EMR on ECS page. To find the internal IP address of the NameNode, go to the Nodes tab of your cluster.

Step 1: Create a database and a table

CREATE DATABASE IF NOT EXISTS mydatabase;

CREATE TABLE IF NOT EXISTS mydatabase.userdata_broker_load (
    userId           INT,
    userName         VARCHAR(20),
    registrationDate DATE
)
ENGINE = OLAP
DUPLICATE KEY(userId)
DISTRIBUTED BY HASH(userId);

Step 2: Submit a load job

Download user_data.parquet and upload it to the /data directory in HDFS. Then submit the load job:

LOAD LABEL mydatabase.userdata_broker_load_label
(
  DATA INFILE("hdfs://<hdfs_ip>:<hdfs_port>/data/user_data.parquet")
  INTO TABLE userdata_broker_load
  FORMAT AS "parquet"
)
WITH BROKER
PROPERTIES
(
  "timeout" = "72000"
);
ParameterDescription
<hdfs_ip>Internal IP address of the NameNode in the HDFS cluster
<hdfs_port>Port of the NameNode. Default: 9000

Step 3: Check the job status and verify data

USE mydatabase;
SHOW LOAD WHERE LABEL = 'userdata_broker_load_label'\G

After the job reaches FINISHED state, verify the imported data:

SELECT * FROM mydatabase.userdata_broker_load;

HDFS authentication

The community edition of HDFS supports simple authentication and Kerberos authentication.

Simple authentication

User identity is determined by the operating system of the client connecting to HDFS. Add the following to StorageCredentialParams in the WITH BROKER clause:

"hadoop.security.authentication" = "simple",
"username" = "<hdfs_username>",
"password" = "<hdfs_password>"
ParameterDescription
hadoop.security.authenticationAuthentication mode. Valid values: simple (default), kerberos
usernameUsername for accessing the NameNodes
passwordPassword for accessing the NameNodes

Kerberos authentication

User identity is determined by Kerberos credentials. Add the following configuration items to the hdfs-site.xml file on the Instance Configuration tab of the StarRocks instance:

"hadoop.security.authentication" = "kerberos",
"kerberos_principal"             = "nn/zelda1@ZELDA.COM",
"kerberos_keytab"                = "/keytab/hive.keytab",
"kerberos_keytab_content"        = "YWFhYWFh"
ParameterDescription
hadoop.security.authenticationSet to kerberos
kerberos_principalKerberos principal in the format username_or_servicename/instance@REALM. The realm must be uppercase. Example: nn/zelda1@ZELDA.COM
kerberos_keytabPath to the Kerberos keytab file. The file must reside on the same server as the broker processes
kerberos_keytab_contentBase64-encoded content of the keytab file
Important

Configure either kerberos_keytab or kerberos_keytab_content, not both.

HDFS high availability (HA) configuration

When NameNode high availability (HA) is configured, StarRocks automatically identifies the active NameNode after a failover. Add the following to hdfs-site.xml on the Instance Configuration tab:

"dfs.nameservices"                                      = "ha_cluster",
"dfs.ha.namenodes.ha_cluster"                           = "ha_n1,ha_n2",
"dfs.namenode.rpc-address.ha_cluster.ha_n1"             = "<hdfs_host>:<hdfs_port>",
"dfs.namenode.rpc-address.ha_cluster.ha_n2"             = "<hdfs_host>:<hdfs_port>",
"dfs.client.failover.proxy.provider.ha_cluster"         = "org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider"
ParameterDescription
dfs.nameservicesCustom name of the HDFS service
dfs.ha.namenodes.xxxComma-separated custom names of the NameNodes. Replace xxx with the value of dfs.nameservices
dfs.namenode.rpc-address.xxx.nnRemote procedure call (RPC) address of each NameNode. Replace nn with the corresponding NameNode name
dfs.client.failover.proxy.provider.xxxFailover proxy provider. Default: org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider
Note

To view these values for an existing HDFS cluster, go to the EMR on ECS page, find the cluster, and click Services in the Actions column. On the Services tab, find HDFS and click Configure, then open the hdfs-site.xml subtab.

Reference

LOAD LABEL syntax

LOAD LABEL [<database_name>.]<label_name>
(
    data_desc[, data_desc ...]
)
WITH BROKER
(
    StorageCredentialParams
)
[PROPERTIES
(
    opt_properties
)
]

data_desc parameters

DATA INFILE ("<file_path>"[, "<file_path>" ...])
[NEGATIVE]
INTO TABLE <table_name>
[PARTITION (<partition1_name>[, <partition2_name> ...])]
[TEMPORARY PARTITION (<temporary_partition1_name>[, <temporary_partition2_name> ...])]
[COLUMNS TERMINATED BY "<column_separator>"]
[ROWS TERMINATED BY "<row_separator>"]
[FORMAT AS "CSV | Parquet | ORC"]
[(format_type_options)]
[(column_list)]
[COLUMNS FROM PATH AS (<partition_field_name>[, <partition_field_name> ...])]
[SET <k1=f1(v1)>[, <k2=f2(v2)> ...]]
[WHERE predicate]
ParameterDescription
file_pathPath to the data files. Supports wildcards: ?, *, [], {}, ^. For wildcard usage, see FileSystem. Examples: oss://bucket/data/tablename/*/* imports all files in all partitions; oss://bucket/data/tablename/dt=202104*/* imports only the 202104 partition
NEGATIVEDeletes a previously imported batch by importing the same data with negated values. Only applicable to aggregate columns of the SUM type
PARTITIONTarget partitions in the destination table. If not set, data is loaded into all partitions
COLUMNS TERMINATED BYColumn delimiter. Default: \t. Because the MySQL protocol escapes special characters on submission, prefix invisible characters with an extra backslash: use \\t for tab, \\n for newline, \\x01 for Apache Hive™ files
FORMAT ASSource file format: CSV, Parquet, or ORC. If not set, inferred from file extension
COLUMNS FROM PATH ASExtracts partition field values from the file path. For example, for a path like /path/col_name=col_value/file1, specifying col_name loads col_value into the corresponding destination column. Only available when importing from HDFS
SETColumn type conversion using the expression syntax column_name = expression. The result is inserted into the destination table
WHEREFilter predicate applied after column type conversion. Only rows that match the condition are loaded

Label behavior

Each import job has a unique label within the database:

  • After `FINISHED`: the label becomes invalid and cannot be reused.

  • After `CANCELLED`: the label can be reused to submit a new import job.

Labels enforce exactly-once semantics: reusing a label for the same data prevents duplicate imports.

Atomicity

A single LOAD statement is atomic. When loading multiple data files, either all files are loaded successfully or none are.

Job properties (opt_properties)

PROPERTIES ("<key1>" = "<value1>"[, "<key2>" = "<value2>" ...])
ParameterDefaultDescription
timeout14400 seconds (4 hours)Job timeout in seconds. If the job does not complete within the timeout, its state changes to CANCELLED. Calculate the minimum timeout using: (total_file_size_MB × number_of_source_files_and_materialized_views) / average_import_speed_MB_per_s. For example: a 1 GB file with 2 related materialized views at 10 MB/s requires at least (1024 × 3) / 10 = 307.2 seconds
max_filter_ratio0Maximum tolerable error rate (0–1). If the actual error rate exceeds this value, the job fails. Set to a value greater than 0 to allow erroneous rows to be skipped. Calculate using: max_filter_ratio = dpp.abnorm.ALL / (dpp.abnorm.ALL + dpp.norm.ALL)
load_mem_limitMemory limit for the job in bytes. Cannot exceed the backend (BE) or compute node (CN) memory cap
strict_modefalseWhen true, erroneous rows are filtered out and only correct rows are imported; error details are returned. When false, fields that fail type conversion are set to NULL and imported alongside correct rows

Monitor a load job

Run SHOW LOAD to check the status of all import jobs in the current database:

USE <database_name>;
SHOW LOAD;

To filter by label:

SHOW LOAD WHERE LABEL = "<label_name>"\G
FieldDescription
JobIdUnique, auto-generated ID. Never reused, even if the job fails
LabelLabel of the import job
StateJob status: PENDING (created), QUEUEING (waiting), LOADING (in progress), CANCELLED (failed), FINISHED (succeeded)
ProgressLoading progress: (tables imported / total source tables) × 100%. Reaches 99% when all source tables are loaded, and 100% only after the job completes. Progress is not linear — a period of no change does not mean the job is stuck
TypeAlways BROKER for Broker Load jobs
EtlInfoData metrics: unselected.rows (rows filtered by WHERE), dpp.norm.ALL (rows loaded), dpp.abnorm.ALL (erroneous rows). Their sum equals the total rows in source files
TaskInfoJob configuration at creation: cluster, timeout, and max_filter_ratio
ErrorMsgError details when the job is CANCELLED. Contains type and msg. Error types: USER_CANCEL, ETL_SUBMIT_FAIL, ETL_QUALITY_UNSATISFIED, LOAD-RUN-FAIL, TIMEOUT, UNKNOWN
CreateTimeTime the job was created
EtlStartTimeSame as LoadStartTime — Broker Load has no ETL phase
EtlFinishTimeSame as LoadStartTime — Broker Load has no ETL phase
LoadStartTimeTime the job entered the LOADING phase
LoadFinishTimeTime the job completed
URLURL to access erroneous data (open with curl or wget). NULL if no errors
JobDetailsDetails including Unfinished backends, ScannedRows, TaskNumber, All backends, FileNumber, and FileSize (in bytes)

Cancel a load job

Cancel a job that is not in CANCELLED or FINISHED state:

CANCEL LOAD FROM <database_name> WHERE LABEL = "<label_name>";

Concurrency

A load job consists of one or more tasks that run in parallel. A job is split into multiple tasks when:

  • Multiple data_desc clauses point to different source addresses.

  • Multiple data_desc clauses point to different partitions of the same source table.

Each task is further split into instances distributed across backends (BEs) for parallel execution. The number of instances per task is determined by the following frontend (FE) configuration parameters:

ParameterDefaultDescription
min_bytes_per_broker_scanner64 MBMinimum data volume processed by each instance
max_broker_concurrency100Maximum parallel instances per task
load_parallel_instance_num1Parallel instances per backend

Total instances = min(total_file_size / min_bytes_per_broker_scanner, max_broker_concurrency, load_parallel_instance_num × number_of_backends)

Troubleshoot common errors

When a load job fails, check the ErrorMsg field in SHOW LOAD output. The following table lists common error types and how to resolve them.

Error typeCauseResolution
ETL_QUALITY_UNSATISFIEDThe error rate exceeds max_filter_ratioIncrease max_filter_ratio in PROPERTIES, or fix data quality issues in the source files. Use URL from SHOW LOAD to inspect erroneous rows
TIMEOUTThe job did not complete within the timeout periodIncrease the timeout value in PROPERTIES. Use the formula (total_file_size_MB × number_of_source_files_and_materialized_views) / average_import_speed_MB_per_s to estimate the required timeout
LOAD-RUN-FAILThe job failed during the LOAD phaseCheck the msg field in ErrorMsg for details. Common causes include insufficient memory — try reducing load_mem_limit or splitting the load into smaller batches
ETL_SUBMIT_FAILThe job could not be submittedVerify that the broker processes are running by executing SHOW PROC "/brokers"
USER_CANCELThe job was cancelled manuallyResubmit the job if needed
UNKNOWNAn unexpected error occurredContact Alibaba Cloud support and provide the JobId