Spark SQL

Spark SQL【Java API】 Spark SQL 【Java API】 阅读详情

一、SQL on Hadoop

SQL是一种传统的用来进行数据分析的标准

  • Hive:原始的SQL-on-Hadoop解决方案
  • Impala:和Hive一样,提供了一种可以针对已有Hadoop数据编写SQL查询的方法
  • Presto:类似于Impala,未被主要供应商支持
  • Shark:Spark SQL的前身,设计目标是作为Hive的补充
  • Phoenix:基于HBase的开源SQL查询引擎

二、Spark SQL

Spark SQL的前身

Shark是spark sql的前身,它的设计初衷是让Hive运行在Spark上,其是对Hive的改造,但是继承了大量Hive代码,给优化和维护带来了大量的麻烦
在这里插入图片描述

Spark SQL架构

  • Spark SQL是Spark的核心组件之一 - 能够直接访问现存的Hive数据
  • 提供JDBC/ODBC接口供第三方工具借助Spark进行数据处理
  • 提供了更高层级的接口方便地处理数据
  • 支持多种操作方式:SQL、API编程
  • 支持多种外部数据源:Parquet、JSON、RDBMS等

在这里插入图片描述

Spark SQL运行原理

Spark sql执行计划的生成过程

  • ①接收 sql 语句,初步解析成 logical plan
  • ②上步生成的 logical plan,生成验证后的 logical plan
  • ③对分析过后的 logical plan,进行优化
  • ④对优化过后的 logical plan,生成 physical plan
  • ⑤根据 physical plan,生成 rdd 的程序,并且提交运行
    在这里插入图片描述

Catalyst优化器

在Spark SQL执行计划中,②③④过程被称为Catalyst

  • Catalyst优化器是Spark SQL的核心
  • Catalyst优化器将逻辑计划转为物理计划

逻辑计划

以执行下段代码为例

select name from
(
	select id,name from student
) as s
where s.id=1

该段代码的逻辑执行计划如图
在这里插入图片描述

优化

  • 1、在投影上面查询过滤器
  • 2、检查过滤是否可下
    经上述优化,会将执行计划修改
    在这里插入图片描述

物理计划

优化后生成物理计划
在这里插入图片描述

二、Spark SQL API

SparkSession

  • SparkSession合并了SQLContext(Spark SQL的编程入口)与HiveContext(SQLContext的子集,包含更多功能)
  • Spark SQL所有功能入口点,,并允许使用DataFrame和Dataset API对Spark进行编程
  • 在spark-shell下,会自动创建将sc(SparkContext)和spark(SparkSession)
// API获取SparkSession
val spark = SparkSession.builder
	.master("local[*]")  // 设置模式,local为本地模式
	.appName("appName")  // 设置appName
	.getOrCreate()       // 获取或创建SparkSession对象

DataSet

DataSet是特定域对象中的强类型集合

  • createDataSet()创建DataSet对象,参数可以Seq、Array、RDD
// Seq做参数
spark.createDataset(1 to 3).show  // 类型为DataSet[Int]
// Array做参数
spark.createDataset(List(("a",1),("b",2),("c",3))).show  // 类型为DataSet[(String,Int)]
// RDD做参数
spark.createDataset(sc.parallelize(List(("a",1,1),("b",2,2)))).show // 类型为DataSet[(String,Int,Int)]
  • 使用样例类(case class 创建Dataset)
case class Student(id:Int,name:String,sex:String,age:Int)
object InnerFunctionDemo2 {
  def main(args: Array[String]): Unit = {
  	// 获取SparkSession
    val spark: SparkSession = SparkSession.builder()
      .appName("innerFunc")
      .master("local[*]")
      .getOrCreate()
    //此包用于隐式转换,如将RDDs转换为DataFrame。
    import spark.implicits._
    val stuDS: Dataset[Student] = Seq(
      Student(1001, "zhangsan", "F", 20),
      Student(1002, "lisi", "M", 16),
      Student(1003, "wangwu", "M", 21)
    ).toDS()
    stuDS.show()
}

在这里插入图片描述

DataFrame

