spark复习笔记(二)——spark sql

14 篇文章 0 订阅
8 篇文章 0 订阅

Spark SQL特点
1、易整合
整合SQL查询和Spark编程
2、统一的数据访问方式
使用相同方式连接不同的数据源
3、继承Hive
在已有的仓库上直接运行SQL或者HQL
4、标准的连接方式
通过JDBC或者ODBC

DataFrame
分布式数据容器
schema 数据的结构信息(类似于desc table)
支持嵌套数据类型 struct array map

从API易用性,DataFrame API提供的是一套高层的关系操作,比函数式的RDD API要更加友好门槛更低

DataFrame懒执行,性能上比RDD高,原因:
优化的执行计划:
查询计划通过Spark catalyst optimiser进行优化

逻辑查询计划优化利用基于关系代数的等价变换,将高成本的操作替换为低成本操作的过程

DataSet(1.6 新增)
1、DataFrame API的扩展
2、友好的API风格
3、DataSet支持编解码器
4、样例类定义数据结构信息,映射到DataSet中的字段名称
5、DataFrame是DataSet的特列
6、DataFrame是强类型

Spark SQL编程
老版本中,SparkSQL查询起点是SQLContext
    连接Hive的查询启动是HiveContext

2.0开始,SparkSession是Spark最新的SQL查询启动,实质是SQLContext和HiveContext,内部封装了SparkContext

DataFrame进行编程
创建DataFrame
1、通过Spark的数据源创建
val df = spark.read.json("../*.json")
2、通过已知的RDD来创建
3、通过查询一个Hive表创建

查看schema信息
df.printSchema

DataFrame语法风格
SQL语法风格(主要)
    查询数据的时候使用SQL语句来查询
    spark.sql("select * from people").show
DSL语法风格
    提供一个特定领域语言区管理结构化的数据
    df.select("name","age").show

RDD和DataFrame的交互
涉及到RDD、DataFrame、DataSet之间的操作,
需要导入import spark.implicts._
这里spark不是包名,而是表示SparkSession的对象
所以必须先创建SparkSession对象再导入,implicits是一个内部object

手动转换
rdd.toDF("name","age").show
样例类反射转换
case class People(name:String,age:Int)
样例把RDD转换成DataFrame
rdd.toDF.show

构建SparkSession
val spark: SparkSession = SparkSession.builder()
            .master("local[*]")
            .appName("Word Count")
            .getOrCreate()
val sc: SparkContext = spark.sparkContext

映射RDD
val rowRdd:RDD[Row] = rdd.map(x=>Row(x._1,x._2))
创建StructType类型
val types = StructType(
    Array(
        StructField("name",StringType),
        StructField("age",IntegerType)    
        )
)
创建DataFrame
val df:DataFrame = spark.createDataFrame(rowRdd,types)
显示
df.show

从DataFrame到RDD
rdd = df.rdd
得到的RDD中存储的数据类型是Row

DataSet编程
DataSet没有使用Java序列化或者Kryo序列化,而是使用一种专门的编码器区序列化对象,然后在网络上处理或者传输

编码器和标准序列化负责将对象转换成字节

创建DataSet
1、使用样例类的序列化
    case class Person(name:String,age:Int)
    为样例类创建编码器
    val ds = Seq(
        Person("lisi",20),
        Person("zs",21)
    ).toDS
    ds.show

2、使用基本类型的序列化
import spark.implicits._
val ds = Seq(1,2,3,4,5).toDS
ds.show

3、在实际使用的时候,更多的是通过RDD得到DataSet

RDD和DataSet的交互
1、从RDD到DataSet
使用反射来推断包含特定类型对象的RDD的schema
rdd.toDS
2、从DataSet到RDD
ds.rdd

DataFrame和DataSet交互
case class Person(name:String,age:Long)
1、DataFrame转换成DataSet
df.as[People]
2、DataSet转DataFrame
ds.toDF


RDD、DataFrame、DataSet之间的关系
版本
RDD (Spark1.0) —> Dataframe(Spark1.3) —> Dataset(Spark1.6)

三者的共性
1.    RDD、DataFrame、Dataset全都是 Spark 平台下的分布式弹性数据集,为处理超大型数据提供便利
2.    三者都有惰性机制,在进行创建、转换,如map方法时,不会立即执行,只有在遇到Action如foreach时,三者才会开始遍历运算。
3.    三者都会根据 Spark 的内存情况自动缓存运算,这样即使数据量很大,也不用担心会内存溢出
4.    三者都有partition的概念
5.    三者有许多共同的函数,如map, filter,排序等
6.    在对 DataFrame和Dataset进行操作许多操作都需要这个包进行支持 import spark.implicits._
7.    DataFrame和Dataset均可使用模式匹配获取各个字段的值和类型


使用IDEA创建SparkSQL程序
添加SparkSQL依赖
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-sql_2.11</artifactId>
    <version>2.1.1</version>
</dependency>


自定义SparkSQL函数
在shell窗口中可以通过spark.udf功能用户可以自定义函数
//注册一个udf函数
//toUpper是函数名,第二个参数是函数的具体实现
spark.udf.register("toUpper",(s:String)=>s.toUpperCase)

用户自定义聚合函数
1、继承UserDefinedAggregateFunction
    Object MyAvg extends UserDefinedAggregateFunction
2、注册自定义函数
    spark.udf.register("myAvg",new MyAvg)

SparkSQL数据源

通用加载和保存函数
默认的数据源是parquet
spark.sql.sources.default设置默认的数据源

val usersDF = spark
.read.load("examples/src/main/resources/users.parquet")
usersDF.select("name", "favorite_color")
.write.save("namesAndFavColors.parquet")


spark.read.load是加载数据的通用做法
df.write.save是保存数据的通用方法

手动指定选项
val peopleDF = spark
.read.format("json")
.load("examples/src/main/resources/people.json")
peopleDF.select("name","age")
.write.format("parquet")
.save("namesAndAges.parquet")


在文件上直接运行SQL
spark.sql("select * from json")

加载json文件
SparkSession.read.format("json").load()

读取Parquet文件
Parquet 是一种流行的列式存储格式,
可以高效地存储具有嵌套字段的记录。

从jdbc读数据
val jdbcDF = spark.read
    .format("jdbc")
    .option("url", "jdbc:mysql://hadoop201:3306/rdd")
    .option("user", "root")
    .option("password", "aaa")
    .option("dbtable", "user")
    .load()

Hive数据库

使用外置的Hive
1.Spark 要接管 Hive 需要把 hive-site.xml copy 到conf/目录下.
2.把 Mysql 的驱动 copy 到 jars/目录下.
3.如果访问不到hdfs, 则需要把core-site.xml和hdfs-site.xml 拷贝到conf/目录下.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

罗少说

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值