返回顶部
首页 > 资讯 > 数据库 >理解Spark SQL(二)—— SQLContext和HiveContext
  • 721
分享到

理解Spark SQL(二)—— SQLContext和HiveContext

理解SparkSQL(二)——SQLContext和HiveContext 2017-07-25 03:07:15 721人浏览 才女
摘要

使用spark sql,除了使用之前介绍的方法,实际上还可以使用SQLContext或者HiveContext通过编程的方式实现。前者支持SQL语法解析器(SQL-92语法),后者支持SQL语法解析器和HiveSQL语法解析器,默认为Hiv

使用spark sql,除了使用之前介绍的方法,实际上还可以使用SQLContext或者HiveContext通过编程的方式实现。前者支持SQL语法解析器(SQL-92语法),后者支持SQL语法解析器和HiveSQL语法解析器,默认为HiveSQL语法解析器,用户可以通过配置切换成SQL语法解析器来运行HiveQL不支持的语法,如:select 1。实际上HiveContext是SQLContext的子类,因此在HiveContext运行过程中除了override的函数和变量,可以使用和SQLContext一样的函数和变量。

因为spark-shell工具实际就是运行的Scala程序片段,为了方便,下面采用spark-shell进行演示。

首先来看SQLContext,因为是标准SQL,可以不依赖于Hive的metastore,比如下面的例子(没有启动hive metastore):

[root@BruceCentos4 ~]# $SPARK_HOME/bin/spark-shell --master yarn --conf spark.sql.catalogImplementation=in-memory

 

 scala> case class offices(office:Int,city:String,region:String,mgr:Int,target:Double,sales:Double)
defined class offices

scala> val rddOffices=sc.textFile("/user/hive/warehouse/orderdb.db/offices/offices.txt").map(_.split(" ")).map(p=>offices(p(0).trim.toInt,p(1),p(2),p(3).trim.toInt,p(4).trim.toDouble,p(5).trim.toDouble))
rddOffices: org.apache.spark.rdd.RDD[offices] = MapPartitionsRDD[3] at map at :26

scala> val officesDataFrame = spark.createDataFrame(rddOffices)
officesDataFrame: org.apache.spark.sql.DataFrame = [office: int, city: string ... 4 more fields]

scala> officesDataFrame.createOrReplaceTempView("offices")

scala> spark.sql("select city from offices where region="Eastern"").map(t=>"City: " + t(0)).collect.foreach(println)
City: NewYork                                                                   
City: ChicaGo
City: Atlanta

scala>

 执行上面的命令后,实际上在yarn集群中启动了一个yarn client模式的Spark Application,然后在scala>提示符后输入的语句会生成RDD的transfORMation,最后一条命令中的collect会生成RDD的action,即会触发Job的提交和程序的执行。

命令行中之所以加上--conf spark.sql.catalogImplementation=in-memory选项,是因为spark-shell中的默认启动的SparkSession对象spark是默认支持Hive的,不带这个选项启动的话,程序就会去连接hive metastore,因为这里并没有启动hive metastore,因此程序在执行createDataFrame函数时会报错。

程序中的第一行是1个case class语句,这里是定义后面的数据文件的模式的(定义模式除了这个方法,其实还有另外一种方法,后面再介绍)。第二行从hdfs中读取一个文本文件,并工通过map映射到了模式上面。第三行基于第二行的RDD生成DataFrame,第四行基于第三行的DataFrame注册了一个逻辑上的临时表,最后一行就可以通过SparkSession的sql函数来执行sql语句了。

实际上,SQLContext是Spark 1.x中的SQL入口,在Spark 2.x中,使用SparkSession作为SQL的入口,但是为了向后兼容,Spark 2.x仍然支持SQLContext来操作SQL,不过会提示deprecated,所以上面的例子是采用Spark 2.x中的写法。

实际上还有另外一种方法来操作SQL,针对同样的数据,例如:

scala> import org.apache.spark.sql._
import org.apache.spark.sql._

scala> import org.apache.spark.sql.types._
import org.apache.spark.sql.types._

