Spark SQL是为了让开发人员摆脱自己编写RDD等原生Spark代码而产生的,开发人员只需要写一句SQL语句或者调用API,就能生成(翻译成)对应的SparkJob代码并去执行,开发变得更简洁

注意:本文全部基于SparkSQL1.6

参考:http://spark.apache.org/docs/1.6.0/

一. API

Spark SQL的API方案:3种

SQL

the DataFrames API

the Datasets API.

但会使用同一个执行引擎

the same execution engine is used

(一)数据转为Dataframe

1、(半)格式化数据(HDFS文件)

SQLContext sqlContext = new org.apache.spark.sql.SQLContext(sc)
// Parquet files are self-describing so the schema is preserved.文件格式自带描述性
DataFrame df= sqlContext.read().parquet("people.parquet");
//SQLContext.read().json() on either an RDD of String, or a JSON file. not a typical JSON file(见下面的小实验)
DataFrame df = sqlContext.read().json("/testDir/people.json");

Load默认是parquet格式,通过format指定格式

DataFrame df = sqlContext.read().load("examples/src/main/resources/users.parquet");
DataFrame df = sqlContext.read().format("json").load("main/resources/people.json");

旧API  已经被废弃

DataFrame df2 =sqlContext.jsonFile("/xxx.json");
DataFrame df2 =sqlContext.parquetFile("/xxx.parquet");

2、RDD数据

SQLContext sqlContext = new org.apache.spark.sql.SQLContext(sc)

a. 通过类  利用JAVA类的反射机制

已有:JavaRDD<Person> people

DataFrame df= sqlContext.createDataFrame(people, Person.class);

b. 通过schema转换RDD

已有:StructType schema = DataTypes.createStructType(fields);

和JavaRDD<Row>  rowRDD

DataFrame df= sqlContext.createDataFrame(rowRDD, schema);

3、 Hive数据(HDFS文件在数据库中的表(schema) 对应关系)

HiveContext sqlContext = new org.apache.spark.sql.hive.HiveContext(sc);
DataFrame df = sqlContext.sql("select count(*) from wangke.wangke where ns_date=20161224");
sqlContext.refreshTable("my_table")
//(if configured,sparkSQL caches metadata)
sqlContext.sql("CREATE TABLE IF NOT EXISTS src (key INT, value STRING)");
sqlContext.sql("LOAD DATA LOCAL INPATH 'resources/kv1.txt' INTO TABLE src");
Row[] results = sqlContext.sql("FROM src SELECT key, value").collect();

4、特殊用法

DataFrame df = sqlContext.sql("SELECT * FROM parquet.`main/resources/users.parquet`");
//查询临时表people
DataFrame teenagers = sqlContext.sql("SELECT name FROMpeople WHERE age >= 13 AND age <= 19")

(二)、Dataframe使用

1、展示

df.show();
df.printSchema();

2、过滤选择

df.select("name").show();
df.select(df.col("name"), df.col("age").plus()).show();
df.filter(df.col("age").gt()).show();
df.groupBy("age").count().show();

3、写文件

df.select("name", "favorite_color").write().save("namesAndFavColors.parquet");
df.select("name", "age").write().format("parquet").save("namesAndAges.parquet");
df.write().parquet("people.parquet");

4、注册临时表

df.registerTempTable("people");

之后就可以用SQL在上面去查了

DataFrame teenagers = sqlContext.sql("SELECT name FROM people WHERE age >= 13 AND age <= 19")

5、保存Hive表

When working with a HiveContext, DataFrames can also be saved as persistent tables using the saveAsTable command

只有HiveContext生成的Dataframe才能调用saveAsTable去持久化hive表

(三)、直接SQL操作

sqlContext.sql("create table xx.tmp like xx.xx");
sqlContext.sql("insert into table xx.tmp partition(day=20160816) select * from xx.xx where day=20160816");
sqlContext.sql("insert overwrite table xx.xx partition(day=20160816) select * from xx.tmp where day=20160816");

二. 原理

将上面的所有操作总结为如下图:

Dataframe本质是  数据  +  数据的描述信息(结构元信息)