  • 当Dataset的类型为Row时,就是DataFrame,可以理解为DataFrame=Dataset[Row]
  • 在RDD基础上加入了Schema(数据结构信息)
  • DataFrame Schema支持嵌套数据类型:struct、map、Array

RDD与DataFrame对比

Student的属性为Name、Age、Height
在这里插入图片描述

创建DataFrame的方式

  • 从Spark数据源进行创建
// 读取csv文件
// option("header","true")的作用将文件首行作为表头
val df: DataFrame = spark.read.option("header","true").csv("in/users.csv")

// 读取json文件
val df2: DataFrame = spark.read.json("in/users.json")

在这里插入图片描述

  • 从RDD转换成DataFrame
    ① 方式一:rdd类型转换成样例类,通过toDF方法转换成DataFrame
case class Person(name:String,age:Int)
// people.txt的内容格式为:zhangsan,21
import spark.implicits._
val df = sc.textFile("in/people.txt")
  .map(x => x.split(",")) // 以逗号分割
  .map(x => Person(x(0), x(1).toInt)) // 转换成Person样例类类型
  .toDF() // 转换成DataFrame
df.printSchema()
df.show()

在这里插入图片描述
② Row类型的RDD+Schema

import org.apache.spark.sql.Row
import org.apache.spark.sql.types.StructType
import org.apache.spark.sql.types.StructField
import org.apache.spark.sql.types.StringType
import org.apache.spark.sql.types._

val people = sc.textFile("in/people.txt")
// 字段名称
val schemaString = "name age"
// 为每个字段设置类型
val schema = StructType(schemaString.split(" ")
  .map(fieldName =>{
	if (fieldName.equals("name"))
	  StructField(fieldName, StringType, true)
	else
	  StructField(fieldName, IntegerType, true)
   })
)
// 将Rdd类型转为Row类型
val rowRDD = people.map(_.split(",")).map(x=>Row(x(0),x(1).toInt))
// 创建DataFrame
val peopleDataFrame = spark.createDataFrame(rowRDD,schema)

peopleDataFrame.printSchema()
peopleDataFrame.show()

在这里插入图片描述
从DataFrame转成RDD只需要用.rdd方法即可

三、Spark SQL操作外部数据源

Spark SQL支持的外部数据源

Spark SQL支持很多数据源,如常用的JSON、CSV、Hive、RDBMS等
在这里插入图片描述

使用常用数据源方式

在DataSet中json、csv的格式的文件读取已经演示,这里就不在赘述

  • Parquet文件
    ①写parquet文件
// 获取SparkSession对象
val spark: SparkSession = SparkSession.builder()
	.master("local[*]")
 	.appName("perDemo")
 	.getOrCreate()
// 获取SparkContext对象
val sc:SparkContext = spark.sparkContext
import spark.implicits._
val list = List(
  ("zhangsan", "red", Array(3, 4, 5)),
  ("lisi", "black", Array(13, 14, 15)),
  ("wangwu", "orange", Array(23, 24, 25)),
  ("zhaoliu", "red", Array(33, 34, 35))
)
// 获取RDD
val rdd1: RDD[(String, String, Array[Int])] = sc.parallelize(list)
// 定义数据的结构
val schema = StructType(
  Array(
    StructField("name", StringType),
    StructField("color", StringType),
    StructField("numbers", ArrayType(IntegerType))
  )
)
// 将RDD转为Row类型
val rowRDD: RDD[Row] = rdd1.map(x=>Row(x._1,x._2,x._3))
val df: DataFrame = spark.createDataFrame(rowRDD,schema)
df.show
// 写parquet文件
df.write.parquet("out/color")

在这里插入图片描述
②读parquet文件

val df: DataFrame = spark.read.parquet("out/color")
df.printSchema()
df.show()

在这里插入图片描述

连接Hive表

① 在idea中,Spark SQL连接Hive

