首先部署Hudi不需要启动任何服务,就只是个安装包而已。实际上就是使用现有的服务器设备构件事务型分布式存储模型。Hudi通过Spark任务创建他的程序,采用Spark标准协议开发(标准协议见:Cluster Mode Overview - Spark 3.4.1 Documentation)。查询Hudi表通过安装在Apache Hive、Apache Spark或PrestoDB中的库完成,因此不需要额外的基础设施。
典型的Hudi数据使用可以在两种模式下实现。在单次运行模式下,Hudi摄取读取下一批数据,将它们摄取到Hudi表并退出。在连续模式下,Hudi摄取作为长时间运行的服务在循环中执行摄取。
对于Merge_On_Read表,Hudi摄取还需要考虑压缩增量文件。同样,可以以异步模式执行压缩,方法是让压缩与摄取同时运行,或者一个接一个地以串行方式运行。
增量流处理
DeltaStreamer 是一个独立的实用程序,用于增量地从各种来源(如DFS、Kafka和DB changlogs)中提取上游更改,并将它们摄取到hudi表中。它作为spark应用程序在两种模式下运行。
在Spark使用需要在spark-submit中添加--packages org.apache.hudi:hudi-utilities-bundle_2.11:0.13.1,必填参数。从0.11.0版本开始,我们开始提供一个新的hudi-utilities-slim-bundle,旨在排除可能导致不同版本Spark冲突和兼容性问题的依赖关系。hudi-utilities-slim-bundle应该和对应Spark版本的Hudi Spark bundle一起使用,比如:在Spark中单独使用hudi-utilities-bundle会遇到兼容性问题,--packages org.apache.hudi:hudi-utilities-slim-bundle_2.12:0.13.1,org.apache.hudi:hudi-spark3.1-bundle_2.12:0.13.1。
Run Once Mode
在这种模式下,Deltastreamer执行一轮摄取,包括增量地从上游源提取事件并将它们摄取到hudi表中。 后台操作,如清理旧的文件版本和归档hoodie时间线,将自动作为运行的一部分执行。对于Merge-On-Read表,压缩也作为摄取的一部分内联运行,除非通过--disable-compaction禁用压缩。默认情况下,每次摄取时压缩都是内联运行的,这可以通过设置属性“hoodie.compact.inline.max.delta.commits”来改变。您既可以手动运行此spark应用程序,也可以使用任何cron触发器或工作流编排器(最常见的部署策略),如Apache Airflow来生成此应用程序。
下面是一个示例调用,在单运行模式下从kafka主题读取并写入yarn集群中的Merge On Read表类型。
spark-submit --packages org.apache.hudi:hudi-utilities-bundle_2.11:0.13.1 \
--master yarn \
--deploy-mode cluster \
--num-executors 10 \
--executor-memory 3g \
--driver-memory 6g \
--conf spark.driver.extraJavaOptions="-XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/varadarb_ds_driver.hprof" \
--conf spark.executor.extraJavaOptions="-XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/varadarb_ds_executor.hprof" \
--queue hadoop-platform-queue \
--conf spark.scheduler.mode=FAIR \
--conf spark.yarn.executor.memoryOverhead=1072 \
--conf spark.yarn.driver.memoryOverhead=2048 \
--conf spark.task.cpus=1 \
--conf spark.executor.cores=1 \
--conf spark.task.maxFailures=10 \
--conf spark.memory.fraction=0.4 \
--conf spark.rdd.compress=true \
--conf spark.kryoserializer.buffer.max=200m \
--conf spark.serializer=org.apache.spark.serializer.KryoSerializer \
--conf spark.memory.storageFraction=0.1 \
--conf spark.shuffle.service.enabled=true \
--conf spark.sql.hive.convertMetastoreParquet=false \
--conf spark.ui.port=5555 \
--conf spark.driver.maxResultSize=3g \
--conf spark.executor.heartbeatInterval=120s \
--conf spark.network.timeout=600s \
--conf spark.eventLog.overwrite=true \
--conf spark.eventLog.enabled=true \
--conf spark.eventLog.dir=hdfs:///user/spark/applicationHistory \
--conf spark.yarn.max.executor.failures=10 \
--conf spark.sql.catalogImplementation=hive \
--conf spark.sql.shuffle.partitions=100 \
--driver-class-path $HADOOP_CONF_DIR \
--class org.apache.hudi.utilities.deltastreamer.HoodieDeltaStreamer \
--table-type MERGE_ON_READ \
--source-class org.apache.hudi.utilities.sources.JsonKafkaSource \
--source-ordering-field ts \
--target-base-path /user/hive/warehouse/stock_ticks_mor \
--target-table stock_ticks_mor \
--props /var/demo/config/kafka-source.properties \
--schemaprovider-class org.apache.hudi.utilities.schema.FilebasedSchemaProvider
Continuous Mode
在这里,deltastreamer运行一个无限循环,每轮执行一次摄取循环,如Once Mode中所述。数据摄取的频率可以通过配置“--min-sync-interval-seconds”来控制。对于Merge-On-Read表,压缩以异步方式与摄取同时运行,除非通过传递“--disable-compaction”标志来禁用。每次摄取运行都会异步触发一个压缩请求,这个频率可以通过设置属性“hoodie.compact.inline.max.delta.commits”来改变。
由于摄取和压缩都在相同的spark context运行,您可以使用DeltaStreamer CLI中的资源分配配置,例如(“--delta-sync-scheduling-weight”、“--compact-scheduling-weight”、“--delta-sync-scheduling-minshare”和“--compact-scheduling-minshare”)来控制摄取和压缩之间的执行器分配。
下面是一个示例调用,以连续模式从kafka主题读取并写入yarn集群中的Merge On Read表类型。
spark-submit --packages org.apache.hudi:hudi-utilities-bundle_2.11:0.13.1 \
--master yarn \
--deploy-mode cluster \
--num-executors 10 \
--executor-memory 3g \
--driver-memory 6g \
--conf spark.driver.extraJavaOptions="-XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/varadarb_ds_driver.hprof" \
--conf spark.executor.extraJavaOptions="-XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/varadarb_ds_executor.hprof" \
--queue hadoop-platform-queue \
--conf spark.scheduler.mode=FAIR \
--conf spark.yarn.executor.memoryOverhead=1072 \
--conf spark.yarn.driver.memoryOverhead=2048 \
--conf spark.task.cpus=1 \
--conf spark.executor.cores=1 \
--conf spark.task.maxFailures=10 \
--conf spark.memory.fraction=0.4 \
--conf spark.rdd.compress=true \
--conf spark.kryoserializer.buffer.max=200m \
--conf spark.serializer=org.apache.spark.serializer.KryoSerializer \
--conf spark.memory.storageFraction=0.1 \
--conf spark.shuffle.service.enabled=true \
--conf spark.sql.hive.convertMetastoreParquet=false \
--conf spark.ui.port=5555 \
--conf spark.driver.maxResultSize=3g \
--conf spark.executor.heartbeatInterval=120s \
--conf spark.network.timeout=600s \
--conf spark.eventLog.overwrite=true \
--conf spark.eventLog.enabled=true \
--conf spark.eventLog.dir=hdfs:///user/spark/applicationHistory \
--conf spark.yarn.max.executor.failures=10 \
--conf spark.sql.catalogImplementation=hive \
--conf spark.sql.shuffle.partitions=100 \
--driver-class-path $HADOOP_CONF_DIR \
--class org.apache.hudi.utilities.deltastreamer.HoodieDeltaStreamer \
--table-type MERGE_ON_READ \
--source-class org.apache.hudi.utilities.sources.JsonKafkaSource \
--source-ordering-field ts \
--target-base-path /user/hive/warehouse/stock_ticks_mor \
--target-table stock_ticks_mor \
--props /var/demo/config/kafka-source.properties \
--schemaprovider-class org.apache.hudi.utilities.schema.FilebasedSchemaProvider \
--continuous
Spark Datasource写的任务
如写数据中所述,可以使用spark数据源将数据摄取到hudi表中。该机制允许您以Hudi格式摄取任何spark数据框架。Hudi Spark DataSource还支持Spark streaming,以将流源摄取到Hudi表中。对于Merge On Read表类型,默认情况下会打开内联压缩,在每次摄取后运行。压缩频率可以通过设置属性“hoodie.compact.inline.max.delta.commits”来改变。
下面是一个使用spark数据源的调用示例
inputDF.write()
.format("org.apache.hudi")
.options(clientOpts) // any of the Hudi client opts can be passed in as well
.option(DataSourceWriteOptions.RECORDKEY_FIELD_OPT_KEY(), "_row_key")
.option(DataSourceWriteOptions.PARTITIONPATH_FIELD_OPT_KEY(), "partition")
.option(DataSourceWriteOptions.PRECOMBINE_FIELD_OPT_KEY(), "timestamp")
.option(HoodieWriteConfig.TABLE_NAME, tableName)
.mode(SaveMode.Append)
.save(basePath);