Spark SQL讲解

Spark SQL是支持在Spark中使用Sql、HiveSql、Scala中的关系型查询表达式。它的核心组件是一个新增的RDD类型SchemaRDD,它把行对象用一个Schema来描述行里面的所有列的数据类型,它就像是关系型数据库里面的一张表。它可以从原有的RDD创建,也可以是Parquet文件,最重要的是它可以支持用HiveQL从hive里面读取数据。

下面是一些案例,可以在Spark shell当中运行。

首先我们要创建一个熟悉的Context,熟悉spark的人都知道吧,有了Context我们才可以进行各种操作。

val sc: SparkContext // 已经存在的SparkContext
val sqlContext = new org.apache.spark.sql.SQLContext(sc) import sqlContext._

Data Sources(数据源)

Spark SQL通过SchemaRDD接口支持在多种数据源上进行操作。一旦一个数据集被加载,它可以被注册成一个表格,甚至可以和其它数据源有连接。

RDDs

Spark SQL支持的一种表的类型是Scala的case class,case class定义了表的类型,下面是例子:

// sc是一个已经存在的SprakContext
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
// import sqlContext._
import sqlContext.createSchemaRDD
// case class在Scala 2.10里面最多支持22个列,为了突破这个限制,最好是定义一个类实现Product接口
case class Person(name: String, age: Int) // 为Person的对象创建一个RDD,然后注册成一张表
val people = sc.textFile("examples/src/main/resources/people.txt").map(_.split(",")).map(p => Person(p(0), p(1).trim.toInt))
people.registerAsTable("people") // 直接写sql吧,这个方法是sqlContext提供的
val teenagers = sql("SELECT name FROM people WHERE age >= 13 AND age <= 19") // teenagers是SchemaRDDs类型,它支持所有普通的RDD操作
teenagers.map(t => "Name: " + t(0)).collect().foreach(println)

从上面这个方法来看,不是很好用,一个表好几十个字段,我就得一个一个的去赋值,它现在支持的操作都是很简单的操作,想要实现复杂的操作可以具体去看HiveContext提供的HiveQL。

Parquet Files

Parquet是一种列式存储格式并且被许多数据处理系统支持。Parquet为Hadoop生态系统中的所有项目提供支持高效率压缩的列式数据表达,而且与数据处理框架、数据模型或编程语言都没有关系。Spark SQL提供了对Parquet的读和写,自动保留原始数据的架构。

val sqlContext = new org.apache.spark.sql.SQLContext(sc)
// import sqlContext._
// createSchemaRDD被用来将RDD隐式转换成一个SchemaRDD
import sqlContext.createSchemaRDD
val people: RDD[Person] = ... // 同上面的例子. // 这个RDD已经隐式转换成一个SchemaRDD, 允许它存储成Parquet格式.
people.saveAsParquetFile("people.parquet") // 从上面创建的文件里面读取,加载一个Parquet文件的结果也是一种JavaSchemaRDD.
val parquetFile = sqlContext.parquetFile("people.parquet") //注册成表,然后在SQL状态下使用
parquetFile.registerAsTable("parquetFile")
val teenagers = sqlContext.sql("SELECT name FROM parquetFile WHERE age >= 13 AND age <= 19")
teenagers.map(t => "Name:" + t(0)).collect().foreach(println)

JSON Datasets(JSON数据集)

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成(网络传输速度快)。

SparkSQL可以自动推断出一个JSON数据集模式并作为一个SchemaRDD来加载。这种转换可以通过使用SQLContext中的两个方法中的一个得到:

jsonFile - 从JSON文件的目录中加载数据,其中文件的每一行就是一个JSON对象。

jsonRdd - 从一个已存在的RDD中加载数据,其中每一个RDD元素都是一个包含一个JSON对象的字符串。

