7. Spark SQL

1.1 出现原因

SparkSQL出现是因为关系数据库已经不能满足各种在大数据时代新增的用户需求。首先,用户需要在不同的结构化和非结构化数据中执行各种操作。其次,用户需要执行像机器学习和图像处理等等高级分析,在实际应用中,也经常需要融合关系查询和分析复杂算法。而SparkSQL正好可以弥补这个缺陷。

1.2 起源与发展

Spark SQL 是 Spark 用于结构化数据(structured data)处理的 Spark 模块。

SparkSQL的前身是Shark,给熟悉RDBMS但又不理解MapReduce的技术人员提供快速上手的工具,hive应运而生,它是当时唯一运行在Hadoop上的SQL-on-hadoop工具。但是MapReduce计算过程中大量的中间磁盘落地过程消耗了大量的I/O,降低的运行效率,为了提高SQL-on-Hadoop的效率,Shark应运而生,但又因为Shark对于Hive的太多依赖(如采用Hive的语法解析器、查询优化器等等),2014年spark团队停止对Shark的开发,发展出了两个分支:SparkSQL 和 Hive on Spark,将所有资源放SparkSQL项目上。

SparkSQL抛弃原有 Shark 的代码,汲取了 Shark 的一些优点,如内存列存储(In-Memory Columnar Storage)、Hive兼容性等,重新开发了SparkSQL代码;由于摆脱了对Hive的依赖性,SparkSQL无论在数据兼容、性能优化、组件扩展方面都得到了极大的方便。

其中 SparkSQL 作为 Spark 生态的一员继续发展,而不再受限于 Hive,只是兼容 Hive;而Hive on Spark 是一个 Hive 的发展计划,该计划将 Spark 作为 Hive 的底层引擎之一,也就是说,Hive 将不再受限于一个引擎,可以采用 Map-Reduce、Tez、Spark 等引擎。

2. 简述RDD 和DataFrame的联系与区别?

2.1 联系

  • 都是spark平台下的分布式弹性数据集,为处理超大型数据提供便利
  • 都有惰性机制,在进行创建、转换,如map方法时,不会立即执行,只有在遇到Action如foreach时,才会开始遍历运算
  • 都会根据spark的内存情况自动缓存运算,这样即使数据量很大,也不用担心会内存溢出
  • 都有partition的概念
  • 有许多共同的函数,如filter,排序等

2.2 区别

RDD

  • RDD一般和spark mlib同时使用
  • RDD不支持sparksql操作

DataFrame

  • DataFrame 与 DataSet 一般不与 spark mllib 同时使用。
  • 与 RDD 和 Dataset 不同,DataFrame 每一行的类型固定为 Row,每一列的值没法直接访问,只有通过解析才能获取各个字段的值。
  • DataFrame 与 DataSet 均支持 SparkSQL 的操作,比如 select,groupby 之类,还能注册临时表/视窗,进行 sql 语句操作。
  • DataFrame 与 DataSet 支持一些特别方便的保存方式,比如保存成 csv,可以带上表头,这样每一列的字段名一目了然。

3. DataFrame的创建与保存

3.1 PySpark-DataFrame创建:

  • spark.read.text(url)

txt1

  • spark.read.json(url)

json1

  • spark.read.format("text").load("people.txt")
    txt2

  • spark.read.format("json").load("people.json")

json2

  • 描述从不同文件类型生成DataFrame的区别。

    text文件生成的DataFrame只有value属性;json文件生成的DataFrame会识别到文件中的键值

  • 用相同的txt或json文件,同时创建RDD,比较RDD与DataFrame的区别。

RDD与DataFrame

3.2 DataFrame的保存

可以使用spark.write操作,把一个DataFrame保存成不同格式的文件,把一个名称为df的DataFrame保存到不同格式文件中,最终会生成一个xxx的目录,不是文件,里面可能会有多个文件和一个SUCESS,如下:

  • df.write.text(dir)

df_txt1

  • df.write.json(dir)

df_json1

  • df.write.format("text").save(dir)
    df_txt2

  • df.write.format("json").save(dir)
    df_json2

4. 选择题

4.1 单选(2分)‍关于Shark,下面描述正确的是:C

  A. Shark提供了类似Pig的功能

  B. Shark把SQL语句转换成MapReduce作业

  C. Shark重用了Hive中的HiveQL解析、逻辑执行计划翻译、执行计划优化等逻辑

  D. Shark的性能比Hive差很多

4.2 单选(2分)‏下面关于Spark SQL架构的描述错误的是:B

  A. 在Shark原有的架构上重写了逻辑执行计划的优化部分,解决了Shark存在的问题

  B. Spark SQL在Hive兼容层面仅依赖HiveQL解析和Hive元数据

  C. Spark SQL执行计划生成和优化都由Catalyst(函数式关系查询优化框架)负责

  D. Spark SQL执行计划生成和优化需要依赖Hive来完成

4.3 单选(2分)‌要把一个DataFrame保存到people.json文件中,下面语句哪个是正确的:A

  A. df.write.json("people.json")

  B. df.json("people.json")

  C. df.write.format("csv").save("people.json")

  D. df.write.csv("people.json")

4.4 多选(3分)‎Shark的设计导致了两个问题:AC

  A. 执行计划优化完全依赖于Hive,不方便添加新的优化策略

  B. 执行计划优化不依赖于Hive,方便添加新的优化策略

  C. Spark是线程级并行,而MapReduce是进程级并行,因此,Spark在兼容Hive的实现上存在线程安全问题,导致Shark不得不使用另外一套独立维护的、打了补丁的Hive源码分支

  D. Spark是进程级并行,而MapReduce是线程级并行,因此,Spark在兼容Hive的实现上存在线程安全问题,导致Shark不得不使用另外一套独立维护的、打了补丁的Hive源码分支

