PySparkSQL 入门(概述、DataFrame操作)

#博学谷IT学习技术支持#

第一章 快速入门

1.1 什么是SparkSQL

SparkSQL 是Spark的一个模块, 用于处理海量结构化数据

第一、针对结构化数据处理,属于Spark框架一个部分

第二、抽象数据结构:DataFrame

DataFrame = RDD + Schema信息;

第三、分布式SQL引擎,类似Hive框架

从Hive框架继承而来,Hive中提供bin/hive交互式SQL命令行及HiveServer2服务,SparkSQL都可以;

Spark SQL模块架构示意图如下

备注:Catalog就是Spark 2.0之后提供的访问元数据的类:Catalog提供一些API用来对数据库、表、视图、缓存、列、函数(UDF/UDAF)进行操作

1.2 为什么要学习SparkSQL

由于MapReduce这种计算模型执行效率比较慢,rdd原生代码较为复杂,所以Spark SQL应运而生,它是将Spark SQL转换成RDD,然后提交到集群中去运行,执行效率非常快!(查看官网学习)

SparkSQL是非常成熟的 海量结构化数据处理框架.

学习SparkSQL主要在2个点:

  • SparkSQL本身十分优秀, 支持SQL语言\性能强\可以自动优化\API简单\兼容HIVE等等

  • 企业大面积在使用SparkSQL处理业务数据

  • 离线开发

  • 数仓搭建

  • 科学计算、数据分析

1.3 SparkSQL特点

1)用户接口:Client

CLI(command-line interface)、JDBC/ODBC(jdbc 访问 hive)、WEBUI(浏览器访问 hive)

2)元数据:Metastore

元数据包括:表名、表所属的数据库(默认是 default)、表的拥有者、列/分区字段、表的类型(是否是外部表)、表的数据所在目录等;

默认存储在自带的 derby 数据库中,推荐使用 MySQL 存储 Metastore

3)Hadoop

使用 HDFS 进行存储,使用 MapReduce 进行计算。

4)驱动器:Driver

5)解析器(SQL Parser)

将 SQL 字符串转换成抽象语法树 AST,这一步一般都用第三方工具库完成,比如 antlr;

对 AST 进行语法分析,比如表是否存在、字段是否存在、SQL 语义是否有误。

6)编译器(Physical Plan)

将 AST 编译生成逻辑执行计划。

7)优化器(Query Optimizer)

对逻辑执行计划进行优化。

8)执行器(Execution)

把逻辑执行计划转换成可以运行的物理计划。对于 Hive 来说,就是 MR/Spark。

1.4 SparkSQL发展历史

Hive架构回顾

HQL 转换为 MR 任务流程说明

1.进入程序,利用Antlr框架定义HQL的语法规则,对HQL完成词法语法解析,将HQL转换为为AST(抽象语法树);

2.遍历AST,抽象出查询的基本组成单元QueryBlock(查询块),可以理解为最小的查询执行单元;

3.遍历QueryBlock,将其转换为OperatorTree(操作树,也就是逻辑执行计划),可以理解为不可拆分的一个逻辑执行单元;

4.使用逻辑优化器对OperatorTree(操作树)进行逻辑优化。例如合并不必要的ReduceSinkOperator,减少Shuffle数据量;

5.遍历OperatorTree,转换为TaskTree。也就是翻译为MR任务的流程,将逻辑执行计划转换为物理执行计划;

6.使用物理优化器对TaskTree进行物理优化;

7.生成最终的执行计划,提交任务到Hadoop集群运行。

Hive

可以发现Hive框架底层就是MapReduce,所以在Hive中执行SQL时,往往很慢很慢

Spark出现以后,将HiveQL语句翻译成基于RDD操作,此时Shark框架诞生了。

- 前身 Shark框架

Shark即Hive on Spark,本质上是通过Hive的HQL进行解析,把HQL翻译成Spark上对应的RDD操作,然后通过Hive的Metadata获取数据库里表的信息,实际为HDFS上的数据和文件,最后有Shark获取并放到Spark上计算。

但是Shark框架更多是对Hive的改造,替换了Hive的物理执行引擎,使之有一个较快的处理速度。然而不容忽视的是Shark继承了大量的Hive代码,因此给优化和维护带来大量的麻烦。为了更好的发展,Databricks在2014年7月1日Spark Summit上宣布终止对Shark的开发,将重点放到SparkSQL模块上。

SparkSQL模块主要将以前依赖Hive框架代码实现的功能自己实现,称为Catalyst引擎。

第二章 SparkSQL概述

