Using Spark
Hudi Streamer
The HoodieStreamer utility (part of hudi-utilities-slim-bundle and hudi-utilities-bundle) provides ways to ingest
from different sources such as DFS or Kafka, with the following capabilities.
- Exactly once ingestion of new events from
Kafka, incremental imports from Sqoop or
output of
HiveIncrementalPulleror files under a DFS folder - Support json, avro or a custom record types for the incoming data
- Manage checkpoints, rollback & recovery
- Leverage Avro schemas from DFS or Confluent schema registry.
- Support for plugging in transformations
The following classes were renamed and relocated to org.apache.hudi.utilities.streamer package.
DeltastreamerMultiWriterCkptUpdateFuncis renamed toStreamerMultiWriterCkptUpdateFuncDeltaSyncis renamed toStreamSyncHoodieDeltaStreameris renamed toHoodieStreamerHoodieDeltaStreamerMetricsis renamed toHoodieStreamerMetricsHoodieMultiTableDeltaStreameris renamed toHoodieMultiTableStreamer
To maintain backward compatibility, the original classes are still present in the org.apache.hudi.utilities.deltastreamer
package, but have been deprecated.
Options
Expand this to see HoodieStreamer's "--help" output describing its capabilities in more details.
[hoodie]$ spark-submit \
--packages org.apache.hudi:hudi-utilities-slim-bundle_2.12:1.0.1,org.apache.hudi:hudi-spark3.5-bundle_2.12:1.0.1 \
--class org.apache.hudi.utilities.streamer.HoodieStreamer `ls packaging/hudi-utilities-slim-bundle/target/hudi-utilities-slim-bundle-*.jar` --help
Usage: <main class> [options]
Options:
--allow-commit-on-no-checkpoint-change
allow commits even if checkpoint has not changed before and after fetch
datafrom source. This might be useful in sources like SqlSource where
there is not checkpoint. And is not recommended to enable in continuous
mode.
Default: false
--base-file-format
File format for the base files. PARQUET (or) HFILE
Default: PARQUET
--bootstrap-index-class
subclass of BootstrapIndex
Default: org.apache.hudi.common.bootstrap.index.HFileBootstrapIndex
--bootstrap-overwrite
Overwrite existing target table, default false
Default: false
--checkpoint
Resume Hudi Streamer from this checkpoint.
--cluster-scheduling-minshare
Minshare for clustering as defined in
https://spark.apache.org/docs/latest/job-scheduling.html
Default: 0
--cluster-scheduling-weight
Scheduling weight for clustering as defined in
https://spark.apache.org/docs/latest/job-scheduling.html
Default: 1
--commit-on-errors
Commit even when some records failed to be written
Default: false
--compact-scheduling-minshare
Minshare for compaction as defined in
https://spark.apache.org/docs/latest/job-scheduling.html
Default: 0
--compact-scheduling-weight
Scheduling weight for compaction as defined in
https://spark.apache.org/docs/latest/job-scheduling.html
Default: 1
--config-hot-update-strategy-class
Configuration hot update in continuous mode
Default: <empty string>
--continuous
Hudi Streamer runs in continuous mode running source-fetch -> Transform
-> Hudi Write in loop
Default: false
--delta-sync-scheduling-minshare
Minshare for delta sync as defined in
https://spark.apache.org/docs/latest/job-scheduling.html
Default: 0
--delta-sync-scheduling-weight
Scheduling weight for delta sync as defined in
https://spark.apache.org/docs/latest/job-scheduling.html
Default: 1
--disable-compaction
Compaction is enabled for MoR table by default. This flag disables it
Default: false
--enable-hive-sync
Enable syncing to hive
Default: false
--enable-sync
Enable syncing meta
Default: false
--filter-dupes
Should duplicate records from source be dropped/filtered out before
insert/bulk-insert
Default: false
--force-empty-sync
Force syncing meta even on empty commit
Default: false
--help, -h
--hoodie-conf
Any configuration that can be set in the properties file (using the CLI
parameter "--props") can also be passed command line using this
parameter. This can be repeated
Default: []
--ingestion-metrics-class
Ingestion metrics class for reporting metrics during ingestion
lifecycles.
Default: org.apache.hudi.utilities.streamer.HoodieStreamerMetrics
--initial-checkpoint-provider
subclass of
org.apache.hudi.utilities.checkpointing.InitialCheckpointProvider.
Generate check point for Hudi Streamer for the first run. This field
will override the checkpoint of last commit using the checkpoint field.
Use this field only when switching source, for example, from DFS source
to Kafka Source.
--max-pending-clustering
Maximum number of outstanding inflight/requested clustering. Delta Sync
will not happen unlessoutstanding clustering is less than this number
Default: 5
--max-pending-compactions
Maximum number of outstanding inflight/requested compactions. Delta Sync
will not happen unlessoutstanding compactions is less than this number
Default: 5
--max-retry-count
the max retry count if --retry-on-source-failures is enabled
Default: 3
--min-sync-interval-seconds
the min sync interval of each sync in continuous mode
Default: 0
--op
Takes one of these values : UPSERT (default), INSERT, BULK_INSERT,
INSERT_OVERWRITE, INSERT_OVERWRITE_TABLE, DELETE_PARTITION
Default: UPSERT
Possible Values: [INSERT, INSERT_PREPPED, UPSERT, UPSERT_PREPPED, BULK_INSERT, BULK_INSERT_PREPPED, DELETE, DELETE_PREPPED, BOOTSTRAP, INSERT_OVERWRITE, CLUSTER, DELETE_PARTITION, INSERT_OVERWRITE_TABLE, COMPACT, INDEX, ALTER_SCHEMA, LOG_COMPACT, UNKNOWN]
--payload-class
subclass of HoodieRecordPayload, that works off a GenericRecord.
Implement your own, if you want to do something other than overwriting
existing value
Default: org.apache.hudi.common.model.OverwriteWithLatestAvroPayload
--post-write-termination-strategy-class
Post writer termination strategy class to gracefully shutdown
deltastreamer in continuous mode
Default: <empty string>
--props
path to properties file on localfs or dfs, with configurations for
hoodie client, schema provider, key generator and data source. For
hoodie client props, sane defaults are used, but recommend use to
provide basic things like metrics endpoints, hive configs etc. For
sources, referto individual classes, for supported properties.
Properties in this file can be overridden by "--hoodie-conf"
Default: file:///Users/shiyanxu/src/test/resources/streamer-config/dfs-source.properties
--retry-interval-seconds
the retry interval for source failures if --retry-on-source-failures is
enabled
Default: 30
--retry-last-pending-inline-clustering, -rc
Retry last pending inline clustering plan before writing to sink.
Default: false
--retry-last-pending-inline-compaction
Retry last pending inline compaction plan before writing to sink.
Default: false
--retry-on-source-failures
Retry on any source failures
Default: false
--run-bootstrap
Run bootstrap if bootstrap index is not found
Default: false
--schemaprovider-class
subclass of org.apache.hudi.utilities.schema.SchemaProvider to attach
schemas to input & target table data, built in options:
org.apache.hudi.utilities.schema.FilebasedSchemaProvider.Source (See
org.apache.hudi.utilities.sources.Source) implementation can implement
their own SchemaProvider. For Sources that return Dataset<Row>, the
schema is obtained implicitly. However, this CLI option allows
overriding the schemaprovider returned by Source.
--source-class
Subclass of org.apache.hudi.utilities.sources to read data. Built-in
options: org.apache.hudi.utilities.sources.{JsonDFSSource (default),
AvroDFSSource, JsonKafkaSource, AvroKafkaSource, HiveIncrPullSource}
Default: org.apache.hudi.utilities.sources.JsonDFSSource
--source-limit
Maximum amount of data to read from source. Default: No limit, e.g:
DFS-Source => max bytes to read, Kafka-Source => max events to read
Default: 9223372036854775807
--source-ordering-field
Field within source record to decide how to break ties between records
with same key in input data. Default: 'ts' holding unix timestamp of
record
Default: ts
--spark-master
spark master to use, if not defined inherits from your environment
taking into account Spark Configuration priority rules (e.g. not using
spark-submit command).
Default: <empty string>
--sync-tool-classes
Meta sync client tool, using comma to separate multi tools
Default: org.apache.hudi.hive.HiveSyncTool
* --table-type
Type of table. COPY_ON_WRITE (or) MERGE_ON_READ
* --target-base-path
base path for the target hoodie table. (Will be created if did not exist
first time around. If exists, expected to be a hoodie table)
* --target-table
name of the target table
--transformer-class
A subclass or a list of subclasses of
org.apache.hudi.utilities.transform.Transformer. Allows transforming raw
source Dataset to a target Dataset (conforming to target schema) before
writing. Default : Not set. E.g. -
org.apache.hudi.utilities.transform.SqlQueryBasedTransformer (which
allows a SQL query templated to be passed as a transformation function).
Pass a comma-separated list of subclass names to chain the
transformations. If there are two or more transformers using the same
config keys and expect different values for those keys, then transformer
can include an identifier. E.g. -
tr1:org.apache.hudi.utilities.transform.SqlQueryBasedTransformer. Here
the identifier tr1 can be used along with property key like
`hoodie.streamer.transformer.sql.tr1` to identify properties related to
the transformer. So effective value for
`hoodie.streamer.transformer.sql` is determined by key
`hoodie.streamer.transformer.sql.tr1` for this transformer. If
identifier is used, it should be specified for all the transformers.
Further the order in which transformer is applied is determined by the
occurrence of transformer irrespective of the identifier used for the
transformer. For example: In the configured value below tr2:org.apache.hudi.utilities.transform.SqlQueryBasedTransformer,tr1:org.apache.hudi.utilities.transform.SqlQueryBasedTransformer
, tr2 is applied before tr1 based on order of occurrence.
The tool takes a hierarchically composed property file and has pluggable interfaces for extracting data, key generation and providing schema. Sample configs for ingesting from kafka and dfs are
provided under hudi-utilities/src/test/resources/streamer-config.
For e.g: once you have Confluent Kafka, Schema registry up & running, produce some test data using (impressions.avro provided by schema-registry repo)
[confluent-5.0.0]$ bin/ksql-datagen schema=../impressions.avro format=avro topic=impressions key=impressionid
and then ingest it as follows.
[hoodie]$ spark-submit \
--packages org.apache.hudi:hudi-utilities-slim-bundle_2.12:1.0.1,org.apache.hudi:hudi-spark3.5-bundle_2.12:1.0.1 \
--class org.apache.hudi.utilities.streamer.HoodieStreamer `ls packaging/hudi-utilities-slim-bundle/target/hudi-utilities-slim-bundle-*.jar` \
--props file://${PWD}/hudi-utilities/src/test/resources/streamer-config/kafka-source.properties \
--schemaprovider-class org.apache.hudi.utilities.schema.SchemaRegistryProvider \
--source-class org.apache.hudi.utilities.sources.AvroKafkaSource \
--source-ordering-field impresssiontime \
--target-base-path file:\/\/\/tmp/hudi-streamer-op \
--target-table uber.impressions \
--op BULK_INSERT
In some cases, you may want to migrate your existing table into Hudi beforehand. Please refer to migration guide.
Using hudi-utilities-slim-bundle bundle jar
It is recommended to use hudi-utilities-slim-bundle, which should be used along with a Hudi Spark bundle
corresponding the Spark version used to make utilities work with Spark, e.g.,
--packages org.apache.hudi:hudi-utilities-slim-bundle_2.12:1.0.1,org.apache.hudi:hudi-spark3.5-bundle_2.12:1.0.1.
Concurrency Control
Using optimistic concurrency control (OCC) via Hudi Streamer requires the configs below to the properties file that can be passed to the job.
hoodie.write.concurrency.mode=optimistic_concurrency_control
hoodie.write.lock.provider=<lock-provider-classname>
hoodie.cleaner.policy.failed.writes=LAZY
As an example, adding the configs to kafka-source.properties file and passing them to Hudi Streamer will enable OCC.
A Hudi Streamer job can then be triggered as follows:
[hoodie]$ spark-submit \
--packages org.apache.hudi:hudi-utilities-slim-bundle_2.12:1.0.1,org.apache.hudi:hudi-spark3.5-bundle_2.12:1.0.1 \
--class org.apache.hudi.utilities.streamer.HoodieStreamer `ls packaging/hudi-utilities-slim-bundle/target/hudi-utilities-slim-bundle-*.jar` \
--props file://${PWD}/hudi-utilities/src/test/resources/streamer-config/kafka-source.properties \
--schemaprovider-class org.apache.hudi.utilities.schema.SchemaRegistryProvider \
--source-class org.apache.hudi.utilities.sources.AvroKafkaSource \
--source-ordering-field impresssiontime \
--target-base-path file:///tmp/hudi-streamer-op \
--target-table uber.impressions \
--op BULK_INSERT
Read more in depth about concurrency control in the concurrency control concepts section