sparksession 读取文件_Spark-读取数据-源码解析

博客探讨了Spark使用SparkSession的load方法读取HDFS上数据的源码过程,特别是针对大量碎片文件可能导致的OOM问题。通过解析DataSource类和HadoopFsRelation的生成,揭示了数据加载背后的逻辑,同时指出在文件碎片严重时可能带来的内存挑战。文章还提及了如何从BaseRelation转换为DataFrame的过程,并建议通过增加资源或预处理文件来避免性能问题。
摘要由CSDN通过智能技术生成

f380e8c2fff4b8688a5b3e0dfc75c0cf.png

知乎排版不好,也可以去简书看:Spark load() 源码解析

问题描述

在使用spark读取HDFS上的数据时,经常使用load的方式(没有hive的情况下)

spark.read.schema(schema).load(data_path)

以前比较常见的是textFile读HDFS的方式,不同于此,load的方式可以直接形成DataFrame,使用上更方便一些。遇到的一个问题是在读取的目录下非常多的碎片文件时,1.load地方为什么单独形成了一个job?2.文件过多时直接OOM程序停止。

在网上能搜到的比较类似的问题:

Spark read.parquet takes too much time

出于好奇,让我们看看load的源码 (2.3.1)

源码追踪

load方法

首先点进load方法,发现是spark sql的包(org.apache.spark.sql)

 /**
   * Loads input in as a `DataFrame`, for data sources that support multiple paths.
   * Only works if the source is a HadoopFsRelationProvider.
   *
   * @since 1.6.0
   */
  @scala.annotation.varargs
  def load(paths: String*): DataFrame = {
    sparkSession.baseRelationToDataFrame(
      DataSource.apply(
        sparkSession,
        paths = paths,
        userSpecifiedSchema = userSpecifiedSchema,
        className = source,
        options = extraOptions.toMap).resolveRelation())
  }
```

入参是目录,可以是多个,返回值是DataFrame。主要是调用了sparkSession.baseRelationToDataFrame
我们看一下这个baseRelationToDataFrame
```scala
  /**
   * Convert a `BaseRelation` created for external data sources into a `DataFrame`.
   *
   * @since 2.0.0
   */
  def baseRelationToDataFrame(baseRelation: BaseRelation): DataFrame = {
    Dataset.ofRows(self, LogicalRelation(baseRelation))
  }

这个方法是使用一个BaseRelation来得到DataFrame。在load方法里,我们传入的就是一个BaseRelation的子类。那我们看看究竟传入了什么样的BaseRelation。

DataSource类

在load函数里,通过DataSource伴生类调用apply方法获取一个DataSource实例,然后使用resolveRelation()方法返回的BaseRelation,看来关键在这个DataSource类

对于这个类,网上也有一些他人的分享:

利用 Spark DataSource API 实现Rest数据源
Spark Data Source API: Extending Our Spark SQL Query Engine

这个类在spark读取数据部分十分重要,有接近一千行代码。

我们这里只看其中一小部分。

首先看一下传入伴生类的参数:

       //sparkSes
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值