scala> val schema = new StructType(Array(StructField("office", IntegerType, false), StructField("city", StringType, false), StructField("region", StringType, false), StructField("mgr", IntegerType, true), StructField("target", DoubleType, true), StructField("sales", DoubleType, false)))
schema: org.apache.spark.sql.types.StructType = StructType(StructField(office,IntegerType,false), StructField(city,StringType,false), StructField(region,StringType,false), StructField(mgr,IntegerType,true), StructField(target,DoubleType,true), StructField(sales,DoubleType,false))

scala> val rowRDD = sc.textFile("/user/hive/warehouse/orderdb.db/offices/offices.txt").map(_.split(" ")).map(p => Row(p(0).trim.toInt,p(1),p(2),p(3).trim.toInt,p(4).trim.toDouble,p(5).trim.toDouble))
rowRDD: org.apache.spark.rdd.RDD[org.apache.spark.sql.Row] = MapPartitionsRDD[3] at map at :30

scala> val dataFrame = spark.createDataFrame(rowRDD, schema)
dataFrame: org.apache.spark.sql.DataFrame = [office: int, city: string ... 4 more fields]

scala> dataFrame.createOrReplaceTempView("offices")

scala> spark.sql("select city from offices where region="Eastern"").map(t=>"City: " + t(0)).collect.foreach(println)
City: NewYork                                                                   
City: Chicago
City: Atlanta

这个例子与之前的例子有一些不同,主要的地方有3个:

之前的例子是采用case class定义模式,Spark采用反射来推断Schema;而这个例子采用StructType类型的对象来定义模式,它接收一个数组,数组成员是StructField对象,代表一个字段的定义,每个字段的定义由字段名称、字段类型和是否允许为空组成;

对于代表数据的RDD,之前的例子是直接用case class定义的类型来分割字段,而这个例子是用的Row类型;

在使用createDataFrame函数生成DataFrame时,该函数的参数不一样,之前的例子只要传入RDD对象即可(对象中隐含了模式),而这个例子需要同时传入RDD和定义的schema;

实际编程中建议采用第二种方法,因为其更加灵活,schema信息可以不必是写死的,而是可以在程序运行的过程中生成。

 

下面接着来看HiveContext的用法,使用HiveContext之前需要确保:

  • 使用的Spark是支持Hive的;
  • Hive的配置文件hive-site.xml已经在Spark的conf目录下;
  • hive metastore已经启动;

举例说明:

首先启动hive metastore:

[root@BruceCentOS ~]# nohup hive --service metastore &

然后仍然通过spark-shell来举例说明,启动spark-shell,如下所示:

[root@BruceCentOS4 ~]# $SPARK_HOME/bin/spark-shell --master yarn

scala> spark.sql("show databases").collect.foreach(println)
[default]
[orderdb]

scala> spark.sql("use orderdb")
res2: org.apache.spark.sql.DataFrame = []

scala> spark.sql("show tables").collect.foreach(println)
[orderdb,customers,false]
[orderdb,offices,false]
[orderdb,orders,false]
[orderdb,products,false]
[orderdb,salesreps,false]

scala> spark.sql("select city from offices where region="Eastern"").map(t=>"City: " + t(0)).collect.foreach(println)
City: NewYork                                                                   
City: Chicago
City: Atlanta

scala>

可以看到这次启动spark-shell没有带上最后那个选项,这是因为这里我们打算用HiveContext来操作Hive中的数据,需要支持Hive。前面说过spark-shell是默认开启了Hive支持的。同SQLContext类似,Spark 2.x中也不需要再用HiveContext对象来操作SQL了,直接用SparkSession对象来操作就好了。可以看到这里可以直接操作表,不用再定义schema,这是因为schema是由外部的hive metastore定义的,spark通过连接到hive metastore来读取表的schema信息,因此这里能直接操作SQL。

 

另外,除了上面的使用SQLContext操作普通文件(需要额外定义模式)和使用HiveContext操作Hive表数据(需要开启hive metastore)之外,SQLContext还能操作JSON、PARQUET等文件,由于这两种数据文件自己带了模式信息,因此可以直接基于文件创建DataFrame,例如:

scala> val df = spark.read.json("file:///opt/spark/examples/src/main/resources/people.json")
df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]                

scala> df.createOrReplaceTempView("people")

