Spark之SparkSQL

本文详细介绍了SparkSQL的基础概念,包括DataFrame和DataSet的区别与联系,展示了如何在Spark中高效地处理结构化数据,以及自定义函数和数据读写操作。重点讲解了RDD到DataFrame和DataSet的转换,以及UDF和UDAF的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是SparkSQL

        SparkSQL是Spark用于结构化数据处理的模块

SparkSQL的原理

SparkSQL提供了两个编程抽象,DataFrame和DataSet

 DataFrame

 1)DataFrame是一种类似RDD的分布式数据集,类似于传统数据库中的二维表格。

        2)DataFrame与RDD的主要区别在于,DataFrame带有schema元信息,即DataFrame所表示的二维表数据集的每一列都带有名称和类型。

 

  注意: Spark SQL性能上比RDD要高。因为Spark SQL了解数据内部结构,从而对藏于DataFrame背后的数据源以及作用于DataFrame之上的变换进行了针对性的优化,最终达到大幅提升运行时效率的目标。反观RDD,由于无从得知所存数据元素的具体内部结构,Spark Core只能在Stage层面进行简单、通用的流水线优化。

DataSet

        1.DataSet是分布式数据集。

       2. DataSet是强类型的。比如可以有DataSet[Car],DataSet[User]。具有类型安全检查

        3.DataFrame是DataSet的特例,type DataFrame = DataSet[Row] ,Row是一个类型,跟Car、User这些的类型一样,所有的表结构信息都用Row来表示。

Rdd、Dataframe、DataSet的关系

(1)RDD、DataFrame、DataSet全都是Spark平台下的分布式弹性数据集,为处理超大型数据提供便利

(2)三者都有惰性机制,在进行创建、转换,如map方法时,不会立即执行,只有在遇到Action行动算子如foreach时,三者才会开始遍历运算

(3)三者有许多共同的函数,如filter,排序等

(4)三者都会根据Spark的内存情况自动缓存运算

(5)三者都有分区的概念

三者转换图:

//注意:在做转换之前,一定要导入隐式转换
    import spark.implicits._
    //RDD=>DF
    //普通RDD转换DF,需要手动补充列名
    val df01: DataFrame = dataRDD.toDF("name","age")
    //样例类RDD=>DF,自动会把样例类的属性名,作为列名
    val df: DataFrame = caseRDD.toDF()
    df01.show()
    df.show()
 
    //DF => RDD
    //DF转RDD,直接.rdd即可,但是需要注意的是DF不会保留原始数据的类型,类型统统为ROW
    val rdd01: RDD[Row] = df.rdd
    val res: RDD[User] = rdd01.map(
      row => {
        User(row.getString(0), row.getLong(1))
      }
    )
    //res.collect().foreach(println)
    //RDD=>DS
    val ds01: Dataset[(String, Long)] = dataRDD.toDS()
    val ds02: Dataset[User] = caseRDD.toDS()
    ds01.show()
    ds02.show()
    //DS => RDD
    val ds2rdd: RDD[User] = ds02.rdd
    val ds2rdd02: RDD[(String, Long)] = ds01.rdd
 
    ds2rdd.collect().foreach(println)
 
    val df2df: DataFrame = df.toDF("name2","age2")
    df2df.show()
 
    val df2ds: Dataset[User] = df2df.as[User]
    df2ds.show()
    //DS=>DF
    val ds2df: DataFrame = df2ds.toDF("name","age")
    ds2df.show()

 

自定义函数

UDF 一进一出

 val df: DataFrame = spark.read.json("E:\\bigdata_study\\sparkSQL\\input\\user.json")
    //创建DataFrame临时视图
    df.createTempView("user")
 
    spark.udf.register("addname",(name:String)=>{"Name:" + name})
    spark.udf.register("double",(age:Long)=>{"double:" + age * 2})
    spark.sql("select addName(name),double(age) from user").show

UDAF 输入多行,返回一行


//特定加载
val df01: DataFrame = spark.read.json("E:\\bigdata_study\\sparkSQL\\input\\user.json")
val df02: DataFrame = spark.read.csv("E:\\bigdata_study\\sparkSQL\\input\\user.txt")
 
//通用加载
val df03: DataFrame = spark.read.load("E:\\bigdata_study\\sparkSQL\\input\\user.json")

写出数据

   //特定
df.write.json("E:\\bigdata_study\\sparkSQL\\input\\out01")
df.write.csv("E:\\bigdata_study\\sparkSQL\\input\\out02")
    /**
      * 写出模式
      * 1.默认模式 存在即报错  如果目录不存在,正常写出;如果目录存在,报错!
      * 2.追加模式 追加写出   如果目录不存在,正常写出;如果目录存在,追加写出!
      * 3.覆盖模式 覆盖写出   如果目录不存在,正常写出;如果目录存在,删除该目录,重新创建同名目录,写出
      * 4.忽略模式 忽略写出   如果目录不存在,正常写出;如果目录存在,忽略本次操作,不报错! (慎用)
      */
//通用
df.write.mode(SaveMode.Ignore).save("E:\\bigdata_study\\sparkSQL\\input\\out02")

 

### 比较 Hive on SparkSparkSQL #### 区别 Hive on Spark 是一种允许 Hive 使用 Spark 作为其执行引擎的方式,而不是默认的 MapReduce 执行引擎。这种方式使得 Hive 可以利用 Spark 更高效的内存管理和并行处理机制来提升查询性能[^1]。 另一方面,SparkSQL 提供了一个更全面的数据处理框架,它不仅能够读取和写入 Hive 表,还可以支持多种其他数据源,并提供了丰富的 API 来操作结构化数据。此外,SparkSQL 还引入了自己的优化器 Catalyst,这有助于进一步提高查询效率[^2]。 #### 性能差异 当涉及到性能方面时,在大多数情况下,由于 Spark 的内存计算特性,无论是 Hive on Spark 或者纯 SparkSQL 查询都比传统的基于 MapReduce 的 Hive 查询要快得多。然而,两者之间的相对表现取决于具体的使用案例: - 对于简单的 SQL 查询,如果这些查询可以直接映射到 HiveQL 而不需要额外的功能,则 Hive on Spark 可能会显示出更好的兼容性和相似甚至稍好的性能。 - 当涉及复杂分析任务或需要更多高级功能(如窗口函数、UDF 用户定义函数等),则 SparkSQL 往往表现出更强的能力,因为它拥有更加灵活且强大的API集合以及内置的支持[^3]。 #### 应用场景 选择哪一个解决方案应该依据实际需求考虑如下因素: - **现有基础设施**:如果你已经有了成熟的 Hive 生态环境并且希望最小化迁移成本,那么可以选择 Hive on Spark;反之,如果没有特别的历史包袱或者正在构建新的应用,则可以优先考虑 SparkSQL[^4]。 - **查询复杂度**:对于较为复杂的ETL流程或是数据分析工作负载来说,SparkSQL 凭借着更为先进的特性和更高的灵活性通常是更好的选项。 - **社区和支持**:考虑到长期维护和技术演进的角度出发,Apache Spark 社区非常活跃,这意味着 SparkSQL 将持续获得改进和发展,相比之下,虽然 Hive on Spark 同样得到了一定关注,但在某些特定领域内可能不如前者那样具有优势。 ```sql -- 示例 Hive on Spark 查询语句 SELECT * FROM table_name WHERE condition; -- 示例 SparkSQL 查询语句 spark.sql("SELECT * FROM table_name WHERE condition") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值