4.5 多选(3分)‌下面关于为什么推出Spark SQL的原因的描述正确的是:AB

  A. Spark SQL可以提供DataFrame API,可以对内部和外部各种数据源执行各种关系操作

  B. 可以支持大量的数据源和数据分析算法,组合使用Spark SQL和Spark MLlib,可以融合传统关系数据库的结构化数据管理能力和机器学习算法的数据处理能力

  C. Spark SQL无法对各种不同的数据源进行整合

  D. Spark SQL无法融合结构化数据管理能力和机器学习算法的数据处理能力

4.6 多选(3分)‌下面关于DataFrame的描述正确的是:ABCD

  A. DataFrame的推出,让Spark具备了处理大规模结构化数据的能力

  B. DataFrame比原有的RDD转化方式更加简单易用,而且获得了更高的计算性能

  C. Spark能够轻松实现从MySQL到DataFrame的转化,并且支持SQL查询

  D. DataFrame是一种以RDD为基础的分布式数据集,提供了详细的结构信息

4.7 多选(3分)‏要读取people.json文件生成DataFrame,可以使用下面哪些命令:AC

  A. spark.read.json("people.json")

  B. spark.read.parquet("people.json")

  C. spark.read.format("json").load("people.json")

  D. spark.read.format("csv").load("people.json")

5. PySpark-DataFrame各种常用操作

5.1 基于df的操作:

  • 打印数据 df.show()默认打印前20条数据
    打印数据

  • 打印概要 df.printSchema()
    打印概要

  • 查询总行数 df.count()
    查询总行数

  • df.head(3) #list类型,list中每个元素是Row类
    df.head

  • 输出全部行 df.collect() #list类型,list中每个元素是Row类

    输出全部行

  • 查询概况 df.describe().show()

    查询概况

  • 取列 df[‘name’], df.name, df[1]
    取列

  • 选择 df.select() 每个人的年龄+1
    年龄+1

  • 筛选 df.filter() 20岁以上的人员信息

    20岁以上

  • 筛选年龄为空的人员信息

    年龄为空

  • 分组df.groupBy() 统计每个年龄的人数
    groupBy()

  • 排序df.sort() 按年龄进行排序
    df.sort()

5.2 基于spark.sql的操作:

  • 创建临时表虚拟表 df.registerTempTable('people')
    创建临时表虚拟表

  • spark.sql执行SQL语句 spark.sql('select name from people').show()
    执行SQL语句

5.3 pyspark中DataFrame与pandas中DataFrame

  • 分别从文件创建两种DataFrame

    pyspark的DataFrame

    pandas中DataFrame

  • 查看两种df的区别

    (1) 地址写法不同

    (2) pyspark的df要通过操作查看结果

    (3) pandas的df自动加索引

  • pandas中DataFrame转换为Pyspark中DataFrame

    pd转pyspark

  • Pyspark中DataFrame转换为pandas中DataFrame

    pyspark转pd

6.从RDD转换得到DataFrame

6.1 利用反射机制推断RDD模式

  • 创建RDD sc.textFile(url).map(),读文件,分割数据项

    读文件,分割数据项

  • 每个RDD元素转换成 Row

    RDD元素转换成 Row

  • 由Row-RDD转换到DataFrame

    Row-RDD转换到DataFrame

6.2 使用编程方式定义RDD模式

  • 下面生成“表头”

    复制代码
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    SHELL
    >>> from pyspark.sql import Row
    >>> from pyspark.sql.types import *
    >>> 
    >>> schemaString = 'name age'
    >>> fields = [StructField(field_name,StringType(),True) for field_name in schemaString.split(' ')]
    >>> schema = StructType(fields)
    

    生成“表头”

  • 下面生成“表中的记录”

    • 创建RDD
    • 转换成Row元素,列名=值
    复制代码
     
    • 1
    • 2
    • 3
    • 4
    SHELL
    >>> lines = spark.sparkContext.textFile('file:///home/zt/people.txt')
    >>> part = lines.map(lambda w:w.split(","))
    >>> peoples = part.map(lambda p:Row(p[0],p[1].strip()))
    >>> peoples.collect()
    

    生成“表中的记录”

  • 下面把“表头”和“表中的记录”拼装在一起

    复制代码
     
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    SHELL
    >>> schemaPeople = spark.createDataFrame(people,schema)
    >>> schemaPeople.show()
    +-------+---+
    |   name|age|
    +-------+---+
    |Michael| 29|
    |   Andy| 30|
    | Justin| 19|
    +-------+---+
    
    >>> schemaPeople.printSchema()
    root
     |-- name: string (nullable = true)
     |-- age: string (nullable = true)
    

    拼装在一起

7. 选择题

7.1 单选(2分) 以下操作中,哪个不是DataFrame的常用操作:D

  A.printSchema()

  B.select()

  C.filter()

  D.sendto()

7.2 多选(3分)‏ 从RDD转换得到DataFrame包含两种典型方法,分别是:AB

  A.利用反射机制推断RDD模式

  B.使用编程方式定义RDD模式

  C.利用投影机制推断RDD模式

  D.利用互联机制推断RDD模式

7.3 多选(3分)‍ 使用编程方式定义RDD模式时,主要包括哪三个步骤:ABC

  A.制作“表头”

  B.制作“表中的记录”

  C.制作映射表

  D.把“表头”和“表中的记录”拼装在一起

 

 
 
posted @ 2022-05-11 21:14  林小林--  阅读(174)  评论(0编辑  收藏  举报