scala> spark.sql("select name,age from people where age>19").map(t=>"Name :" + t(0) + ", Age: " + t(1)).collect.foreach(println)
Name :Andy, Age: 30    

 

最后来看下DataFrame的另一种叫做DSL(Domain Specific Language)的用法。

scala> val df = spark.read.json("file:///opt/spark/examples/src/main/resources/people.json")
df: org.apache.spark.sql.DataFrame = [age: bigint, name: string]                

scala> df.show()
+----+-------+                                                                  
| age|   name|
+----+-------+
|null|Michael|
|  30|   Andy|
|  19| Justin|
+----+-------+


scala> df.select("name").show()
+-------+                                                                       
|   name|
+-------+
|Michael|
|   Andy|
| Justin|
+-------+


scala> df.select(df("name"), df("age") + 1).show()
+-------+---------+                                                             
|   name|(age + 1)|
+-------+---------+
|Michael|     null|
|   Andy|       31|
| Justin|       20|
+-------+---------+


scala> df.filter(df("age") > 21).show()
+---+----+
|age|name|
+---+----+
| 30|Andy|
+---+----+


scala> df.groupBy("age").count().show()
+----+-----+                                                                    
| age|count|
+----+-----+
|  19|    1|
|null|    1|
|  30|    1|
+----+-----+


scala>

以上是对Spark SQL的SQLContext和HiveContext基本用法的一些总结,都是采用spark-shell工具举的例子。实际上由于spark-shell是运行scala程序片段的工具,上述例子完全可以改成独立的应用程序。我将在下一篇博文当中尝试使用Scala、Java和python来编写独立的程序来操作上面的示例hive数据库orderdb,可以适当使用一些较为复杂的SQL来统计分析数据。

 

 

 

 

您可能感兴趣的文档:

--结束END--

本文标题: 理解Spark SQL(二)—— SQLContext和HiveContext

