This is an automated email from the ASF dual-hosted git repository.

danny0405 pushed a commit to branch asf-site
in repository https://gitbox.apache.org/repos/asf/hudi.git


The following commit(s) were added to refs/heads/asf-site by this push:
     new fd7ae7ed9ff [DOCS] Add missing features for `HoodieStreamer` (#10758)
fd7ae7ed9ff is described below

commit fd7ae7ed9ffa3b1562489a4eace4b944f300c2ed
Author: Shiyan Xu <[email protected]>
AuthorDate: Mon Feb 26 18:54:44 2024 -0600

    [DOCS] Add missing features for `HoodieStreamer` (#10758)
---
 website/docs/hoodie_streaming_ingestion.md | 475 ++++++++++++++++++++---------
 1 file changed, 334 insertions(+), 141 deletions(-)

diff --git a/website/docs/hoodie_streaming_ingestion.md 
b/website/docs/hoodie_streaming_ingestion.md
index ac4e4cb73b4..50d6d4f0fff 100644
--- a/website/docs/hoodie_streaming_ingestion.md
+++ b/website/docs/hoodie_streaming_ingestion.md
@@ -6,6 +6,18 @@ import Tabs from '@theme/Tabs';
 import TabItem from '@theme/TabItem';
 
 ## 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](https://sqoop.apache.org/docs/1.4.2/SqoopUserGuide#_incremental_imports)
 from Sqoop or
+  output of `HiveIncrementalPuller` or 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](https://github.com/confluentinc/schema-registry).
+- Support for plugging in transformations
+
 :::danger Important
 
 The following classes were renamed and relocated to 
`org.apache.hudi.utilities.streamer` package.
@@ -15,98 +27,159 @@ The following classes were renamed and relocated to 
`org.apache.hudi.utilities.s
 - `HoodieDeltaStreamerMetrics` is renamed to `HoodieStreamerMetrics`
 - `HoodieMultiTableDeltaStreamer` is renamed to `HoodieMultiTableStreamer`
 
-To maintain backward compatiblity, the original classes are still present in 
the org.apache.hudi.utilities.deltastreamer
+To maintain backward compatibility, the original classes are still present in 
the `org.apache.hudi.utilities.deltastreamer`
 package, but have been deprecated.
 
 :::
 
-The `HoodieStreamer` utility (part of `hudi-utilities-bundle`) provides the 
way to ingest from different sources such as DFS or Kafka, with the following 
capabilities.
-
-- Exactly once ingestion of new events from Kafka, [incremental 
imports](https://sqoop.apache.org/docs/1.4.2/SqoopUserGuide#_incremental_imports)
 from Sqoop or output of `HiveIncrementalPuller` or 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](https://github.com/confluentinc/schema-registry).
-- Support for plugging in transformations
+### Options
+<details>
 
-Command line options describe capabilities in more detail
+<summary>
+Expand this to see HoodieStreamer's "--help" output describing its 
capabilities in more details.
+</summary>
 
-```java
+```shell
 [hoodie]$ spark-submit --class 
org.apache.hudi.utilities.streamer.HoodieStreamer `ls 
packaging/hudi-utilities-bundle/target/hudi-utilities-bundle-*.jar` --help
 Usage: <main class> [options]
-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
+      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
+      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
+      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
+      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 (Deprecated in favor of --enable-sync and 
--sync-tool-classes)
+      Enable syncing to hive
       Default: false
     --enable-sync
       Enable syncing meta
       Default: false
-    --sync-tool-classes
-      Classes (comma-separated) to be used for syncing meta. Shall be used 
only when --enable-sync or --enable-hive-sync is set to true
-      Note: When used with deprecated --enable-hive-sync flag, HiveSyncTool 
will always be run along with any other classes mentioned in here.
-      Default: org.apache.hudi.hive.HiveSyncTool
     --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 "--propsFilePath") can also be passed command line using this
-      parameter
+      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 (use when input is
-      purely new data/inserts to gain speed)
+      Takes one of these values : UPSERT (default), INSERT, BULK_INSERT,
+      INSERT_OVERWRITE, INSERT_OVERWRITE_TABLE, DELETE_PARTITION
       Default: UPSERT
-      Possible Values: [UPSERT, INSERT, BULK_INSERT]
+      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.
-      Default: 
file:///Users/vinoth/bin/hoodie/src/test/resources/streamer-config/dfs-source.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:
@@ -117,13 +190,11 @@ Options:
       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, AvroKafkaSource, CsvDFSSource, HiveIncrPullSource, 
-      JdbcSource, JsonKafkaSource, ORCDFSSource, ParquetDFSSource, 
-      S3EventsHoodieIncrSource, S3EventsSource, SqlSource}
+      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 For e.g:
+      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
@@ -132,22 +203,44 @@ Options:
       record
       Default: ts
     --spark-master
-      spark master to use.
-      Default: local[2]
+      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 in Hive
+      name of the target table
     --transformer-class
-      subclass 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 -
+      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)
+      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.
 ```
+</details>
 
 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`.
@@ -173,57 +266,29 @@ and then ingest it as follows.
 
 In some cases, you may want to migrate your existing table into Hudi 
beforehand. Please refer to [migration guide](/docs/migration_guide).
 
-### Note on hudi utilities bundle usage for different spark versions
-From 0.11.0 release, we start to provide a new `hudi-utilities-slim-bundle` 
which aims to exclude dependencies that can
-cause conflicts and compatibility issues with different versions of Spark.  
The `hudi-utilities-slim-bundle` 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:0.13.0,org.apache.hudi:hudi-spark3.1-bundle_2.12:0.13.0`,
-if using `hudi-utilities-bundle` solely to run `HoodieStreamer` in Spark 
encounters compatibility issues.
-
-#### MultiTableStreamer
+### Using `hudi-utilities` bundle jars
 
-`HoodieMultiTableStreamer`, a wrapper on top of `HoodieStreamer`, enables one 
to ingest multiple tables at a single go into hudi datasets. Currently it only 
supports sequential processing of tables to be ingested and COPY_ON_WRITE 
storage type. The command line options for `HoodieMultiTableStreamer` are 
pretty much similar to `HoodieStreamer` with the only exception that you are 
required to provide table wise configs in separate files in a dedicated config 
folder. The following command l [...]
+From 0.11.0 release, we start to provide a new `hudi-utilities-slim-bundle` 
which aims to exclude dependencies that can
+cause conflicts and compatibility issues with different versions of Spark.
 
-```java
-  * --config-folder
-    the path to the folder which contains all the table wise config files
-    --base-path-prefix
-    this is added to enable users to create all the hudi datasets for related 
tables under one path in FS. The datasets are then created under the path - 
<base_path_prefix>/<database>/<table_to_be_ingested>. However you can override 
the paths for every table by setting the property 
hoodie.streamer.ingestion.targetBasePath
-```
+It is recommended to switch to `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:0.13.0,org.apache.hudi:hudi-spark3.2-bundle_2.12:0.13.0`.
 
-The following properties are needed to be set properly to ingest data using 
`HoodieMultiTableStreamer`.
+`hudi-utilities-bundle` remains as a legacy bundle jar to work with Spark 2.4 
and 3.1.
 
-```java
-hoodie.streamer.ingestion.tablesToBeIngested
-  comma separated names of tables to be ingested in the format 
<database>.<table>, for example db1.table1,db1.table2
-hoodie.streamer.ingestion.targetBasePath
-  if you wish to ingest a particular table in a separate path, you can mention 
that path here
-hoodie.streamer.ingestion.<database>.<table>.configFile
-  path to the config file in dedicated config folder which contains table 
overridden properties for the particular table to be ingested.
-```
+### Concurrency Control
 
-Sample config files for table wise overridden properties can be found under 
`hudi-utilities/src/test/resources/streamer-config`. The command to run 
`HoodieMultiTableStreamer` is also similar to how you run `HoodieStreamer`.
+Using optimistic concurrency control (OCC) via Hudi Streamer requires the 
configs below to the properties file that can be passed to the
+job. 
 
-```java
-[hoodie]$ spark-submit --class 
org.apache.hudi.utilities.streamer.HoodieMultiTableStreamer `ls 
packaging/hudi-utilities-bundle/target/hudi-utilities-bundle-*.jar` \
-  --props 
file://${PWD}/hudi-utilities/src/test/resources/streamer-config/kafka-source.properties
 \
-  --config-folder file://tmp/hudi-ingestion-config \
-  --schemaprovider-class 
org.apache.hudi.utilities.schema.SchemaRegistryProvider \
-  --source-class org.apache.hudi.utilities.sources.AvroKafkaSource \
-  --source-ordering-field impresssiontime \
-  --base-path-prefix file:\/\/\/tmp/hudi-streamer-op \ 
-  --target-table uber.impressions \
-  --op BULK_INSERT
+```properties
+hoodie.write.concurrency.mode=optimistic_concurrency_control
+hoodie.write.lock.provider=<lock-provider-classname>
+hoodie.cleaner.policy.failed.writes=LAZY
 ```
 
-For detailed information on how to configure and use 
`HoodieMultiTableStreamer`, please refer [blog 
section](/blog/2020/08/22/ingest-multiple-tables-using-hudi).
-
-### Concurrency Control
-
-The `HoodieStreamer` utility (part of hudi-utilities-bundle) provides ways to 
ingest from different sources such as DFS or Kafka, with the following 
capabilities.
-
-Using optimistic_concurrency_control via Hudi Streamer requires adding the 
above configs to the properties file that can be passed to the
-job. For example below, adding the configs to kafka-source.properties file and 
passing them to Hudi Streamer will enable optimistic concurrency.
+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:
 
 ```java
@@ -232,14 +297,15 @@ A Hudi Streamer job can then be triggered as follows:
   --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-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](/docs/concurrency_control) section
 
-## Checkpointing
+### Checkpointing
+
 `HoodieStreamer` uses checkpoints to keep track of what data has been read 
already so it can resume without needing to reprocess all data.
 When using a Kafka source, the checkpoint is the [Kafka 
Offset](https://cwiki.apache.org/confluence/display/KAFKA/Offset+Management) 
 When using a DFS source, the checkpoint is the 'last modified' timestamp of 
the latest file read.
@@ -251,70 +317,97 @@ If you need to change the checkpoints for reprocessing or 
replaying data you can
 - `--source-limit` will set a maximum amount of data to read from the source. 
For DFS sources, this is max # of bytes read.
 For Kafka, this is the max # of events to read.
 
-## Schema Providers
+### Transformers
+
+`HoodieStreamer` supports custom transformation on records before writing to 
storage. This is done by supplying 
+implementation of `org.apache.hudi.utilities.transform.Transformer` via 
`--transformer-class` option. Check out
+the [options](#options) section for details.
+
+### Schema Providers
+
 By default, Spark will infer the schema of the source and use that inferred 
schema when writing to a table. If you need 
 to explicitly define the schema you can use one of the following Schema 
Providers below.
 
-### Schema Registry Provider
+#### Schema Registry Provider
+
 You can obtain the latest schema from an online registry. You pass a URL to 
the registry and if needed, you can also 
 pass userinfo and credentials in the url like: 
`https://foo:[email protected]` The credentials are then extracted 
 and are set on the request as an Authorization Header.
 
 When fetching schemas from a registry, you can specify both the source schema 
and the target schema separately.
 
-|Config|Description|Example|
-|---|---|---|
-|hoodie.streamer.schemaprovider.registry.url|The schema of the source you are 
reading from|https://foo:[email protected]|
-|hoodie.streamer.schemaprovider.registry.targetUrl|The schema of the target 
you are writing to|https://foo:[email protected]|
+| Config                                            | Description              
                      | Example                            |
+|---------------------------------------------------|------------------------------------------------|------------------------------------|
+| hoodie.streamer.schemaprovider.registry.url       | The schema of the source 
you are reading from  | https://foo:[email protected] |
+| hoodie.streamer.schemaprovider.registry.targetUrl | The schema of the target 
you are writing to    | https://foo:[email protected] |
 
 The above configs are passed to Hudi Streamer spark-submit command like: 
-```--hoodie-conf 
hoodie.streamer.schemaprovider.registry.url=https://foo:[email protected]```
 
-### JDBC Schema Provider
+```shell
+--hoodie-conf 
hoodie.streamer.schemaprovider.registry.url=https://foo:[email protected]
+```
+
+There are other optional configs to work with schema registry provider such as 
SSL-store related configs, and supporting
+custom transformation of schema returned by schema registry, e.g., converting 
the original json schema to avro schema
+via `org.apache.hudi.utilities.schema.converter.JsonToAvroSchemaConverter`.
+
+| Config                                                  | Description        
                                  | Example                                     
                           |
+|---------------------------------------------------------|------------------------------------------------------|------------------------------------------------------------------------|
+| hoodie.streamer.schemaprovider.registry.schemaconverter | The class name of 
the custom schema converter to use | 
`org.apache.hudi.utilities.schema.converter.JsonToAvroSchemaConverter` |
+| schema.registry.ssl.keystore.location                   | SSL key store 
location                               |                                        
                                |
+| schema.registry.ssl.keystore.password                   | SSL key store 
password                               |                                        
                                |
+| schema.registry.ssl.truststore.location                 | SSL trust store 
location                             |                                          
                              |
+| schema.registry.ssl.truststore.password                 | SSL trust store 
password                             |                                          
                              |
+| schema.registry.ssl.key.password                        | SSL key password   
                                  |                                             
                           |
+
+#### JDBC Schema Provider
+
 You can obtain the latest schema through a JDBC connection.
 
-|Config|Description|Example|
-|---|---|---|
-|hoodie.streamer.schemaprovider.source.schema.jdbc.connection.url|The JDBC URL 
to connect to. You can specify source specific connection properties in the 
URL|jdbc:postgresql://localhost/test?user=fred&password=secret|
-|hoodie.streamer.schemaprovider.source.schema.jdbc.driver.type|The class name 
of the JDBC driver to use to connect to this URL|org.h2.Driver|
-|hoodie.streamer.schemaprovider.source.schema.jdbc.username|username for the 
connection|fred|
-|hoodie.streamer.schemaprovider.source.schema.jdbc.password|password for the 
connection|secret|
-|hoodie.streamer.schemaprovider.source.schema.jdbc.dbtable|The table with the 
schema to reference|test_database.test1_table or test1_table|
-|hoodie.streamer.schemaprovider.source.schema.jdbc.timeout|The number of 
seconds the driver will wait for a Statement object to execute to the given 
number of seconds. Zero means there is no limit. In the write path, this option 
depends on how JDBC drivers implement the API setQueryTimeout, e.g., the h2 
JDBC driver checks the timeout of each query instead of an entire JDBC batch. 
It defaults to 0.|0|
-|hoodie.streamer.schemaprovider.source.schema.jdbc.nullable|If true, all 
columns are nullable|true|
+| Config                                                           | 
Description                                                                     
                                                                                
                                                                                
                                                                                
                      | Example                                                 
   |
+|------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------|
+| hoodie.streamer.schemaprovider.source.schema.jdbc.connection.url | The JDBC 
URL to connect to. You can specify source specific connection properties in the 
URL                                                                             
                                                                                
                                                                                
             | jdbc:postgresql://localhost/test?user=fred&password=secret |
+| hoodie.streamer.schemaprovider.source.schema.jdbc.driver.type    | The class 
name of the JDBC driver to use to connect to this URL                           
                                                                                
                                                                                
                                                                                
            | org.h2.Driver                                              |
+| hoodie.streamer.schemaprovider.source.schema.jdbc.username       | username 
for the connection                                                              
                                                                                
                                                                                
                                                                                
             | fred                                                       |
+| hoodie.streamer.schemaprovider.source.schema.jdbc.password       | password 
for the connection                                                              
                                                                                
                                                                                
                                                                                
             | secret                                                     |
+| hoodie.streamer.schemaprovider.source.schema.jdbc.dbtable        | The table 
with the schema to reference                                                    
                                                                                
                                                                                
                                                                                
            | test_database.test1_table or test1_table                   |
+| hoodie.streamer.schemaprovider.source.schema.jdbc.timeout        | The 
number of seconds the driver will wait for a Statement object to execute to the 
given number of seconds. Zero means there is no limit. In the write path, this 
option depends on how JDBC drivers implement the API setQueryTimeout, e.g., the 
h2 JDBC driver checks the timeout of each query instead of an entire JDBC 
batch. It defaults to 0. | 0                                                    
      |
+| hoodie.streamer.schemaprovider.source.schema.jdbc.nullable       | If true, 
all columns are nullable                                                        
                                                                                
                                                                                
                                                                                
             | true                                                       |
 
 The above configs are passed to Hudi Streamer spark-submit command like:
 ```--hoodie-conf 
hoodie.streamer.jdbcbasedschemaprovider.connection.url=jdbc:postgresql://localhost/test?user=fred&password=secret```
 
-### File Based Schema Provider
+#### File Based Schema Provider
+
 You can use a .avsc file to define your schema. You can then point to this 
file on DFS as a schema provider.
 
-|Config|Description|Example|
-|---|---|---|
-|hoodie.streamer.schemaprovider.source.schema.file|The schema of the source 
you are reading from|[example schema 
file](https://github.com/apache/hudi/blob/a8fb69656f522648233f0310ca3756188d954281/docker/demo/config/test-suite/source.avsc)|
-|hoodie.streamer.schemaprovider.target.schema.file|The schema of the target 
you are writing to|[example schema 
file](https://github.com/apache/hudi/blob/a8fb69656f522648233f0310ca3756188d954281/docker/demo/config/test-suite/target.avsc)|
+| Config                                            | Description              
                     | Example                                                  
                                                                                
     |
+|---------------------------------------------------|-----------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
+| hoodie.streamer.schemaprovider.source.schema.file | The schema of the source 
you are reading from | [example schema 
file](https://github.com/apache/hudi/blob/a8fb69656f522648233f0310ca3756188d954281/docker/demo/config/test-suite/source.avsc)
 |
+| hoodie.streamer.schemaprovider.target.schema.file | The schema of the target 
you are writing to   | [example schema 
file](https://github.com/apache/hudi/blob/a8fb69656f522648233f0310ca3756188d954281/docker/demo/config/test-suite/target.avsc)
 |
 
+#### Hive Schema Provider
 
-### Hive Schema Provider
 You can use hive tables to fetch source and target schema. 
 
-|Config| Description                                           |
-|---|-------------------------------------------------------|
-|hoodie.streamer.schemaprovider.source.schema.hive.database| Hive database 
from where source schema can be fetched |
-|hoodie.streamer.schemaprovider.source.schema.hive.table| Hive table from 
where source schema can be fetched    |
-|hoodie.streamer.schemaprovider.target.schema.hive.database| Hive database 
from where target schema can be fetched |
-|hoodie.streamer.schemaprovider.target.schema.hive.table| Hive table from 
where target schema can be fetched    |
+| Config                                                     | Description     
                                       |
+|------------------------------------------------------------|--------------------------------------------------------|
+| hoodie.streamer.schemaprovider.source.schema.hive.database | Hive database 
from where source schema can be fetched  |
+| hoodie.streamer.schemaprovider.source.schema.hive.table    | Hive table from 
where source schema can be fetched     |
+| hoodie.streamer.schemaprovider.target.schema.hive.database | Hive database 
from where target schema can be fetched  |
+| hoodie.streamer.schemaprovider.target.schema.hive.table    | Hive table from 
where target schema can be fetched     |
 
 
-### Schema Provider with Post Processor
+#### Schema Provider with Post Processor
 The SchemaProviderWithPostProcessor, will extract the schema from one of the 
previously mentioned Schema Providers and 
 then will apply a post processor to change the schema before it is used. You 
can write your own post processor by extending 
 this class: 
https://github.com/apache/hudi/blob/master/hudi-utilities/src/main/java/org/apache/hudi/utilities/schema/SchemaPostProcessor.java
 
-## Sources
+### Sources
+
 Hoodie Streamer can read data from a wide variety of sources. The following 
are a list of supported sources:
 
-### Distributed File System (DFS)
+#### Distributed File System (DFS)
 See the storage configurations page to see some examples of DFS applications 
Hudi can read from. The following are the 
 supported file formats Hudi can read/write with on DFS Sources. (Note: you can 
still use Spark/Flink readers to read from 
 other formats and then write data as Hudi format.)
@@ -331,57 +424,157 @@ For DFS sources the following behaviors are expected:
 - For JSON DFS source, you always need to set a schema. If the target Hudi 
table follows the same schema as from the source file, you just need to set the 
source schema. If not, you need to set schemas for both source and target. 
 - `HoodieStreamer` reads the files under the source base path 
(`hoodie.streamer.source.dfs.root`) directly, and it won't use the partition 
paths under this base path as fields of the dataset. Detailed examples can be 
found [here](https://github.com/apache/hudi/issues/5485).
 
-### Kafka
+#### Kafka
 Hudi can read directly from Kafka clusters. See more details on 
`HoodieStreamer` to learn how to setup streaming 
 ingestion with exactly once semantics, checkpointing, and plugin 
transformations. The following formats are supported 
 when reading data from Kafka:
 
-- AVRO
-- JSON
+- AVRO: `org.apache.hudi.utilities.sources.AvroKafkaSource`
+- JSON: `org.apache.hudi.utilities.sources.JsonKafkaSource`
+- Proto: `org.apache.hudi.utilities.sources.ProtoKafkaSource`
 
-### S3 Events
+Check out [Kafka source 
config](https://hudi.apache.org/docs/configurations#Kafka-Source-Configs) for 
more details.
+
+#### Pulsar
+
+`HoodieStreamer` also supports ingesting from Apache Pulsar via 
`org.apache.hudi.utilities.sources.PulsarSource`.
+Check out [Pulsar source 
config](https://hudi.apache.org/docs/configurations#Pulsar-Source-Configs) for 
more details.
+
+#### Cloud storage event sources
 AWS S3 storage provides an event notification service which will post 
notifications when certain events happen in your S3 bucket: 
 https://docs.aws.amazon.com/AmazonS3/latest/userguide/NotificationHowTo.html
-AWS will put these events in a Simple Queue Service (SQS). Apache Hudi 
provides an S3EventsSource that can read from SQS 
-to trigger/processing of new or changed data as soon as it is available on S3.
+AWS will put these events in a Simple Queue Service (SQS). Apache Hudi 
provides `S3EventsSource`
+and `S3EventsHoodieIncrSource` that can read from SQS to trigger/processing of 
new or changed data as soon as it is
+available on S3. Check out [S3 source 
configs](https://hudi.apache.org/docs/configurations#S3-Source-Configs) for 
more details.
+
+Similar to S3 event source, Google Cloud Storage (GCS) event source is also 
supported via `GcsEventsSource` and
+`GcsEventsHoodieIncrSource`. Check out [GCS events source 
configs](https://hudi.apache.org/docs/configurations#GCS-Events-Source-Configs) 
for more details.
 
-#### Setup
+##### AWS Setup
 1. Enable S3 Event Notifications 
https://docs.aws.amazon.com/AmazonS3/latest/userguide/NotificationHowTo.html
 2. Download the aws-java-sdk-sqs jar. 
 3. Find the queue URL and Region to set these configurations:
    1. 
hoodie.streamer.s3.source.queue.url=https://sqs.us-west-2.amazonaws.com/queue/url
    2. hoodie.streamer.s3.source.queue.region=us-west-2 
-4. start the S3EventsSource and S3EventsHoodieIncrSource using the 
`HoodieStreamer` utility as shown in sample commands below:
+4. Start the `S3EventsSource` and `S3EventsHoodieIncrSource` using the 
`HoodieStreamer` utility as shown in sample commands below:
 
 Insert code sample from this blog: 
https://hudi.apache.org/blog/2021/08/23/s3-events-source/#configuration-and-setup
 
-### JDBC Source
+#### JDBC Source
 Hudi can read from a JDBC source with a full fetch of a table, or Hudi can 
even read incrementally with checkpointing from a JDBC source.
 
-|Config|Description|Example|
-|---|---|---|
-|hoodie.streamer.jdbc.url|URL of the JDBC 
connection|jdbc:postgresql://localhost/test|
-|hoodie.streamer.jdbc.user|User to use for authentication of the JDBC 
connection|fred|
-|hoodie.streamer.jdbc.password|Password to use for authentication of the JDBC 
connection|secret|
-|hoodie.streamer.jdbc.password.file|If you prefer to use a password file for 
the connection||
-|hoodie.streamer.jdbc.driver.class|Driver class to use for the JDBC 
connection||
-|hoodie.streamer.jdbc.table.name||my_table|
-|hoodie.streamer.jdbc.table.incr.column.name|If run in incremental mode, this 
field will be used to pull new data incrementally||
-|hoodie.streamer.jdbc.incr.pull|Will the JDBC connection perform an 
incremental pull?||
-|hoodie.streamer.jdbc.extra.options.|How you pass extra configurations that 
would normally by specified as 
spark.read.option()|hoodie.streamer.jdbc.extra.options.fetchSize=100 
hoodie.streamer.jdbc.extra.options.upperBound=1 
hoodie.streamer.jdbc.extra.options.lowerBound=100|
-|hoodie.streamer.jdbc.storage.level|Used to control the persistence 
level|Default = MEMORY_AND_DISK_SER|
-|hoodie.streamer.jdbc.incr.fallback.to.full.fetch|Boolean which if set true 
makes an incremental fetch fallback to a full fetch if there is any error in 
the incremental read|FALSE|
-
-### SQL Source
-SQL Source that reads from any table, used mainly for backfill jobs which will 
process specific partition dates. 
+| Config                                           | Description               
                                                                                
                  | Example                                                     
                                                                                
       |
+|--------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
+| hoodie.streamer.jdbc.url                         | URL of the JDBC 
connection                                                                      
                            | jdbc:postgresql://localhost/test                  
                                                                                
                 |
+| hoodie.streamer.jdbc.user                        | User to use for 
authentication of the JDBC connection                                           
                            | fred                                              
                                                                                
                 |
+| hoodie.streamer.jdbc.password                    | Password to use for 
authentication of the JDBC connection                                           
                        | secret                                                
                                                                                
             |
+| hoodie.streamer.jdbc.password.file               | If you prefer to use a 
password file for the connection                                                
                     |                                                          
                                                                                
          |
+| hoodie.streamer.jdbc.driver.class                | Driver class to use for 
the JDBC connection                                                             
                    |                                                           
                                                                                
         |
+| hoodie.streamer.jdbc.table.name                  |                           
                                                                                
                  | my_table                                                    
                                                                                
       |
+| hoodie.streamer.jdbc.table.incr.column.name      | If run in incremental 
mode, this field will be used to pull new data incrementally                    
                      |                                                         
                                                                                
           |
+| hoodie.streamer.jdbc.incr.pull                   | Will the JDBC connection 
perform an incremental pull?                                                    
                   |                                                            
                                                                                
        |
+| hoodie.streamer.jdbc.extra.options.              | How you pass extra 
configurations that would normally by specified as spark.read.option()          
                         | hoodie.streamer.jdbc.extra.options.fetchSize=100 
hoodie.streamer.jdbc.extra.options.upperBound=1 
hoodie.streamer.jdbc.extra.options.lowerBound=100 |
+| hoodie.streamer.jdbc.storage.level               | Used to control the 
persistence level                                                               
                        | Default = MEMORY_AND_DISK_SER                         
                                                                                
             |
+| hoodie.streamer.jdbc.incr.fallback.to.full.fetch | Boolean which if set true 
makes an incremental fetch fallback to a full fetch if there is any error in 
the incremental read | FALSE                                                    
                                                                                
          |
+
+#### SQL Sources
+
+SQL Source `org.apache.hudi.utilities.sources.SqlSource` reads from any table, 
used mainly for backfill jobs which will process specific partition dates. 
 This won't update the streamer.checkpoint.key to the processed commit, instead 
it will fetch the latest successful 
 checkpoint key and set that value as this backfill commits checkpoint so that 
it won't interrupt the regular incremental 
 processing. To fetch and use the latest incremental checkpoint, you need to 
also set this hoodie_conf for Hudi Streamer 
 jobs: `hoodie.write.meta.key.prefixes = 'streamer.checkpoint.key'`
 
 Spark SQL should be configured using this hoodie config:
-hoodie.streamer.source.sql.sql.query = 'select * from source_table'
+`hoodie.streamer.source.sql.sql.query = 'select * from source_table'`
 
+Using `org.apache.hudi.utilities.sources.SqlFileBasedSource` allows setting 
the SQL queries in a file to read from any
+table. SQL file path should be configured using this hoodie config:
+`hoodie.streamer.source.sql.file = 'hdfs://xxx/source.sql'`
+
+### Error Table
+
+`HoodieStreamer` supports segregating error records into a separate table 
called "Error table" alongside with the 
+target data table. This allows easy integration with dead-letter queues (DLQ). 
Error Table is supported with 
+user-provided subclass of 
`org.apache.hudi.utilities.streamer.BaseErrorTableWriter` supplied via
+config `hoodie.errortable.write.class`. Check out more in 
`org.apache.hudi.config.HoodieErrorTableConfig`.
+
+### Termination Strategy
+
+Users can configure a post-write termination strategy under `continuous` mode 
if need be. For instance,
+users can configure graceful shutdown if there is no new data from the 
configured source for 5 consecutive times. 
+Here is the interface for the termination strategy.
+
+```java
+/**
+ * Post write termination strategy for deltastreamer in continuous mode.
+ */
+public interface PostWriteTerminationStrategy {
+
+  /**
+   * Returns whether HoodieStreamer needs to be shutdown.
+   * @param scheduledCompactionInstantAndWriteStatuses optional pair of 
scheduled compaction instant and write statuses.
+   * @return true if HoodieStreamer has to be shutdown. false otherwise.
+   */
+  boolean shouldShutdown(Option<Pair<Option<String>, JavaRDD<WriteStatus>>> 
scheduledCompactionInstantAndWriteStatuses);
+
+}
+```
+
+Also, this might help in bootstrapping a new table. Instead of doing one bulk 
load or bulk_insert leveraging a large
+cluster for a large input of data, one could start `HoodieStreamer` on the 
`continuous` mode and add a shutdown strategy
+to terminate, once all data has been bootstrapped. This way, each batch could 
be smaller and may not need a large
+cluster to bootstrap data. There is a concrete implementation provided 
out-of-the-box: 
[NoNewDataTerminationStrategy](https://github.com/apache/hudi/blob/0d0a4152cfd362185066519ae926ac4513c7a152/hudi-utilities/src/main/java/org/apache/hudi/utilities/deltastreamer/NoNewDataTerminationStrategy.java).
+Users can feel free to implement their own strategy as they see fit.
+
+### Dynamic configuration updates
+
+When Hoodie Streamer is running in `continuous` mode, the properties can be 
refreshed/updated before each sync calls.
+Interested users can implement 
`org.apache.hudi.utilities.deltastreamer.ConfigurationHotUpdateStrategy` to 
leverage this.
+
+## MultiTableStreamer
+
+`HoodieMultiTableStreamer`, a wrapper on top of `HoodieStreamer`, enables one 
to ingest multiple tables at a single go
+into hudi datasets. Currently it only supports sequential processing of tables 
to be ingested and COPY_ON_WRITE storage
+type. The command line options for `HoodieMultiTableStreamer` are pretty much 
similar to `HoodieStreamer` with the only
+exception that you are required to provide table wise configs in separate 
files in a dedicated config folder. The
+following command line options are introduced
+
+```java
+  * --config-folder
+    the path to the folder which contains all the table wise config files
+    --base-path-prefix
+    this is added to enable users to create all the hudi datasets for related 
tables under one path in FS. The datasets are then created under the path - 
<base_path_prefix>/<database>/<table_to_be_ingested>. However you can override 
the paths for every table by setting the property 
hoodie.streamer.ingestion.targetBasePath
+```
+
+The following properties are needed to be set properly to ingest data using 
`HoodieMultiTableStreamer`.
+
+```java
+hoodie.streamer.ingestion.tablesToBeIngested
+  comma separated names of tables to be ingested in the format 
<database>.<table>, for example db1.table1,db1.table2
+hoodie.streamer.ingestion.targetBasePath
+  if you wish to ingest a particular table in a separate path, you can mention 
that path here
+hoodie.streamer.ingestion.<database>.<table>.configFile
+  path to the config file in dedicated config folder which contains table 
overridden properties for the particular table to be ingested.
+```
+
+Sample config files for table wise overridden properties can be found
+under `hudi-utilities/src/test/resources/streamer-config`. The command to run 
`HoodieMultiTableStreamer` is also similar
+to how you run `HoodieStreamer`.
+
+```java
+[hoodie]$ spark-submit --class 
org.apache.hudi.utilities.streamer.HoodieMultiTableStreamer `ls 
packaging/hudi-utilities-bundle/target/hudi-utilities-bundle-*.jar` \
+  --props 
file://${PWD}/hudi-utilities/src/test/resources/streamer-config/kafka-source.properties
 \
+  --config-folder file://tmp/hudi-ingestion-config \
+  --schemaprovider-class 
org.apache.hudi.utilities.schema.SchemaRegistryProvider \
+  --source-class org.apache.hudi.utilities.sources.AvroKafkaSource \
+  --source-ordering-field impresssiontime \
+  --base-path-prefix file:\/\/\/tmp/hudi-streamer-op \ 
+  --target-table uber.impressions \
+  --op BULK_INSERT
+```
+
+For detailed information on how to configure and use 
`HoodieMultiTableStreamer`, please refer [blog 
section](/blog/2020/08/22/ingest-multiple-tables-using-hudi).
 
 ## Structured Streaming
 

Reply via email to