  • 开启hive的元数据服务
    命令:nohup hive --service metastore &
  • 添加maven依赖
<dependency>
  <groupId>org.apache.spark</groupId>
  <artifactId>spark-hive_2.11</artifactId>
  <version>2.1.1</version>
</dependency>
  • 连接hive
val spark: SparkSession = SparkSession.builder()
   .master("local[*]")
   .appName("sparksqlOnHiveDemo")
   .config("hive.metastore.uris","thrift://192.168.233.133:9083") // 配置远程连接的metastore的uri
   .enableHiveSupport()
   .getOrCreate()
spark.sql("show databases").collect.foreach(println)

// 可以对hive中的表进行操作
val df: DataFrame = spark.sql("select * from toronto")
df.show()

在这里插入图片描述
在这里插入图片描述
注意:默认连接的时候Hive Default库,若需要使用其他库中的表,可以用库名.表名的形式

② spark-shell环境下连接Hive

  • 修改Hive的conf目录下的hive-site.xml文件
    添加如下内容
<property>
  <name>hive.metastore.uris</name>
  <value>thrift://192.168.233.133:9083</value>
</property>
  • 拷贝hive-site.xml文件到spark的conf目录下
    命令:cp /opt/hive/conf/hive-site.xml /opt/spark/conf/
  • 进入spark-shell命令行,集成了hive后可直接访问Hive表
scala> val df=spark.table("toronto")
scala> df.show

在这里插入图片描述

连接RDBMS(关系型数据库管理系统)

以mysql为例
①在idea中,Spark SQL连接mysql

  • 添加maven依赖
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.38</version>
</dependency>
  • 连接mysql
val spark: SparkSession = SparkSession.builder()
	.master("local[*]")
	.appName("sqlDemo")
	.getOrCreate()
// mysql驱动
val driver = "com.mysql.jdbc.Driver"
// mysql地址
val url = "jdbc:mysql://192.168.233.133:3306/information_schema"
// 登录用户名
val user = "root"
// 登录密码
val password = "root"
// 配置
val prop = new Properties()
prop.setProperty("user",user)
prop.setProperty("password",password)
prop.setProperty("driver",driver)
// 连接mysql,第二个参数为要连接的表名
val df: DataFrame = spark.read.jdbc(url,"SCHEMATA",prop)
df.printSchema()

在这里插入图片描述
②在spark-shell下连接mysql

  • 添加mysql的jar包到spark的jars路径下
  • 进入spark-shell命令行
scala> val url="jdbc:mysql://192.168.233.133:3306/hive"
scala> val tbname="TBLS"
scala> val prop = new java.util.Properties
scala> prop.setProperty("username","root")
scala> prop.setProperty("password","root")
scala> prop.setProperty("driver","com.mysql.jdbc.Driver")
scala> val jdbcDF= spark.read.jdbc(url,tbname,prop)
scala> jdbcDF.printSchema

在这里插入图片描述
在这里插入图片描述

Spark SQL函数

内置函数

Spark SQL提供了许多内置函数,可以参考这位博主的博文:Spark SQL 函数全集
使用内置函数的方式有两种,一种是通过编程的方式的使用,另一种是通过SQL的方式使用