本文链接: https://lsjlt.com/news/2527.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 理解Spark SQL(二)—— SQLContext和HiveContext
    使用Spark SQL,除了使用之前介绍的方法,实际上还可以使用SQLContext或者HiveContext通过编程的方式实现。前者支持SQL语法解析器(SQL-92语法),后者支持SQL语法解析器和HiveSQL语法解析器,默认为Hiv...
    99+
    2017-07-25
    理解Spark SQL(二)—— SQLContext和HiveContext
  • 理解Spark SQL(一)—— CLI和ThriftServer
    Spark SQL主要提供了两个工具来访问hive中的数据,即CLI和ThriftServer。前提是需要Spark支持Hive,即编译Spark时需要带上hive和hive-thriftserver选项,同时需要确保在$SPARK_HOM...
    99+
    2017-01-02
    理解Spark SQL(一)—— CLI和ThriftServer
  • 理解Spark SQL(三)—— Spark SQL程序举例
    上一篇说到,在Spark 2.x当中,实际上SQLContext和HiveContext是过时的,相反是采用SparkSession对象的sql函数来操作SQL语句的。使用这个函数执行SQL语句前需要先调用DataFrame的createO...
    99+
    2020-09-04
    理解Spark SQL(三)—— Spark SQL程序举例
  • 理解Spark运行模式(二)(Yarn Cluster)
    上一篇说到Spark的yarn client运行模式,它与yarn cluster模式的主要区别就是前者Driver是运行在客户端,后者Driver是运行在yarn集群中。yarn client模式一般用在交互式场景中,比如spark sh...
    99+
    2020-11-26
    理解Spark运行模式(二)(Yarn Cluster)
  • 怎么理解spark的自定义分区和排序及spark与jdbc
    这篇文章将为大家详细讲解有关怎么理解spark的自定义分区和排序及spark与jdbc,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。//自定义分区import org.apache...
    99+
    2023-06-02
  • MyBatis之Mapper XML 文件详解(二)-sql和入参
    sql这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。它可以被静态地(在加载参数) 参数化. 不同的属性值通过包含的实例变化. 比如:<sql id="userColu...
    99+
    2024-04-02
  • 如何理解Spark Streaming的数据可靠性和一致性
    如何理解Spark Streaming的数据可靠性和一致性,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。眼下大数据领域最热门的词汇之一便是流计算了,其中最耀眼的项目无疑是来自S...
    99+
    2023-06-19
  • 详解Unique SQL原理和应用
    目录1、什么是Unique SQL2、Unique SQL如何统计3、如何使用Unique SQL4、用Unique SQL辅助定位问题4.1查询异常的行活动导致的磁盘争用4.2查询...
    99+
    2024-04-02
  • LINQ To SQL和ORM怎么理解
    这篇文章主要讲解了“LINQ To SQL和ORM怎么理解”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“LINQ To SQL和ORM怎么理解”吧!LINQ To SQL和ORM的理解1、没...
    99+
    2023-06-17
  • 理解sql中的group by和having
    下面通过一个例子,来简单解释group by的原理。 1. GROUP BY 假设我们有表1,表名为test: 如果我们执行如下SQL语句: SELECT name FROM test GROUP BY name 我们很容易可以...
    99+
    2019-09-16
    理解sql中的group by和having
  • 如何理解sql注入和xss攻击
    SQL注入攻击是指通过构建特殊的输入作为参数传入Web应用程序,一般是SQL语法里的一些组合,通过执行SQL语句进而执行攻击者所要的操作;而Xss攻击称为跨站脚本攻击,它是一种经常出现在web应用中的计算机安全漏洞,因Web应用程序对用户的...
    99+
    2024-04-02
  • SQL Server权限管理和数据恢复详解
    Microsoft公司的SQL Server是企业中广泛使用的数据库,现在很多的电子商务网站、企业信息化等都是基于SQL Server进行搭建部署的。随着网络的不断发展,非法用户技术的日益增长,针对SQL ...
    99+
    2024-04-02
  • 解析Mybatis Porxy动态代理和sql解析替换问题
    目录JDK常用核心原理概述过程详解JDK动态代理sql语句解析替换JDK常用核心原理 概述 在 Mybatis 中,常用的作用就是讲数据库中的表的字段映射为对象的属性,在进入Myba...
    99+
    2024-04-02
  • 如何理解Oracle和MySQL中短小精悍的SQL
    这篇文章将为大家详细讲解有关如何理解Oracle和MySQL中短小精悍的SQL,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 如果让你写一个简单牛叉的SQ...
    99+
    2024-04-02
  • 如何理解ABAP的OPEN SQL和Hybris Commerce的Flexible Search
    如何理解ABAP的OPEN SQL和Hybris Commerce的Flexible Search,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。在ABAP应用里...
    99+
    2023-06-04
  • 如何理解SQL Server数据体系和应用程序逻辑
    这篇文章给大家介绍如何理解SQL Server数据体系和应用程序逻辑,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。  很多人都用过SQLServer数据库,但是很少的人真正理解SQLS...
    99+
    2024-04-02
  • 二维码文件处理:PHP和NumPy的最佳解决方案是什么?
    二维码是一种广泛应用于生活和工作中的二维码文件,其可存储大量信息,因此在日常生活中越来越普遍。然而,对于二维码文件的处理,往往需要使用一些特殊的工具和技术,其中包括PHP和NumPy。那么PHP和NumPy的最佳解决方案是什么呢?本文将对这...
    99+
    2023-06-13
    numpy 二维码 文件
  • SVM算法的理解及其Python实现多分类和二分类问题
    目录原理分类理论确定最大间距SVM多分类Python实现多分类二分类总结原理 SVM被提出于1964年,在二十世纪90年代后得到快速发展并衍生出一系列改进和扩展算法,在人像识别、文本...
    99+
    2023-02-01
    SVM算法理解 Python实现多分类 Python实现二分类
  • 关于sql和mysql对于别名不能调用的理解有哪些
    本篇文章为大家展示了关于sql和mysql对于别名不能调用的理解有哪些,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。在写sql的时候,由于有部分语句别名不能调用,百...
    99+
    2024-04-02
  • 带你理解什么是sql注入攻击、xss攻击和cors攻击
    目录SQL注入SQL注入攻击的总体思路:SQL注入攻击实例:如何应对:XSS攻击非持久 XSS攻击:解决的具体方案:CORS攻击简单请求:非简单请求:SQL注入 SQL注入就是通过把...
    99+
    2023-05-16
    sql注入攻击 xss攻击 cors攻击
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作