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. luanet性能测试

    测试环境 intel-i5 双核 2.53HZ 服务器客户端均在本机运行 测试内容:echo回射,每个包的字节数在20字节内 luanet 连接数 每秒回射数 1 19,000/s 10 12,500 ...

  2. 《转》Python学习(16)-python异常

    转自 http://www.cnblogs.com/BeginMan/p/3171445.html 一.什么是错误,什么是异常,它们两者区别 这里解释如下:个人觉得很通俗易懂 错误是指在执行代码过程中 ...

  3. IOS设计模式第六篇之适配器设计模式

    版权声明:原创作品,谢绝转载!否则将追究法律责任. 那么怎么使用适配器设计模式呢? 这个之前提到的水平滚动的视图像这样: 为了开始实现他,我们创建一个新的继承与UIView的HorizontalScr ...

  4. Makefile 中all 和.PHONY的作用

    请编写一个makefile同时编译.链接下面两个程序: main1.c: #include<stdio.h> int main(void) { printf("main1\n&q ...

  5. 求组合数 C++程序

    一 递归求组合数 设函数为void    comb(int m,int k)为找出从自然数1.2.... .m中任取k个数的所有组合. 分析:当组合的第一个数字选定时,其后的数字是从余下的m-1个数中 ...

  6. 部署OpenStack问题汇总(六)-- OpenStack入门需要知道的概念

    本博客已经添加"打赏"功能,"打赏"位置位于右边栏红色框中,感谢您赞助的咖啡. 一.网络问题-network 更多网络原理机制可以参考<OpenStack ...

  7. 面试题:应用中很多jar包,比如spring、mybatis、redis等等,各自用的日志系统各异,怎么用slf4j统一输出?(上)

    一.问题概述 如题所说,后端应用(非spring boot项目)通常用到了很多jar包,比如spring系列.mybatis.hibernate.各类连接数据库的客户端的jar包.可能这个jar包用的 ...

  8. vi 撤销操作

    'u' : 撤销上一个编辑操作 'ctrl + r' : 恢复,即回退前一个命令 'U' : 行撤销,撤销所有在前一个编辑行上的操作

  9. 手写代码UI,xib和StoryBoard间的的优劣比较

    在UI制作方面,逐渐分化三种主要流派:使用代码手写UI:使用单个xib文件组织viewController或者view:使用StoryBoard来通过单个或很少的几个文件构建UI.三种方式各有优劣,也 ...

  10. vue--引入富文本编辑器

    https://blog.csdn.net/div_ma/article/details/79536634 // 使用 https://blog.csdn.net/div_ma/article/det ...