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. php的session问题总结

    1. 看文档发现,在session的configure option中有三个关于gc的,分别是: session.gc_probability "1" PHP_INI_ALL se ...

  2. Matlab 二维绘图函数(plot类)

    plot 功能 绘制二维图形的最基本函数. 语法 //x为向量时,以x的元素值为纵坐标,x的序号为横坐标绘制曲线. //x为矩阵时,以其序号为横坐标,按列绘制每列元素值相对于其序号的曲线. polt( ...

  3. 分布式实时日志系统(一)环境搭建之 Jstorm 集群搭建过程/Jstorm集群一键安装部署

    最近公司业务数据量越来越大,以前的基于消息队列的日志系统越来越难以满足目前的业务量,表现为消息积压,日志延迟,日志存储日期过短,所以,我们开始着手要重新设计这块,业界已经有了比较成熟的流程,即基于流式 ...

  4. mysql查询语句集

    1. mysql 查询出某字段的值不为空的语句 1.不为空 select * from table where id <> ""; select * from tabl ...

  5. [转] 基于TINY4412的Andorid开发-------简单的LED灯控制

    阅读目录 一.编写驱动程序 二.编写代码测试驱动程序 三.编写HAL代码 四.编写Framework代码 五.编写JNI代码 六.编写App 参考资料: <Andriod系统源代码情景分析> ...

  6. matlab中 数据保留有效位数

    可以使用round函数  ,这函数原本功能是四舍五入 比如: >> A = 0.0326465;>> B = round(A*1000)/1000 B = 0.0330

  7. [NHibernate] Guid 作主键速度超慢的背后

    http://blog.csdn.net/educast/article/details/6602353 最近遇到了一个让人抓狂的性能问题.生产环境里有一张表的数据量目前达到了 70 万条.结果发现无 ...

  8. Gradle gitignore Gradle 模式 上传SVN 要忽略的文件

    .gradle /local.properties /.idea/workspace.xml /.idea/libraries .DS_Store /build /captures /.idea *. ...

  9. vmware新建Ubuntu时,提示此主机不支持 Intel VT-x

    有两种解决方式 一.BIOS中打开CPU虚拟选项,不同厂商主板配置不同: 以下以个人thinkpad T460P电脑为例: 1.关机,开机,在启动时,按F1今天 BIOS 设置页面: 2.选择 Sec ...

  10. WCF的简单使用

    WCF简单介绍 WCF(windows communication foundation)是微软推出的数据通信的统一编程模型,在WCF有四个主要的关键点: abcd Address(地址):定义服务的 ...