• SparkSQL---简介及RDD V.S DataFrame V.S Dataset编程模型详解


    一、SparkSQL简介

    SparkSQL,就是Spark生态体系中的构建在SparkCore基础之上的一个基于SQL的计算模块。SparkSQL的前身不叫SparkSQL,而叫Shark,最开始的时候底层代码优化,sql的解析、执行引擎等等完全基于Hive,总之Shark的执行速度要比hive高出一个数量级,但是hive的发展制约了Shark,所以在15年中旬的时候,shark负责人,将shark项目结束掉,重新独立出来的一个项目,就是sparksql,不再依赖hive,做了独立的发展,逐渐的形成两条互相独立的业务:SparkSQL和Hive-On-Spark。在SparkSQL发展过程中,同时也吸收了Shark有些的特点:基于内存的列存储,动态字节码优化技术。

    二、SparkSQL特点

    1、强大的整合能力
    可以在spark程序中混合SQL查询操作
    2、统一的数据访问接口
    使得sparksql可以非常便捷的进行数据访问操作
    3、可以读写hive中的数据
    对于hive的强大支持,是sparksql重要的能力之一
    4、提供了支持JDBC/ODBC
    为了方便一些BI组件的调用数据,使得对数据访问变得多元化,功能完整化
    总结:
    SparkSQL就是Spark生态体系中用于处理结构化数据的一个模块。换句话说,SparkSQL处理的就是二维表数据。
    ①结构化数据是什么?存储在关系型数据库中的数据,就是结构化数据;
    ②半结构化数据是什么?类似xml、json等的格式的数据被称之为半结构化数据;
    ③非结构化数据是什么?音频、视频、图片等为非结构化数据。

    三、SparkSQL编程入口和模型

    1、SparkSQL编程入口

    在SparkSQL中的编程模型,不再是SparkContext,但是创建需要依赖SparkContext。SparkSQL中的编程模型,在spark2.0以前的版本中为SQLContext和HiveContext,HiveContext是SQLContext的一个子类,提供Hive中特有的一些功能,比如row_number开窗函数等等,这是SQLContext所不具备的,在Spark2.0之后将这两个进行了合并——SparkSession。使用工厂构建器(Builder方式)模式创建SparkSession。

    	//创建sparkSql程序入口
        val spark = SparkSession.builder()
        .appName("sparksql")
        .master("local[*]")
        .enableHiveSupport()//开启hive支持,支持hive的相关操作
        .getOrCreate()
        //通过sparkSql程序入口调用SparkContext
        val sc = spark.sparkContext
        //设置日志级别
        sc.setLogLevel("WARN")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    2、SparkSQL编程模型

    主要通过两种方式操作SparkSQL,一种就是SQL,另一种为DataFrame和Dataset。
    people.json数据:
    {“name”:“json”,“age”:23,“hobby”:“running”}
    {“name”:“charles”,“age”:32,“hobby”:“basketball”}
    {“name”:“tom”,“age”:28,“hobby”:“football”}
    {“name”:“lili”,“age”:24,“hobby”:“running”}
    {“name”:“bob”,“age”:20,“hobby”:“swimming”}

    1、SQL
    就和Hive操作一样,但是需要清楚一点的是,SQL操作的是表,所以要想用SQL进行操作,就需要将SparkSQL对应的编程模型转化成为一张表才可以。同时支持,通用sql和hivesql。

     	//SQL风格
     	//加载数据
        val dataFrame = spark.read.json("F:\\test\\people.json")
        //想要使用SQL风格,必须将数据首先注册为一张表
        dataFrame.createOrReplaceTempView("person")
        //查询所有数据
        spark.sql("select * from person").show()
        //查询age和name,并将age+10岁
        spark.sql("select name,age+10 as age from  person").show()
        //查询name和age,只要age>30的
        val sql=
          """
            |select * from person where age>30
          """.stripMargin
        spark.sql(sql).show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2、DSL(DataFrame&DataSet)
    为方便大家使用函数式编程的思想,类似sparkcore的编程模式,sparksql也支持DSL(Domain Specified Language,领域专用语言,或者特定领域语言),即通过DataFrame和Dataset来支持类似RDD的编程。
    DataFrame和Dataset是SparkSQL中的编程模型。DataFrame和Dataset我们都可以理解为是一张mysql中的二维表,表有什么?表头,表名,字段,字段类型。RDD其实说白了也是一张二维表,但是这张二维表相比较于DataFrame和Dataset却少了很多东西,比如表头,表名,字段,字段类型,只有数据。
    一般的,将RDD称之为Spark体系中的第一代编程模型;DataFrame比RDD多了一个Schema元数据信息,被称之为Spark体系中的第二代编程模型;Dataset吸收了RDD的优点(强类型推断和强大的函数式编程)和DataFrame中的优化(SQL优化引擎,内存列存储),成为Spark的最新一代的编程模型。

    	//DSL风格(领域专用语言),就是通过dataFrame和Dataset来支持类似RDD的编程,调用函数
    	//加载数据
        val dataFrame = spark.read.json("F:\\test\\people.json")
        //查询name,hobby
        dataFrame.select("name","hobby").show()
        //需要导包
        import spark.implicits._
        //查询name和age,只要age>30岁的人
        dataFrame.select("name","age").filter($"age">30).show()
        //查询age,并将每个age+10岁
        dataFrame.select($"age",$"age"+10 as "age1").show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    3、RDD V.S DataFrame V.S Dataset

    1、RDD
    弹性分布式数据集,是Spark对数据进行的一种抽象,可以理解为Spark对数据的一种组织方式,更简单些说,RDD就是一种数据结构,里面包含了数据和操作数据的方法。
    RDD是Spark最底层的抽象,目前是开发者用的最多的,但逐步会转向DataFrame和Dataset(当然,这是Spark的发展趋势)调整。
    2、DataFrame
    DataFrame在RDD的基础上加了Schema(描述数据的信息,可以认为是元数据,DataFrame曾经就有个名字叫SchemaRDD)
    假设RDD中的两行数据长这样
    在这里插入图片描述
    那么DataFrame中的数据长这样
    在这里插入图片描述
    DataFrame比RDD多了一个表头信息(Schema),像一张表了,DataFrame还配套了新的操作数据的方法,DataFrame API(如df.select())和SQL(select id, name from xx_table where …)。
    通过DataFrame API或SQL处理数据,会自动经过Spark 优化器(Catalyst)的优化,即使你写的程序或SQL不高效,也可以运行的很快。
    3、Dataset
    Dataset提供了强类型支持,也是在RDD的每行数据加了类型约束
    假设RDD中的两行数据长这样
    在这里插入图片描述
    那么Dataset中的数据长这样
    在这里插入图片描述
    或者也可以是这样,其中每行数据是个Object
    在这里插入图片描述
    相比DataFrame,Dataset提供了编译时类型检查,对于分布式程序来讲,提交一次作业太费劲了(要编译、打包、上传、运行),到提交到集群运行时才发现错误,实在是不方便,这也是引入Dataset的一个重要原因。

  • 相关阅读:
    EfficientViT:高效视觉transformer与级联组注意力
    【书城项目】第三、四阶段--页面 jsp动态化、代码优化、EL修改表单
    达摩院年终预测出炉:2022 十大科技趋势,AI for Science 高居榜首
    wxpython 的sizer布局
    tensorflow学习笔记
    HTTPS基础概念
    springboot+vue高性能教学资源教材租借平台设计与实现
    【无标题】
    锐捷Ruijie交换机版本升级
    Android Ble蓝牙App(七)扫描过滤
  • 原文地址:https://blog.csdn.net/onthe_wing/article/details/138199844