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. 构建高性能J2EE应用的五种核心策略

    对于J2EE,我们知道当开发应用时,在架构设计阶段的决定将对应用的性能和可扩展性产生深远的影响.现在当开发一个应用项目时,我们越来越多地注意到了性能和可扩展性的问题.应用性能的问题比应用功能的不丰富问 ...

  2. tomcat启动报错 java.lang.ClassNotFoundException: org.apache.jsp.index_jsp

    项目运行一直很平稳,但是换了tomcat之后打开jsp网页时就报错,描述如下: 1. 错误描述 打开jsp网页时报错 java.lang.NullPointerException     org.ap ...

  3. python 字符串编码 ,区别 utf-8 和utf-8-sig

    Python 读取文件首行多了"\ufeff"字符串 python读取B.txt文件时,控制台打印首行正常,但是若是用首行内容打开文本的话,就会报错: Traceback (mos ...

  4. HTTP 请求头 详解

    转载:https://kb.cnblogs.com/page/92320/ HTTP(HyperTextTransferProtocol)即超文本传输协议,目前网页传输的的通用协议.HTTP协议采用了 ...

  5. 转:纯CSS实现“鼠标移过显示层”效果

    利用<a>标签的a:hover状态触发鼠标移过的动作,其中未触发状态显示为单个图片.兼容IE6/7/8以及FF/Chrome等主流浏览器.以下是图示及完整代码. 原文:http://www ...

  6. Mac idea 执行testng用例,提示%MODULE_WORKING_DIR%目录不存在解决办法

    idea 下载git代码 执行testng用例,报错: 下午4:47 Error running 'Test.apkStart': Cannot start process, the working ...

  7. win8.1安装驱动出现“文件的哈希值不在指定的目录”的解决办法[zz]

    1.鼠标移到右下角,点击“设置”,再点击“更改电脑设置”2.点击最后一个“更新和回复”,再点击“恢复”3.点击“恢复”之后,在右边点击高级启动下面的“重新启动”4.等一会会出现几个选项,点击“疑难解答 ...

  8. Spring ORM数据訪问——Hibernate

    Hibernate 我们将首先介绍Spring环境中的Hibernate 5.然后介绍使用Hibernate 5来演示Spring集成O-R映射器的方法. 本节将具体介绍很多问题,并显示DAO实现和事 ...

  9. [svc]为何linux ext4文件系统目录默认大小是4k?

    linux ext4普通盘为什么目录大小是4k? Why does every directory have a size 4096 bytes (4 K)? To understand this, ...

  10. 文档 - STOMP Over WebSocket

    http://jmesnil.net/stomp-websocket/doc/ What is STOMP? STOMP is a simple text-orientated messaging p ...