2.1 SparkSQL和Hive的异同

  • Hive和Spark 均是:“分布式SQL计算引擎”

  • 均是构建大规模结构化数据计算的绝佳利器,同时SparkSQL拥有更好的性能。

  • 目前,企业中使用Hive仍旧居多,但SparkSQL将会在很近的未来替代Hive成为分布式SQL计算市场的顶级

2.2 SparkSQL的数据抽象

回顾Pandas和SparkSQL的数据抽象

Pandas - DataFrame

  • 二维表数据结构

  • 单机(本地)集合

SparkCore - RDD

  • 无标准数据结构,存储什么数据均可

  • 分布式集合(分区)

  • Pandas - DataFrame

  • •二维表数据结构

  • •单机(本地)集合

  • SparkCore - RDD

  • •无标准数据结构,存储什么数据均可

  • •分布式集合(分区)

  • SparkSQL - DataFrame

  • •二维表数据结构

  • •分布式集合(分区)

SparkSQL 其实有3类数据抽象对象

  • SchemaRDD对象(已废弃)

  • DataSet对象:可用于Java、Scala语言

  • DataFrame对象:可用于Java、Scala、Python、R

我们以Python开发SparkSQL,主要使用的就是DataFrame对象作为核心数据结构

在SparkSQL当中,Spark为我们提供了两个操作SparkSQL的抽象,分别是DataFrame和DataSet。也就是说我们操作SparkSQL一般都是使用DataFrame或者DataSet来实现的

RDD(Spark1.0) ==> DataFrame(1.3) ==> DataSet(1.6)

2.3 SparkSQL数据抽象的发展

RDD

  • RDD是一个懒执行的不可变的可以支持Lambda表达式的并行数据集合。

  • RDD的最大好处就是简单,API的人性化程度很高。

  • RDD的劣势是性能限制,它是一个JVM驻内存对象,这也就决定了存在GC的限制和数据增加时Java序列化成本的升高。

DataFrame

  • 什么是DataFrame

DataFrame的前身是SchemaRDD,从Spark 1.3.0开始SchemaRDD更名为DataFrame。并不再直接继承自RDD,而是自己实现了RDD的绝大多数功能。

DataFrame是一种以RDD为基础的分布式数据集,类似于传统数据库的二维表格,带有Schema元信息(可以理解为数据库的列名和类型)

  • 总结:

DataFrame ==> RDD - 泛型 + Schema + 方便的SQL操作 + 优化

DataFrame是特殊的RDD

DataFrame是一个分布式的表

RDD、DataFrame、DataSet的区别

  • RDD[Person]

  • 以Person为类型参数,但不了解 其内部结构。

  • DataFrame

  • DataFrame = RDD[Person] - 泛型 + Schema + SQL操作 + 优化

  • 提供了详细的结构信息schema列的名称和类型。这样看起来就像一张表了

  • DataSet[Person]

  • DataFrame = RDD[Person] - 泛型 + Schema + SQL操作 + 优化

  • 不光有schema信息,还有类型信息

注意:DataFrame = DataSet[Row]

2.4 SparkSession 应用入口 SparkSession对象

在RDD阶段,程序的执行入口对象是: SparkContext

在Spark 2.0后,推出了SparkSession对象,作为Spark编码的统一入口对象。

SparkSession对象可以:

  • l- 用于SparkSQL编程作为入口对象

  • l- 用于SparkCore编程,可以通过SparkSession对象中获取到SparkContext

所以,我们后续的代码,执行环境入口对象,统一变更为SparkSession对象

SparkSession:这是一个新入口,取代了原本的SQLContext与HiveContext。对于DataFrame API的用户来说,Spark常见的混乱源头来自于使用哪个“context”。现在使用SparkSession,它作为单个入口可以兼容两者,注意原本的SQLContext与HiveContext仍然保留,以支持向下兼容。

文档:

http://spark.apache.org/docs/latest/sql-getting-started.html

1)、SparkSession在SparkSQL模块中

2)、SparkSession对象实例通过建造者模式构建

SparkSession实现了SQLContext及HiveContext所有功能。SparkSession支持从不同的数据源加载数据,并把数据转换成DataFrame,并且支持把DataFrame转换成SQLContext自身中的表,然后使用SQL语句来操作数据。SparkSession亦提供了HiveQL以及其他依赖于Hive的功能的支持。

其中①表示导入SparkSession所在的包,②表示建造者模式构建对象和设置属性

构建SparkSession核心代码

 
# coding:utf8

# SparkSQL 中的入口对象是SparkSession对象
from pyspark.sql import SparkSession


