一, 简介

Spark SQL是用于结构化数据处理的Spark模块。与基本的Spark RDD API不同,Spark SQL提供的接口为Spark提供了关于数据结构和正在执行的计算的更多信息。在内部,Spark SQL使用这些额外的信息来执行额外的优化。有几种与Spark
SQL进行交互的方式,包括SQL和Dataset API。在计算结果时,使用相同的执行引擎,而不管使用哪种API /语言表示计算。这种统一意味着开发人员可以轻松地在不同的API之间来回切换,基于这些API提供了表达给定转换的最自然的方式。

Spark SQL的一个用途是执行SQL查询。Spark SQL也可以用来从现有的Hive安装中读取数据。从另一种编程语言中运行SQL时,结果将作为数据集/数据框返回。您还可以使用命令行 或通过JDBC / ODBC与SQL接口进行交互。

二, 数据集和数据框(Datasets and DataFrames)

数据集Datasets 是分布式数据集合。数据集Datasets 是Spark
1.6中添加的一个新接口,它提供了RDD(强类型,使用强大的lambda函数的功能)的好处以及Spark SQL优化执行引擎的优点。数据集可以被构造从JVM对象,然后使用功能性的转换操作(map,flatMap,filter等等)。数据集API可用于Scala和 Java。Python不支持数据集API。但是由于Python的动态特性,数据集API的许多优点已经可用(例如,您可以自然地通过名称访问行的字段 row.columnName)。R的情况类似。

      一个DataFrame是一个数据集组织成命名列。它在概念上等同于关系数据库中的表格或R / Python中的数据框架,但具有更丰富的优化。DataFrame可以从各种各样的源构建,例如:结构化数据文件,Hive中的表,外部数据库或现有的RDD。数据帧API是Scala,Java的,可用的Python和[R 。在Scala和Java中,DataFrame由Rows 的数据集表示。在Scala API中,DataFrame只是一个类型的别名Dataset[Row]。而在Java API中,用户需要Dataset<Row>用来表示一个DataFrame。

1,创建Spark Sql的入口

Spark中所有功能的入口点就是这个SparkSession类。要创建一个基本的SparkSession,只需使用SparkSession.builder():

import org.apache.spark.sql.SparkSession

val spark = SparkSession
.builder()
.appName("Spark SQL basic example")
.config("spark.some.config.option", "some-value")
.getOrCreate()
import spark.implicits._


  SparkSession在Spark
2.0中为Hive特性提供内置支持,包括使用HiveQL编写查询,访问Hive UDF以及从Hive表读取数据的能力。要使用这些功能,您不需要有现有的Hive安装程序。

2,创建数据框DataFrame

使用a SparkSession,应用程序可以从现有的RDD,Hive表或Spark数据源创建DataFrame 举个例子,下面根据JSON文件的内容创建一个DataFrame:

val df = spark.read.json("examples/src/main/resources/people.json")

// 显示数据框中的数据
df.show()
// +----+-------+
// | age| name|
// +----+-------+
// |null|Michael|
// | 30| Andy|
// | 19| Justin|
// +----+-------+

其中people.json中的数据为:

{"name":"Michael"}
{"name":"Andy", "age":30}
{"name":"Justin", "age":19}

3,无类型数据集Dataset操作(又名DataFrame操作) 

        DataFrames为Scala,Java,Python和R中的结构化数据操作提供了一个特定领域的语言。

        如上所述,在Spark 2.0中,DataFrames只是Row,Scala和Java API中的数据集。这些操作也被称为“无类型转换”,与强类型的Scala / Java数据集中的“类型转换”不同。这里我们包含一些使用数据集的结构化数据处理的基本示例:

 import spark.implicits._
// 以树形格式打印数据集的 Schema 格式
df.printSchema()
// root
// |-- age: long (nullable = true)
// |-- name: string (nullable = true) // 选择 name 的列数据
df.select("name").show()
// +-------+
// | name|
// +-------+
// |Michael|
// | Andy|
// | Justin|
// +-------+ // 选择所有的人,并且 age 加一,
df.select($"name", $"age" + 1).show()
// +-------+---------+
// | name|(age + 1)|
// +-------+---------+
// |Michael| null|
// | Andy| 31|
// | Justin| 20|
// +-------+---------+ // 选出年龄大于21的人信息
df.filter($"age" > 21).show()
// +---+----+
// |age|name|
// +---+----+
// | 30|Andy|
// +---+----+ // 通过年龄的升序排序,并计数每个人的数量
df.groupBy("age").count().show()
// +----+-----+
// | age|count|
// +----+-----+
// | 19| 1|
// |null| 1|
// | 30| 1|
// +----+-----+

有关可在数据集上执行的操作类型的完整列表,请参阅API文档

除了简单的列引用和表达式之外,数据集还具有丰富的函数库,包括字符串操作,日期算术,通用数学运算等等。DataFrame函数参考中提供了完整的列表。

4,以编程方式运行SQL查询

通过以上的例子利用sql函数,SparkSession使应用程序能够以编程方式运行SQL查询,并将结果返回为DataFrame。

    df.createOrReplaceTempView("people")  // 创建临时视图

    val sqlDF = spark.sql("SELECT * FROM people")
sqlDF.show()
// +----+-------+
// | age| name|
// +----+-------+
// |null|Michael|
// | 30| Andy|
// | 19| Justin|
// +----+-------+

5,全局临时视图

Spark SQL中的临时视图是会话范围的,如果创建它的会话终止,将会消失。如果您希望在所有会话之间共享一个临时视图并保持活动状态,直到Spark应用程序终止,则可以创建一个全局临时视图。全局临时视图与系统保存的数据库绑定global_temp,我们必须使用限定的名称来引用它,例如SELECT * FROM global_temp.view1。

   // 创建全局临时试图
df.createGlobalTempView("people") // 全局临时视图绑定到系统数据库中保存`global_temp` 
spark.sql("SELECT * FROM global_temp.people").show()
// +----+-------+
// | age| name|
// +----+-------+
// |null|Michael|
// | 30| Andy|
// | 19| Justin|
// +----+-------+ // 全局临时视图是跨会话的
spark.newSession().sql("SELECT * FROM global_temp.people").show()
// +----+-------+
// | age| name|
// +----+-------+
// |null|Michael|
// | 30| Andy|
// | 19| Justin|
// +----+-------+

6,创建数据集Dataset

      数据集类似于RDD,但是,不使用Java序列化或Kryo,而是使用专门的编码器对对象进行序列化以便通过网络进行处理或传输。虽然编码器和标准序列化都负责将对象转换为字节,但编码器是动态生成的代码,并且使用允许Spark执行许多操作(如过滤,排序和散列)的格式,而无需将字节反序列化回对象。

  case class Person(name: String, age: Long) // 强转类型
 import spark.implicits._
    // 自定义类//创建case类的编码器
    val caseClassDS = Seq(Person("Andy", 32)).toDS()
    caseClassDS.show()
    // +----+---+
    // |name|age|
    // +----+---+
    // |Andy| 32|
    // +----+---+     // 对于最常见的类型//编码器是通过导入spark.implicits._自动提供
    val primitiveDS = Seq(1, 2, 3).toDS()
    primitiveDS.map(_ + 1).collect() // Returns: Array(2, 3, 4)     //通过提供一个类可以将DataFrames转换为Dataset。映射将通过名称
    val path = "epeople.json"
    val peopleDS = spark.read.json(path).as[Person]
    peopleDS.show()
    // +----+-------+
    // | age|   name|
    // +----+-------+
    // |null|Michael|
    // |  30|   Andy|
    // |  19| Justin|
    // +----+-------+

7,与RDD进行互操作

       Spark SQL支持将现有RDD转换为Datasets的两种不同方法。第一种方法使用反射来推断包含特定类型对象的RDD的模式。这种基于反射的方法导致更简洁的代码,并且在编写Spark应用程序时已经知道模式的情况下工作良好。

创建数据集的第二种方法是通过编程接口,允许您构建模式,然后将其应用于现有的RDD。虽然这个方法比较冗长,但是它允许你在构造数据集的时候直到运行时才知道列和它们的类型。


// 用于从RDD到DataFrames的隐式转换
import spark.implicits._ // 从文本文件创建Person对象的RDD,将其转换为Dataframe 
val peopleDF = spark.sparkContext
.textFile("people.txt")
.map(_.split(","))
.map(attributes => Person(attributes(0), attributes(1).trim.toInt))
.toDF()
//将DataFrame注册为临时视图
peopleDF.createOrReplaceTempView("people") //SQL语句可以通过使用 Spark 提供的SQL方法运行
val teenagersDF = spark.sql("SELECT name, age FROM people WHERE age BETWEEN 13 AND 19") // 结果中的行的列可以通过字段索引
teenagersDF.map(teenager => "Name: " + teenager(0)).show()
// +------------+
// | value|
// +------------+
// |Name: Justin|
// +------------+ // 或通过字段名称
teenagersDF.map(teenager => "Name: " + teenager.getAs[String]("name")).show()
// +------------+
// | value|
// +------------+
// |Name: Justin|
// +------------+ // 没有为数据集[Map [K,V]]预定义的编码器,明确定义了
implicit val mapEncoder = org.apache.spark.sql.Encoders.kryo[Map[String, Any]]
// 原始类型和大小写类型也可以定义为
// implicit val stringIntMapEncoder: Encoder[Map[String, Any]] = ExpressionEncoder() //  row.getValuesMap [T]一栏立刻变成一个地图[String,T] 
teenagersDF.map(teenager => teenager.getValuesMap[Any](List("name", "age"))).collect()
// Array(Map("name" -> "Justin", "age" -> 19))

8,以编程方式指定模式

      当案例类不能提前定义时(例如,记录的结构是用字符串编码的,或者文本数据集将被解析,字段对不同的用户来说投影方式不同),DataFrame可以用三个步骤以编程方式创建一个。

          1,Row从原RDD 创建一个RDD;

          2, 创建在步骤1中创建的RDD中StructType与Rows 结构匹配 的模式。

          3,Row通过createDataFrame提供的方法将模式应用于s 的RDD SparkSession。

  import spark.implicits._
// 创建一个 RDD
val peopleRDD = spark.sparkContext.textFile("people.txt") // 模式用字符串编码
val schemaString = "name age" // 根据模式字符串
val fields = schemaString.split(" ")
.map(fieldName => StructField(fieldName, StringType, nullable = true))
val schema = StructType(fields) // 将RDD(人的记录)行
val rowRDD = peopleRDD
.map(_.split(","))
.map(attributes => Row(attributes(0), attributes(1).trim)) // 应用架构的RDD 
val peopleDF = spark.createDataFrame(rowRDD, schema) //使用DataFrame 
peopleDF.createOrReplaceTempView("people") // SQL可以在使用DataFrames 
val results = spark.sql("SELECT name FROM people") // SQL查询的结果是DataFrame并支持所有正常的RDD操作
// 结果中一行的列可以通过字段索引或字段名称
results.map(attributes => "Name: " + attributes(0)).show()
// +-------------+
// | value|
// +-------------+
// |Name: Michael|
// | Name: Andy|
// | Name: Justin|
// +-------------+

spark SQL (一)初识 ,简介的更多相关文章

  1. Spark SQL External DataSource简介

    随着Spark1.2的发布,Spark SQL开始正式支持外部数据源.这使得Spark SQL支持了更多的类型数据源,如json, parquet, avro, csv格式.只要我们愿意,我们可以开发 ...

  2. 【转载】Spark SQL之External DataSource外部数据源

    http://blog.csdn.net/oopsoom/article/details/42061077 一.Spark SQL External DataSource简介 随着Spark1.2的发 ...

  3. Spark SQL概念学习系列之Spark SQL的简介(一)

    Spark SQL提供在大数据上的SQL查询功能,类似于Shark在整个生态系统的角色,它们可以统称为SQL on Spark. 之前,Shark的查询编译和优化器依赖于Hive,使得Shark不得不 ...

  4. Spark SQL概念学习系列之SQL on Spark的简介(三)

    AMPLab 将大数据分析负载分为三大类型:批量数据处理.交互式查询.实时流处理.而其中很重要的一环便是交互式查询. 大数据分析栈中需要满足用户 ad-hoc.reporting. iterative ...

  5. 初识Spark2.0之Spark SQL

    内存计算平台spark在今年6月份的时候正式发布了spark2.0,相比上一版本的spark1.6版本,在内存优化,数据组织,流计算等方面都做出了较大的改变,同时更加注重基于DataFrame数据组织 ...

  6. Spark SQL Catalyst源代码分析之TreeNode Library

    /** Spark SQL源代码分析系列文章*/ 前几篇文章介绍了Spark SQL的Catalyst的核心执行流程.SqlParser,和Analyzer,本来打算直接写Optimizer的,可是发 ...

  7. Spark学习之Spark SQL

    一.简介 Spark SQL 提供了以下三大功能. (1) Spark SQL 可以从各种结构化数据源(例如 JSON.Hive.Parquet 等)中读取数据. (2) Spark SQL 不仅支持 ...

  8. Spark SQL在100TB上的自适应执行实践(转载)

    Spark SQL是Apache Spark最广泛使用的一个组件,它提供了非常友好的接口来分布式处理结构化数据,在很多应用领域都有成功的生产实践,但是在超大规模集群和数据集上,Spark SQL仍然遇 ...

  9. [Spark SQL_1] Spark SQL 配置

    0. 说明 Spark SQL 的配置基于 Spark 集群搭建  && Hive 的安装&配置 1. 简介 Spark SQL 是构建在 Spark Core 模块之上的四大 ...

随机推荐

  1. JVM初始化类契机

    * 对于初始化只有主动使用类字段时才会初始化<br> * 除非对一个类的主动引用,否则所有引用类的方式都不会触发其初始化<br> * 主动引用有且只有以下场景:<p> ...

  2. SpringBoot整合sa-token,完成网站权限验证

    sa-token是什么? sa-token是一个JavaWeb轻量级权限认证框架,其API调用非常简单,有多简单呢?以登录验证为例,你只需要: // 在登录时写入当前会话的账号id StpUtil.s ...

  3. AI算法测评事项

    前言 注:大概2017年-2018年国内人工智能热度达到顶峰,随后热度开始逐渐减少.2018年前人工智能被投资界.学术界.工业界和媒体炒的特别热,各大企业都想尝试一下深度学习技术在业务场景的应用.试水 ...

  4. 阿里云centos7[linux]安装nginx

    标题 说明 服务器版本 Centos7 x64 nginx版本 1.19.6 作者 walton 一.准备 创建安装包目录并进入 mkdir /usr/dev/nginx cd /usr/dev/ng ...

  5. Mysql性能监控可视化

    前言 ​ 操作系统以及Mysql数据库的实时性能状态数据尤为重要,特别是在有性能抖动的时候,这些实时的性能数据可以快速帮助你定位系统或Mysql数据库的性能瓶颈,镜像你在Linux系统上使用top.i ...

  6. mysql修改sql_mode为宽松模式

    sql_mode ANSI TRADITIONAL STRICT_TRANS_TABLES sql_mode为空 最宽松的模式, 即使有错误既不会报错也不会有警告️ ANSI 宽松模式,对插入数据进行 ...

  7. thinkphp3.2框架运行原理

    thinkphp3.2是使用率非常普遍的国产php框架,以简单易于上手闻名,那么它框架结构是怎样的? tp3.2设计简单来说就是CBD,core(框架核心文件),bebavior(行为,tp3.2一大 ...

  8. Ts有限状态机

    ts版本的有限状态机 最近做小游戏要做切换人物状态,花点时间写了一个有限状态机,使用语言为Ts,也可改成自己的语言 按照目前的逻辑,这个可以继续横向扩展,某些做流程管理 先上预览图 Fsm:状态机类 ...

  9. 【Oracle】查看哪些用户被授予了DBA权限

    查看哪些用户被授予了DBA权限 select * from dba_role_privs where granted_role='DBA'; 回收权限: revoke dba from xxx;

  10. CTFshow萌新赛-萌新福利

    下载链接文件 拿到show.bin文件 使用010Editor工具打开文件 做取反操作 取反后可以看到 把show.bin改为show.m4a 使用音频播放软件播放,即可得到flag