  • 编程式使用
// 使用内置函数需要导入此包
import org.apache.spark.sql.functions._
// scoreTableDF根据sid分组,count用于计算结果,选出count=2的
scoreTableDF.groupBy("sid").count().where("count=2").show()
  • 通过SQL的方式
scoreTableDF.createOrReplaceTempView("score")
studentTableDF.createOrReplaceTempView("student")
spark.sql("select sid,count(1) from score group by sid having count(1)=2).show()

自定义函数

除了内置函数,Spark SQL中还可以使用自定义函数,详细内容可以参照这篇博客:Spark SQL 中的UDF、UDAF、UDTF

Spark性能优化

  • 序列化
    Spark默认使用的是Java的序列化
    正确使用Kryo序列化,比Java序列化快约10倍,但不支持所有可序列化类型
conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer");
//向Kryo注册自定义类型
conf.registerKryoClasses(Array(classOf[MyClass1], classOf[MyClass2]));

如果没有注册需要序列化的class,Kyro依然可以照常工作,但会存储每个对象的全类名(full class name),这样往往比默认的 Java serialization 更浪费空间

  • 使用对象数组、原始类型代替Java、Scala集合类(如HashMap)
    避免嵌套结构
  • 尽量使用数字作为Key,而非字符串
  • 以较大的RDD使用MEMORY_ONLY_SER
  • 加载CSV、JSON时,仅加载所需字段
  • 仅在需要时持久化中间结果(RDD/DS/DF)
  • 避免不必要的中间结果(RDD/DS/DF)的生成
  • DF的执行速度比DS快约3倍
  • 自定义RDD分区与spark.default.parallelism
    该参数用于设置每个stage的默认task数量
  • 将小变量广播出去,而不是直接使用
  • 尝试处理本地数据并最小化跨工作节点的数据传输
  • 表连接(join操作)
    最大的表放在第一位
    广播最小的表
    最小化表join的数量
Spark SQL及实例 什么是Spark SQLSpark SQL是Apache Spark用于处理结构化数据的模块。Spark SQL允许使用SQL或熟悉的DataFrame API查询Spark程序内的结构化数据。Spark SQL支持多语言编程包括Java、Scala、Python和R,可以根据自身喜好进行选择。本文中所涉及的Spark SQL代码示例均使用python语言。Spark SQL的核心-DataFram 阅读详情

相关推荐

Spark SQL基础

Spark SQL基础介绍

qq_50215015的博客 1521

Spark读写csv(带表头)

1.读csv文件 //2.x后也内置了csv的解析器,也可以简单滴使用csv(), val df=spark.read.format("csv").option("header", "true").option("mode", "DROPMALFORMED").csv("csv/file/path") //全参数解析 val spark = SparkSession.builder().appNa...

老五是个机器人 1万+

Spark SQL 详解

基于上述的两点,从 Spark 1.6 开始出现 DataSet,作为 DataFrame API 的一个扩展,是一个强类型的特定领域的对象,这种对象可以函数式或者关系操作并行地转换,结合了 RDD 和 DataFrame 的优点,至 Spark 2.0 中将 DataFrame 与 DataSet 合并。Spark SQL 的核心是一个叫做 Catalyst 的查询编译器,它将用户程序中的 SQL/DataFrame/Dataset 经过一系列的操作,最终转化为 Spark 系统中执行的 RDD。

zh_19995的博客 999

spark读取csv文件

spark读取csv文件,如果用textFile直接读取也可以,但是对于后续的操作不太方便。所以要采用sqlContext来读取csv文件 在shell中直接使用sqlContext 时会报错,所以启动时要添加依赖包 ./spark-shell --packages com.databricks:spark-csv_2.10:1.3.0 这样就直接进入了shell,然后加载hdfs上的csv

Silence的博客 6026

Hive on Spark and Spark sql on Hive

结构上Hive On Spark和SparkSQL都是一个翻译层,把一个SQL翻译成分布式可执行的Spark程序。Hive和SparkSQL都不负责计算。Hive的默认执行引擎是mr,还可以运行在Spark和Tez。Spark可以连接多种数据源,然后使用SparkSQL来执行分布式计算。Hive On Spark 配置1、首先安装包要选择对,否则就没有开始了。Hive版本:apache-hive-...

代灿灿灿的博客 3226

Spark SQL和Spark Streaming简介

1. Spark SQL 用于处理结构化数据,提供SQL语句查询的API接口 SparkSQL数据类型DataFrames 这种数据类型支持结构化的数据文件,Hive中的表,外部数据库和已存在的RDD 该接口在Python, R, Java, Scala中都是可用的 SparkSQL数据类型DataSets Spark 1.6中添加的新接口 不支持Python ...

学习笔记 3057

spark读取、保存.csv文件、并指定编码格式

一、用spark实现读取csv文件 核心代码: val spark = SparkSession .builder() .master("local[*]") .appName("app") .getOrCreate() //读取文件 //方式一: val srcDF = spark .r

qq_56870570的博客 1万+

【Hive进阶】-- Hive SQL、Spark SQL和 Hive on Spark SQL

Hive由Facebook开发,用于解决海量结构化日志的数据统计,于2008年贡献给 Apache 基金会。Hive是基于Hadoop的数据仓库工具,可以将结构化数据映射为一张表,提供类似SQL语句查询功能本质:将Hive SQL转化成MapReduce程序。Spark SQL主要用于结构型数据处理,它的前身为Shark,在Spark 1.3.0版本后才成长为正式版,可以彻底摆脱之前Shark必须依赖HIVE的局面。

欢迎来到我的博客,一起探索代码里的世界! 3930

spark读取csv文件——scala

spark读取csv文件——scala 下面介绍如何通过scala读取csv文件 读取的过程是首先按照普通额文本文件进行读取,然后通过opencsv的jar包进行转换,通过对每行进行读取,生成string数组。 好,下面上货。 import java.io.StringReader import au.com.bytecode.opencsv.CSVReader object CC{

archer的技术故事 2万+

信捷XD/XL系列PLC与C#通信实战:Modbus-RTU协议详解(附完整代码)

本文详细介绍了信捷XD/XL系列PLC与C#通过Modbus-RTU协议实现高效通信的实战指南。从硬件连接到软件配置,再到核心通信功能的实现与优化,提供了完整的代码示例和工业级应用建议,帮助开发者快速构建稳定的自动化通信系统。

weixin_28292761的博客 511

半导体设备上位机开发:我的经验与新人指导

半导体设备上位机开发是一项复杂而富有挑战性的工作,需要扎实的技术基础和丰富的经验。如果你对半导体设备上位机开发感兴趣,欢迎随时与我交流,我会尽力帮助你!

qq_43518667的博客 2734

spark 读取CSV文件

1. spark 读取CSV文件;可以直接使用DataBricks的第三方包来读取CSV文件,下载第三方包后放入指定路径 1.1 定义数据格式 导入数据之前我们需要按照具体的数据格式定义数据格式 采用StructType定义字段格式,与数据集中的各个字段一一对应。 // StructField 中的的三个参数分别为字段名称、字段数据类型和是否不允许为空。 val fie

haozhangyn的专栏 1万+

2022年电赛F题23年电赛D题-信号调制度测量装置说明中提到带通采样定律。

另外,当对于一个频率很高的射频信号采样时,如果采样频率设的太低,对提高采样量化的信噪比是不利的。低通采样定理在《信号与系统》教材中进行了详细的讨论,但未对带通信号的采样定理进行描述,国内樊昌信和曹丽娜老师编写的《通信原理》第10章第2小节有所描述,但没有详细的公式推导,容易给初学者产生超过该最低采样频率即不会产生频谱混叠的假象。故采样频率没选好,就会使周期性频谱搬移过程中造成频谱混叠,既然频谱和原信号的频谱对不上了,故就无法无失真恢复原信号了,总之,频域波形不出现重叠是无失真传输的重要保障。

qq_64919823的博客 2183

Spark-SQL

但是,随着 Spark 的发展,对于野心勃勃的 Spark 团队来说,Shark 对于 Hive 的太多依 赖(如采用 Hive 的语法解析器、查询优化器等等),制约了 Spark 的 One Stack Rule Them All 的既定方针,制约了 Spark 各个组件的相互集成,所以提出了 SparkSQL 项目。从 API 易用性的角度上看,DataFrame API 提供的是一套高层的关系操作,比函数式的 RDD API 要 更加友好,门槛更低。如果是数字,默认作为 Int 处理;

2501_90677971的博客 2231

Yolov2 训练时anchor是如何使用的?build_target

0.简略描述 1.将真值检测框变换到特征图尺度上 2.计算以特征图每个网格中心为中心点时所有锚框与真值检测框的交并比 3.取与真值检测框交并比最大的锚框的id,及真值检测框中心所在cell的id,有此,可将真值检测框与预测结果对应起来 4.计算位置回归损失,置信度损失,分类损失 1,网络的输出 图1 yolov2 网络对于检测框位置大小的输出是: 对于1个batch网络的输出的shape为[batch_size, H*W*num_anchors, 5+num_classes], 其中: num_

机器人视觉感知 2818

国科大——形式语言与自动机理论(0812课程)——作业

此次作业题考察,包括但不限于有限自动机、无限自动机、正则文法、正则表达式以及正则语言的性质,题考查下推自动机相关的知识,题考查图灵机相关的知识。此课程建议本科学习过课程的同学选修,成绩占比:考试100%。此课程虽然留有作业,但可做也可不做,且不考勤。

qq_54145399的博客 706

Spark编程基础及Spark SQL

/ 创建 Spark 运行配置对象// 创建 Spark 上下文环境对象(连接对象)//通过内存创建RDD。

iqizum的博客 1697

GStreamer 源代码入门

GStreamer 是一个高度模块化的多媒体框架,其源代码结构清晰,设计精良。

深之JohnChen的专栏 954

Spark DataFrame、Spark SQL、Spark Streaming入门教程

文章目录前言1、RDD、Spark DataFrame、Spark SQL、Spark Streaming2、Spark DataFrame2.1 创建基本的Spark DataFrame2.2 从各类数据源创建Spark DataFrame2.3 Spark DataFrame持久化数据2.4 Dataframe常见的API3、Spark SQL4、Spark Streaming实时计算TCP...

pysense的博客 2345

C#与欧姆龙PLC 通信——fins udp协议

该调试助手专门为了帮助大家学习以及测试Fins-Udp通信,下面进行详细介绍。

qq_34059233的博客 2876

【Windows Server 2019】存储服务器的配置和管理——iSCSI的安装和配置(下)

博文介绍了如何使用Windows 10 和 ESXi 验证iSCSI服务器部署成功以及如何管理iSCSI服务 。

VMware, Windows, Linux, Cisco, Container, Kubernetes, Kali 8002

浅谈spark sql、hive on spark、spark on hive

主要讨论spark sql、hive on spark、spark on hive的区别

ergouy's blog 1170

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Spark SQL特点

Spark SQL特点 1.Spark SQL概念 Spark SQL是Spark用来处理结构化数据的一个模块,它提供了一个编程抽象叫做DataFrame并且作为分布式SQL查询引擎的作用。 相比于Spark RDD API,Spark SQL包含了对结构化数据和在其上运算的更多信息,Spark SQL使用这些信息进行了额外的优化,使对结构化数据的操作更加高效和方便。 有多种方式去使用...

Running_Tiger的博客 3083

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Spark SQL 的SQL处理引擎分析

目录 一.补充以Sql Server 为例,SQL语句的执行逻辑顺序 1、From阶段 2、Where 阶段 3、Group By 4、Having 5、Select 6、Order By 7、SQL 流程示意图 二:Sqlparser:sql –> unresolved logical plan 三:Analyzer:Unresolved logical plan...

威少(微笑) 1459

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

上一篇: Spark SQL 中的UDF、UDAF、UDTF
下一篇: Spark SQL解析json文件
简单不过l
博客等级 码龄8年 15粉丝 78原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值