// sc 是已经存在的SparkContext
val sqlContext = new org.apache.spark.sql.SQLContext(sc) // 一个JSON 数据集用一个路径指出
// 这个路径既可以是一个单独的文本文件,也可以是一个存储文本文件的目录
val path = "examples/src/main/resources/people.json"
// 根据路径指出的文件生成一个SchemaRDD
val people = sqlContext.jsonFile(path) // 推断的模式可以通过使用printSchema() 方法显式化
people.printSchema()
// root
// |-- age: IntegerType
// |-- name: StringType // 把SchemaRDD注册成一个表
people.registerAsTable("people") // SQL状态可以通过使用sqlContext提供的sql方法运行
val teenagers = sqlContext.sql("SELECT name FROM people WHERE age >= 13 AND age <= 19") // 另外,一个SchemaRDD也可以通过每个字符串存储一个JSON数据集对象的string类型的RDD来生成
val anotherPeopleRDD = sc.parallelize(
"""{"name":"Yin","address":{"city":"Columbus","state":"Ohio"}}""" :: Nil)
val anotherPeople = sqlContext.jsonRDD(anotherPeopleRDD)

Hive Tables

Spark SQL也支持读写存储在Apache Hive上的数据。然而,hive的依赖太多了,默认的Spark assembly 是没带这些依赖的,需要我们运行 SPARK_HIVE=true sbt/sbt assembly/assembly重新编译,或者用maven的时候添加 -Phive参数,它会重新编译出来一个hive  assembly的jar包,然后需要把这个jar包放到所有的节点上。另外还需要把 hive-site.xml放到conf目录下。没进行hive部署的话,下面的例子也可以用LocalHiveContext来代替HiveContext。

val sc: SparkContext // 已经存在的SparkContext
val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc) // 引入这个Context,然后就会给所有的sql语句进行隐式转换
import hiveContext._ hql("CREATE TABLE IF NOT EXISTS src (key INT, value STRING)")
hql("LOAD DATA LOCAL INPATH 'examples/src/main/resources/kv1.txt' INTO TABLE src") // 使用HiveQL查询
hql("FROM src SELECT key, value").collect().foreach(println)

或者写成如下形式:

// sc is an existing SparkContext.
val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc) hiveContext.hql("CREATE TABLE IF NOT EXISTS src (key INT, value STRING)")
hiveContext.hql("LOAD DATA LOCAL INPATH 'examples/src/main/resources/kv1.txt' INTO TABLE src") // Queries are expressed in HiveQL
hiveContext.hql("FROM src SELECT key, value").collect().foreach(println)

Writing Language-Integrated Relational Queries

文字语言综合关联查询,目前这个功能只是在Scala里面支持。

Spark SQL还支持一个特定域的语言编写查询。再次,利用上述实例数据:

// sc是一个已经存在的SparkContext
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
import sqlContext._
val people: RDD[Person] = ... // 同前面的例子. // 和后面这个语句是一样的 'SELECT name FROM people WHERE age >= 10 AND age <= 19'
val teenagers = people.where('age >= 10).where('age <= 19).select('name)
teenagers.map(t => "Name: " + t(0)).collect().foreach(println)

DSL(领域语言)使用scala符号表示隐含表中的列,通过在前面加一个(‘)来标示。隐式转换将这些符号表达式表示成SQL执行引擎的值。一个完整的功能支持列表可以在ScalaDoc中找到。

Spark SQL讲解的更多相关文章

  1. 以慕课网日志分析为例-进入大数据Spark SQL的世界

    下载地址.请联系群主 第1章 初探大数据 本章将介绍为什么要学习大数据.如何学好大数据.如何快速转型大数据岗位.本项目实战课程的内容安排.本项目实战课程的前置内容介绍.开发环境介绍.同时为大家介绍项目 ...

  2. spark结构化数据处理:Spark SQL、DataFrame和Dataset

    本文讲解Spark的结构化数据处理,主要包括:Spark SQL.DataFrame.Dataset以及Spark SQL服务等相关内容.本文主要讲解Spark 1.6.x的结构化数据处理相关东东,但 ...

  3. 以某课网日志分析为例 进入大数据 Spark SQL 的世界

    第1章 初探大数据 本章将介绍为什么要学习大数据.如何学好大数据.如何快速转型大数据岗位.本项目实战课程的内容安排.本项目实战课程的前置内容介绍.开发环境介绍.同时为大家介绍项目中涉及的Hadoop. ...

  4. 第七篇:Spark SQL 源码分析之Physical Plan 到 RDD的具体实现

    /** Spark SQL源码分析系列文章*/ 接上一篇文章Spark SQL Catalyst源码分析之Physical Plan,本文将介绍Physical Plan的toRDD的具体实现细节: ...

  5. 第五篇:Spark SQL Catalyst源码分析之Optimizer

    /** Spark SQL源码分析系列文章*/ 前几篇文章介绍了Spark SQL的Catalyst的核心运行流程.SqlParser,和Analyzer 以及核心类库TreeNode,本文将详细讲解 ...

  6. 第四篇:Spark SQL Catalyst源码分析之TreeNode Library

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

  7. 第三篇:Spark SQL Catalyst源码分析之Analyzer

    /** Spark SQL源码分析系列文章*/ 前面几篇文章讲解了Spark SQL的核心执行流程和Spark SQL的Catalyst框架的Sql Parser是怎样接受用户输入sql,经过解析生成 ...

  8. 第二篇:Spark SQL Catalyst源码分析之SqlParser

    /** Spark SQL源码分析系列文章*/ Spark SQL的核心执行流程我们已经分析完毕,可以参见Spark SQL核心执行流程,下面我们来分析执行流程中各个核心组件的工作职责. 本文先从入口 ...

  9. Spark SQL 编程API入门系列之SparkSQL的入口

    不多说,直接上干货! SparkSQL的入口:SQLContext SQLContext是SparkSQL的入口 val sc: SparkContext val sqlContext = new o ...

随机推荐

  1. 使用base64编码的好处

    在项目中,将报文进行压缩.加密后,最后一步必然是使用base64编码,因为base64编码的字符串,更适合不同平台.不同语言的传输: 它不受其他编码的影响,仍然保持不变,这点很有意义,如下验证: St ...

  2. 转: springboot2.0下hystrix.stream 404

    springboot2.0下hystrix dashboard Unable to connect to Command Metric Stream解决办法https://blog.csdn.net/ ...

  3. 使用 properties 配置文件装配 bean 的方式

    在spring中将bean 注册到spring 容器中常见的有三种方式(两类): 先说明配置文件内容:application.yml,有一段配置如下 persons: youtube: name: y ...

  4. idea没有代码自动提示功能和包自动引入不了问题

    idea没有代码自动提示功能和包自动引入不了问题 原因:节电模式 File -> Power Save Mode (被勾选了) 处理方法: File -> Power Save Mode ...

  5. 未能加载文件或程序集“Microsoft.SqlServer.Management.Sdk.Sfc, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91”或它的某一个依赖项。系统找不到指定的文件。

    莫名其妙的,在 VS 中添加数据库连接就报这个错误,经过查找,解决方法是重新安装下两个sql server的组件:SharedManagementObjects.msi 和 SQLSysClrType ...

  6. Android:相机适配及图片处理的一些问题

    链接:http://www.cnblogs.com/liushilin/p/6387263.html 链接:http://www.cnblogs.com/liushilin/p/5956691.htm ...

  7. Python Import机制

    最近在看<Python源码剖析>,对Python内部运行机制比以前了解的更深入了,感觉自己有机会也可以做个小型的动态脚本语言了,呵呵,当然是吹牛了.目的当然不是创造一个动态语言,目的只有一 ...

  8. Lua语法基础(3)--迭代器和泛型for

    迭代器和闭包 迭代器是一种支持指针类型的结构,它可以遍历集合的每一个元素.在Lua中我们常常使用函数来描述迭代器,每次调用该函数就返回集合的下一个元素. 迭代器需要保留上一次成功调用的状态和下一次成功 ...

  9. LeetCode: Partition List 解题报告

    Partition List Given a linked list and a value x, partition it such that all nodes less than x come ...

  10. pyqt5-UDP消息发送

    使用pyqt5做了一个发送UDP消息的客户端. 项目的完整代码已上传到 github 很简单的,只是用来向某个地址发送UPD消息.这个后面会用到新的功能也会更新.这里贴一下qt5做界面的代码,跟qt4 ...