所有的上述SQL及dataframe操作最终都通过Catalyst翻译成spark程序RDD操作代码

sparkSQL前身是shark,大量依赖Hive项目的jar包与功能,但在上面的扩展越来越难,因此出现了SparkSQL,它重写了分析器,执行器   脱离了对Hive项目的大部分依赖,基本可以独立去运行,只用到两个地方:

1.借用了hive的词汇分析的jar即HiveQL解析器

2.借用了hive的metastore和数据访问API即hiveCatalog

也就是说上图的左半部分的操作全部用的是sparkSQL本身自带的内置SQL解析器解析SQL进行翻译,用到内置元数据信息(比如结构化文件中自带的结构元信息,RDD的schema中的结构元信息)

右半部分则是走的Hive的HQL解析器,还有Hive元数据信息

因此左右两边的API调用的底层类会有不同

SQLContext使用:

简单的解析器(scala语言写的sql解析器)【比如:1.在半结构化的文件里面使用sql查询时,是用这个解析器解析的,2.访问(半)结构化文件的时候,通过sqlContext使用schema,类生成Dataframe,然后dataframe注册为表时,registAsTmpTable   然后从这个表里面进行查询时,即使用的简单的解析器,一些hive语法应该是不支持的,有待验证)】

simpleCatalog【此对象中存放关系(表),比如我们指定的schema信息,类的信息,都是关系信息】

HiveContext使用:

HiveQL解析器【支持hive的hql语法,如只有通过HiveContext生成的dataframe才能调用saveAsTable操作】

hiveCatalog(存放数据库和表的元数据信息)

三. Catalyst

所有的SQL操作最终都通过Catalyst翻译成spark程序代码

四. 文件小实验(关于sparkSQL使用json的坑)

SQLContext sqlContext = new SQLContext(sc);
DataFrame df = sqlContext.read().json("/testDir/people.json");

将json文件放在文件系统中,一直无法找到

原来它是从HDFS里面取数据的

sc.textFile("/testDir/people.txt")也是默认从HDFS中读

注意这个路径,最开始的斜杠很重要

如果没有,则是相对路径,前面会自动加上user和用户名的路径

hdfs://10.67.1.98:9000/user/wangke/testDir/people.txt

创建了一个合法的json文件放在了HDFS下

尝试其API,发现一直报错

org.apache.spark.sql.AnalysisException: Cannot resolve column name "age" among (_corrupt_record);

原因(很坑很坑)

1. 不能写成合法的json数据

[

    {

        "name": "Michael",

        "age": 

    },

    {

        "name": "Andy",

        "age": 

    },

    {

        "name": "justin",

        "age": 

    }

]

这个是标准的,spark不识别,呵呵呵

改:

 {

        "name": "Michael",

        "age": } {

        "name": "Andy",

        "age":  }{

        "name": "justin",

        "age":
}

依然报错

http://www.aboutyun.com/thread-12312-1-1.html

2. Json数据不能换行

{"name": "Michael","age": }
{"name": "Andy","age": }
{"name": "justin","age": }

原因:

Note that the file that is offered as a json file is not a typical JSON file. Each line must contain a separate, self-contained valid JSON object. As a consequence, a regular multi-line JSON file will most often fail.

http://stackoverflow.com/questions/38545850/org-apache-spark-sql-analysisexception-cannot-resolve-id-given-input-columns

 json要在一行的原因 初步猜测是因为和spark json file to DF的步骤有关,猜测的步骤:

. val jsonRdd= sc.textFile('your_json_file')
. jsonRdd.map(line => )
 实现方式是先读text文件,然后map line to row or tuple, 然后 toDF
 不在一行不好识别一个json string 有几行,也无法确定 df的schema。

五. SparkSQL整体架构(前端+后端)

thriftserver作为一个前端,它其实只是主要分为两大块:

1.维护与用户的JDBC连接

2.通过HiveContext的API提交用户的HQL查询

