For the complete documentation index, see llms.txt. This page is also available as Markdown.

Batch Data Ingestion in Practice

In practice, we need to run Pinot data ingestion as a pipeline or a scheduled job.

Assuming pinot-distribution is already built, inside examples directory, you could find several sample table layouts.

Table Layout

Usually each table deserves its own directory, like airlineStats.

Inside the table directory, rawdata is created to put all the input data.

Typically, for data events with timestamp, we partition those data and store them into a daily folder. E.g. a typically layout would follow this pattern: rawdata/%yyyy%/%mm%/%dd%/[daily_input_files].

/var/pinot/airlineStats/rawdata/2014/01/01/airlineStats_data_2014-01-01.avro
/var/pinot/airlineStats/rawdata/2014/01/02/airlineStats_data_2014-01-02.avro
/var/pinot/airlineStats/rawdata/2014/01/03/airlineStats_data_2014-01-03.avro
/var/pinot/airlineStats/rawdata/2014/01/04/airlineStats_data_2014-01-04.avro
/var/pinot/airlineStats/rawdata/2014/01/05/airlineStats_data_2014-01-05.avro
/var/pinot/airlineStats/rawdata/2014/01/06/airlineStats_data_2014-01-06.avro
/var/pinot/airlineStats/rawdata/2014/01/07/airlineStats_data_2014-01-07.avro
/var/pinot/airlineStats/rawdata/2014/01/08/airlineStats_data_2014-01-08.avro
/var/pinot/airlineStats/rawdata/2014/01/09/airlineStats_data_2014-01-09.avro
/var/pinot/airlineStats/rawdata/2014/01/10/airlineStats_data_2014-01-10.avro
/var/pinot/airlineStats/rawdata/2014/01/11/airlineStats_data_2014-01-11.avro
/var/pinot/airlineStats/rawdata/2014/01/12/airlineStats_data_2014-01-12.avro
/var/pinot/airlineStats/rawdata/2014/01/13/airlineStats_data_2014-01-13.avro
/var/pinot/airlineStats/rawdata/2014/01/14/airlineStats_data_2014-01-14.avro
/var/pinot/airlineStats/rawdata/2014/01/15/airlineStats_data_2014-01-15.avro
/var/pinot/airlineStats/rawdata/2014/01/16/airlineStats_data_2014-01-16.avro
/var/pinot/airlineStats/rawdata/2014/01/17/airlineStats_data_2014-01-17.avro
/var/pinot/airlineStats/rawdata/2014/01/18/airlineStats_data_2014-01-18.avro
/var/pinot/airlineStats/rawdata/2014/01/19/airlineStats_data_2014-01-19.avro
/var/pinot/airlineStats/rawdata/2014/01/20/airlineStats_data_2014-01-20.avro
/var/pinot/airlineStats/rawdata/2014/01/21/airlineStats_data_2014-01-21.avro
/var/pinot/airlineStats/rawdata/2014/01/22/airlineStats_data_2014-01-22.avro
/var/pinot/airlineStats/rawdata/2014/01/23/airlineStats_data_2014-01-23.avro
/var/pinot/airlineStats/rawdata/2014/01/24/airlineStats_data_2014-01-24.avro
/var/pinot/airlineStats/rawdata/2014/01/25/airlineStats_data_2014-01-25.avro
/var/pinot/airlineStats/rawdata/2014/01/26/airlineStats_data_2014-01-26.avro
/var/pinot/airlineStats/rawdata/2014/01/27/airlineStats_data_2014-01-27.avro
/var/pinot/airlineStats/rawdata/2014/01/28/airlineStats_data_2014-01-28.avro
/var/pinot/airlineStats/rawdata/2014/01/29/airlineStats_data_2014-01-29.avro
/var/pinot/airlineStats/rawdata/2014/01/30/airlineStats_data_2014-01-30.avro
/var/pinot/airlineStats/rawdata/2014/01/31/airlineStats_data_2014-01-31.avro

Configuring batch ingestion job

Create a batch ingestion job spec file to describe how to ingest the data.

Below is an example (also located at examples/batch/airlineStats/ingestionJobSpec.yaml)

Executing the job

Below command will create example table into Pinot cluster.

Below command will kick off the ingestion job to generate Pinot segments and push them into the cluster.

After job finished, segments are stored in examples/batch/airlineStats/segments following same layout of input directory layout.

Executing the job using Spark

The example below runs Spark in local mode against the sample airlineStats data on the local filesystem (no S3/HDFS credentials). Download a Spark 3.x distribution and set SPARK_HOME, or use a pre-installed Spark.

Build or download a Pinot binary distribution following the local install guide.

Local-FS Spark job spec

Use LocalPinotFS for local paths. Spark 3 runner classes live in the spark3 package. You can start from examples/batch/airlineStats/sparkIngestionJobSpec.yaml and align class names / FS as below:

Local-mode spark-submit

Ensure PINOT_DISTRIBUTION_DIR points at an unpacked binary distribution (contains lib/, plugins/, plugins-external/, and examples/).

Required pieces:

  • plugins.dir — semicolon-separated list including both plugins (record readers such as Avro) and plugins-external (Spark batch runners)

  • spark.driver.extraClassPath / spark.executor.extraClassPathpinot-batch-ingestion-spark-3-*-shaded.jar and pinot-all-*-jar-with-dependencies.jar

Executing the job using Hadoop

Sample Hadoop ingestion job spec (also at examples/batch/airlineStats/hadoopIngestionJobSpec.yaml). For a local filesystem dry run, prefer LocalPinotFS as below (the checked-in sample may use HadoopPinotFS for HDFS-oriented pipelines):

Ensure PINOT_ROOT_DIR and PINOT_VERSION are set properly.

Executing a backfill ingestion job

When the backfill input directory for a given date may contain fewer files than the original ingestion, LaunchDataIngestionJob cannot fully replace the existing segments — see the Edge case example in the backfill docs. For that case, use LaunchBackfillIngestionJob, which reuses the same ingestionJobSpec.yaml and replaces the existing segments in a date range via Pinot's segment-lineage machinery.

The -startDate (inclusive) and -endDate (exclusive) arguments use yyyy-MM-dd format and are parsed as UTC day boundaries.

For the full step-by-step workflow, supported options (including -partitionColumn / -partitionColumnValue for partition-scoped backfills), and OFFLINE-only constraints, see Backfill Data.

Tuning

You can set Environment Variable: JAVA_OPTS to modify:

  • Log4j2 file location with -Dlog4j2.configurationFile

  • Plugin directory location with -Dplugins.dir=/opt/pinot/plugins (standalone). For Spark/Hadoop batch jobs, use a semicolon-separated list that also includes plugins-external: -Dplugins.dir=/opt/pinot/plugins;/opt/pinot/plugins-external

  • JVM props, like -Xmx8g -Xms4G

Note that you need to config above three all together in JAVA_OPTS. If you only config JAVA_OPTS="-Xmx4g" then plugins.dir is empty usually will cause job failure.

E.g. standalone Docker job:

You can also add your customized JAVA_OPTS if necessary.

Last updated

Was this helpful?