if __name__ == '__main__':
    # 构建SparkSession对象, 这个对象是 构建器模式 通过builder方法来构建
    spark = SparkSession.builder.\
        appName("local[*]").\
        config("spark.sql.shuffle.partitions", "4").\
        getOrCreate()
    # appName 设置程序名称, config设置一些常用属性
    # 最后通过getOrCreate()方法 创建SparkSession对象
 
from pyspark.sql import SparkSession
from pyspark.sql import Row
import os
os.environ['SPARK_HOME'] = '/export/servers/spark'
PYSPARK_PYTHON = "/root/anaconda3/envs/pyspark_env/bin/python"
# 当存在多个版本时,不指定很可能会导致出错
os.environ["PYSPARK_PYTHON"] = PYSPARK_PYTHON
os.environ["PYSPARK_DRIVER_PYTHON"] = PYSPARK_PYTHON

if __name__ == '__main__':
    # TODO: 构建SparkSession实例对象,读取数据
    # 设置应用名称和运行模式
    # 通过装饰模式获取实例对象,此种方式为线程安全的
    spark = SparkSession.builder\
        .appName('test')\
        .getOrCreate()
    sc = spark.sparkContext
    # spark.conf.set("spark.sql.shuffle.partitions", 6)
    # TODO: 2. 从文件系统读取数据,包含本地文件系统或HDFS文件系统
    inputDS = spark.read.text("file:///export/pyfolder1/pyspark-chapter03_3.8/data/word.txt")
    print(type(inputDS))
    print("Count={}".format(inputDS.count()))
    inputDS.show()
    spark.stop()

第三章 DataFrame入门和操作

3.1 DataFrame概述

DataFrame和RDD都是:弹性的、分布式的、数据集

只是,DataFrame存储的数据结构“限定”为:二维表结构化数据

而RDD可以存储的数据则没有任何限制,想处理什么就处理什么

DataFrame 是按照二维表格的形式存储数据

RDD则是存储对象本身

3.2 DataFrame初体验

 
范例演示:加载json格式数据
第一步、上传官方测试数据$SPARK_HOME/examples/src/main/resources至HDFS目录/datas
第二步、启动pyspark-shell命令行,采用本地模式localmode运行
第三步、读取雇员信息数据

3.3 Schema 信息详解

查看DataFrame中Schema是什么,执行如下命令:

可以看出Schema信息封装在StructType中,包含很多StructField对象,查看源码。

其一、StructType 定义,是一个样例类,属性为StructField的数组

其二、StructField 定义,同样是一个样例类,有四个属性,其中字段名称和类型为必填

自定义Schema结构,官方提供实例代码:

3.4 Row对象

DataFrame中每条数据封装在Row中,Row表示每行数据,具体哪些字段位置,获取DataFrame中第一条数据。

如何构建Row对象:传递value即可,官方实例代码:

from pyspark.sql import Row
// Create a Row from values.
Row(value1, value2, value3, ...)

如何获取Row中每个字段的值呢?

下标获取,从0开始,类似数组下标获取

Row对象构建Dataframe部分代码演示

peopleDF.filter((peopleDF.age >= 19) & (peopleDF.age <= 28)).show()
peopleDF.filter("age>= 19  and age <=28").show()
# 尝试一下操作
from pyspark.sql.functions import col, when
peopleDF.withColumn("little",when((col("age") >= 19) & (col("age") <= 28),1).otherwise(0)).show()
peopleDF.select("age",(when((peopleDF["age"]>=19)& (peopleDF["age"]<=28),1).otherwise(0)).alias("xxx")).show()
  
if __name__ == '__main__':
    spark = SparkSession.builder \
        .appName('test') \
        .getOrCreate()
    sc = spark.sparkContext
    # Load a text file and convert each line to a Row.
    # 读取一个文件转化每一行为Row对象
    lines = sc.textFile("file:///export/pyfolder1/pyspark-chapter03_3.8/data/sql/people.txt")
    parts = lines.map(lambda l: l.split(","))
    people = parts.map(lambda p: Row(name=p[0], age=int(p[1])))
    # 推断Schema,并且将DataFrame注册为Table
    schemaPeople = spark.createDataFrame(people)
    schemaPeople.createOrReplaceTempView("people")
    # SQL 可以在已注册为表的 DataFrame 上运行。
    teenagers = spark.sql("SELECT name FROM people WHERE age >= 13 AND age <= 19")
    teenNames = teenagers.rdd.map(lambda p: "Name: " + p.name).collect()
    for name in teenNames:
        print(name)# Name: Justin
    spark.stop()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值