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. spring 下载

    Spring官网(https://spring.io/)改版后,直接下载Jar包的链接,下面汇总 1.直接输入地址,改相应版本即可:http://repo.springsource.org/libs- ...

  2. Android下Notification,样式style,主题theme的功能实现

    一:Notification 1.NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVIC ...

  3. java类中serialversionuid 作用 是什么?举个例子说明(转)

    serialVersionUID适用于Java的序列化机制.简单来说,Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的.在进行反序列化时,JVM会把传来的字节流中的 ...

  4. HBase随机读写

    HDFS不太适合做大量的随机读应用,但HBASE却特别适合随机的读写 个人理解: 1.数据库一般都会有一层缓存,任何对数据的更改实际上是先更改内存中的数据.然后有异步的守护进程负责将脏页按照一定策略刷 ...

  5. 设计模式-装饰模式(Decorator Pattern)

    装饰模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活

  6. 浏览器中beforeunload的使用

    打开一些慢的网站的时候只见浏览器在不停转圈,但是页面还停留在当前页面的,有些网站的效果是你点击链接要跳到另一个页面的时候,在当前页面弹出一个框提示“正在加载中....”, 用到了浏览器的beforeu ...

  7. 开发集成工具MyEclipse中Outline的问题

    序言 不懂的多查,越查就越显得自己的无知,越发现大神的存在,可能相对于我来说是大神,在他那个高度,就觉得自己很菜,这些都正常,最值得敬佩的是,比你厉害的人,还比你更努力,那自己还有什么理由不努力呢,如 ...

  8. IOS开发之UIScrollVIew运用

    UIScrollView可以实现在一个界面看到所有内容,同时也不需要担心所显示的内容超出屏幕的大小,当超出之后可以翻阅至下一页浏览. #pragma mark - UIScrollViewDelega ...

  9. 【Unity】8.1 Unity内置的UI控件

    分类:Unity.C#.VS2015 创建日期:2016-04-27 一.简介 Unity 5.x内置了-套完整的GUI系统,提供了从布局.控件到皮肤的-整套GUI解决方案,因此可直接利用它做出各种风 ...

  10. 每日英语:China Destroys Six Tons of Confiscated Ivory

    BEIJING—Chinese government officials destroyed more than six tons of ivory that had been illegally s ...