Spark SQL入门用法与原理分析的更多相关文章

  1. spark sql 入门

    package cn.my.sparksql import cn.my.sparkStream.LogLevel import org.apache.spark.{SparkConf, SparkCo ...

  2. Spark SQL概念学习系列之Spark SQL入门

    前言 第1章   为什么Spark SQL? 第2章  Spark SQL运行架构 第3章 Spark SQL组件之解析 第4章 深入了解Spark SQL运行计划 第5章  测试环境之搭建 第6章 ...

  3. Spark SQL概念学习系列之Spark SQL入门(八)

    前言 第1章   为什么Spark SQL? 第2章  Spark SQL运行架构 第3章 Spark SQL组件之解析 第4章 深入了解Spark SQL运行计划 第5章  测试环境之搭建 第6章 ...

  4. Spark SQL入门案例之人力资源系统数据处理

    通过该案例,给出一个比较完整的.复杂的数据处理案例,同时给出案例的详细解析. 人力资源系统的管理内容组织结构图 1) 人力资源系统的数据库与表的构建. 2) 人力资源系统的数据的加载. 3) 人力资源 ...

  5. spark sql 基本用法

    一.通过结构化数据创建DataFrame: publicstaticvoid main(String[] args) {    SparkConf conf = new SparkConf() .se ...

  6. Spark2.x(六十二):(Spark2.4)共享变量 - Broadcast原理分析

    之前对Broadcast有分析,但是不够深入<Spark2.3(四十三):Spark Broadcast总结>,本章对其实现过程以及原理进行分析. 带着以下几个问题去写本篇文章: 1)dr ...

  7. 【原创 Hadoop&Spark 动手实践 9】Spark SQL 程序设计基础与动手实践(上)

    [原创 Hadoop&Spark 动手实践 9]SparkSQL程序设计基础与动手实践(上) 目标: 1. 理解Spark SQL最基础的原理 2. 可以使用Spark SQL完成一些简单的数 ...

  8. Spark SQL Catalyst源代码分析Optimizer

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

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

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

随机推荐

  1. JDK下载链接

    所有的存档页面 http://www.oracle.com/technetwork/cn/java/archive-139210-zhs.html

  2. Android Studio 出现 Gradle's dependency cache may be corrupt 解决方案

    将 .\项目地址\gradle\wrapper\gradle-wrapper.properties 文件中的 gradle版本 与 正常的版本 修改一致即可.

  3. ThinkPHP5 封装邮件发送服务(可发附件)

    1.Composer 安装 phpmailer 1 composer require phpmailer/phpmailer 2.ThinkPHP 中封装邮件服务类 我把它封装在扩展目录 extend ...

  4. kubernetes 测试 Mariadb gtid 主从复制.

    k8s 为 1个master 3个node 下载镜像 : mariadb 镜像版本是10.2.13 (此时10.3还没发布正式版) docker pull mariadb push到私有仓库 dock ...

  5. 10分钟10行代码开发APP(delphi 应用案例)

    总结一下用到的知识(开发环境安装配置不计算在内): 第六章  使用不同风格的按钮: 第十七章  让布局适应不同大小与方向的窗体: 第二十五章 使用 dbExpress访问 InterBase ToGo ...

  6. iPhone 上如何通过 Safari 使用 Pocket

     在开始之前,请确认你的机器上已经安装了 Pocket  应用软件. 如何安装 1.打开Pocket应用,点击左上角的菜单(三条横岗),找到最下面的 Help ,点击 How To Save ,找到 ...

  7. storm事务

    1. storm 事务 对于容错机制,Storm通过一个系统级别的组件acker,结合xor校验机制判断一个msg是否发送成功,进而spout可以重发该msg,保证一个msg在出错的情况下至少被重发一 ...

  8. [转]stetho使用介绍

    原文链接:http://www.jianshu.com/p/c03a8959d1a5# 转载请注明来源,尊重作者成果 介绍 stetho是facebook开发的Android调试工具.它可以通过chr ...

  9. lombok 一个不错的小工具

    (1)官方文档  Lombok features (2)Lombok Reduces Your Boilerplate Code (3)Lombok-Java代码自动生成 开发利器

  10. CentOS7.5搭建Solr7.4.0集群服务

    一.Solr集群概念 solr单机版搭建参考: https://www.cnblogs.com/frankdeng/p/9615253.html 1.概念 SolrCloud(solr 云)是Solr ...