Spark Sql 转换成Task执行 和 InsertIntoHiveTable写入hive表数据 源码分析

Spark SQL转Task执行与InsertIntoHiveTable源码解析
本文深入探讨了Spark SQL如何将逻辑计划和物理计划转化为Task执行,特别是在InsertIntoHiveTable操作中,详细阐述了Task如何将数据写入Hive表的过程,包括创建临时目录、数据写入.staging目录,以及最终提交数据到Hive表的元数据更新。

1.3.1 InsertIntoHiveTable类源码解析

1.3.1.1 背景

请添加图片描述

读取数据,经过处理后,最终写入 hive表,这里研究下写入原理。抛出如下几个问题?

1、task处理完数据后,如何将数据放到表的location目录下?

2、这类写入表的task,是如何从spark sql 逻辑计划/物理计划 转化成 task启动的?

1.3.1.2 spark sql 逻辑计划/物理计划 如何转化成 task(回答问题2)

driver端 调试日志如下(定位InsertIntoHiveTable物理执行算子的run方法):

run:84, InsertIntoHiveTable (org.apache.spark.sql.hive.execution)
sideEffectResult$lzycompute:108, DataWritingCommandExec (org.apache.spark.sql.execution.command)
sideEffectResult:106, DataWritingCommandExec (org.apache.spark.sql.execution.command)
executeCollect:120, DataWritingCommandExec (org.apache.spark.sql.execution.command)  -- 物理执行计划触发执行
$anonfun$logicalPlan$1:229, Dataset (org.apache.spark.sql)    -----org.apache.spark.sql.Dataset#logicalPlan 
apply:-1, 76482793 (org.apache.spark.sql.Dataset$$Lambda$1656)
$anonfun$withAction$1:3618, Dataset (org.apache.spark.sql)
apply:-1, 277117675 (org.apache.spark.sql.Dataset$$Lambda$1657)
$anonfun$withNewExecutionId$5:100, SQLExecution$ (org.apache.spark.sql.execution)
apply:-1, 1668179857 (org.apache.spark.sql.execution.SQLExecution$$$Lambda$1665)
withSQLConfPropagated:160, SQLExecution$ (org.apache.spark.sql.execution)
$anonfun$withNewExecutionId$1:87, SQLExecution$ (org.apache.spark.sql.execution)
apply:-1, 216687255 (org.apache.spark.sql.execution.SQLExecution$$$Lambda$1658)
withActive:764, SparkSession (org.apache.spark.sql)
withNewExecutionId:64, SQLExecution$ (org.apache.spark.sql.execution)
withAction:3616, Dataset (org.apache.spark.sql)
<init>:229, Dataset (org.apache.spark.sql)
$anonfun$ofRows$2:100, Dataset$ (org.apache.spark.sql)  --- org.apache.spark.sql.Dataset#ofRows
apply:-1, 2116006444 (org.apache.spark.sql.Dataset$$$Lambda$925)
withActive:764, SparkSession (org.apache.spark.sql)
ofRows:97, Dataset$ (org.apache.spark.sql)
$anonfu
### Execute InsertIntoHiveTable 的作用 在 Spark SQL UI 中,`Execute InsertIntoHiveTable` 是一个关键操作,Spark 正在执行数据写入 Hive 的操作。该操作通常出现在使用 `DataFrameWriter` 的 `insertInto` 或 `saveAsTable` 方法时,或是在 SQL 语句中使用 `INSERT INTO` 或 `INSERT OVERWRITE` 语句将数据写入 Hive 的场景中 [^1]。 当 Spark SQL 任务执行到 `Execute InsertIntoHiveTable` 阶段时,它会将计算引擎生成的数据按照 Hive 的格式写入指定的存储系统(如 HDFS、S3 等)。此阶段涉及数据的序列化、分区写入、文件格式转换(如 Parquet、ORC、Text 等)以及元数据更新等操作 [^2]。 在 Spark SQL UI 中,`Execute InsertIntoHiveTable` 通常出现在 **DAG Visualization** 或 **Job/Stage 页面**中,用于标识写入 Hive 的具体执行阶段。该操作可能包含多个任务(Task),每个任务负责写入一部分数据到目标 Hive 的对应分区中。 以下是一个典型的写入 Hive 的代码示例: ```scala val df = spark.read.parquet("input_path") df.write .mode("overwrite") .partitionBy("dt", "hour") .saveAsTable("hive_table_name") ``` 在此示例中,Spark 会生成一个 `Execute InsertIntoHiveTable` 操作,负责将数据以分区方式写入 Hive ,并根据 `mode("overwrite")` 的设定决定是否覆盖已有数据 [^2]。 ### Execute InsertIntoHiveTable 的性能影响因素 在执行 `Execute InsertIntoHiveTable` 操作时,性能可能受到以下几个因素的影响: 1. **数据倾斜**:如果某些分区的数据量远大于其他分区,可能导致部分任务执行时间过长,从而影响整体写入性能。 2. **小文件问题**:每个任务写入多个小文件会增加文件系统的元数据负担,降低后续查询效率。可以通过调整 `spark.sql.files.maxPartitionBytes` 来控制每个任务写入的文件大小 [^1]。 3. **并发写入控制**:通过 `spark.sql.shuffle.partitions` 控制写入阶段的并行度,从而影响任务数量文件数量。 4. **文件格式与压缩**:Parquet、ORC 等列式存储格式在写入时会进行压缩编码优化,可能会影响写入速度最终文件大小 [^2]。 ### Execute InsertIntoHiveTable 的监控建议 在 Spark SQL UI 中,应重点关注以下指标来评估 `Execute InsertIntoHiveTable` 的执行情况: - **Task Duration**:查看各任务的执行时间是否均衡,是否存在长尾任务。 - **Write Files**:每个任务写入的文件数量,过多的小文件可能示需要进行分区合并。 - **Shuffle Read/Write**:如果写入前涉及 Shuffle 操作,需关注 Shuffle 数据量是否合理。 - **GC Time**:长时间的垃圾回收可能会影响写入性能,需优化内存配置。 ### 示例监控截图(模拟) 在 Spark SQL UI 的 **Stage 页面**中,`Execute InsertIntoHiveTable` 的信息可能如下所示: ```text Stage ID: 123 Description: Execute InsertIntoHiveTable Submitted: 2024-04-05 10:00:00 Completed: 2024-04-05 10:05:30 Duration: 5 mins 30 secs Number of Tasks: 200 Completed Tasks: 200 Write Files: 1500 (total) Shuffle Write: 50 GB ``` 上述信息明该阶段共写入了 1500 个文件,总 Shuffle 写入量为 50GB,任务执行时间较长,可能需要优化分区策略或调整并行度 。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值