- 介绍
SparkSQL引入了一种新的RDD——SchemaRDD,SchemaRDD由行对象(Row)以及描述行对象中每列数据类型的Schema组成;SchemaRDD很象传统数据库中的表。SchemaRDD可以通过RDD、Parquet文件、JSON文件、或者通过使用hiveql查询hive数据来建立。SchemaRDD除了可以和RDD一样操作外,还可以通过registerTempTable注册成临时表,然后通过SQL语句进行操作。
值得注意的是:
lSpark1.1使用registerTempTable代替1.0版本的registerAsTable
lSpark1.1在hiveContext中,hql()将被弃用,sql()将代替hql()来提交查询语句,统一了接口。
l使用registerTempTable注册表是一个临时表,生命周期只在所定义的sqlContext或hiveContext实例之中。换而言之,在一个sqlContext(或hiveContext)中registerTempTable的表不能在另一个sqlContext(或hiveContext)中使用。
另外,Spark1.1提供了语法解析器选项spark.sql.dialect,就目前而言,Spark1.1提供了两种语法解析器:sql语法解析器和hiveql语法解析器。
lsqlContext现在只支持sql语法解析器(SQL-92语法)
lhiveContext现在支持sql语法解析器和hivesql语法解析器,默认为hivesql语法解析器,用户可以通过配置切换成sql语法解析器,来运行hiveql不支持的语法,如select 1。
l切换可以通过下列方式完成:
l在sqlContexet中使用setconf配置spark.sql.dialect
l在hiveContexet中使用setconf配置spark.sql.dialect
l在sql命令中使用 set spark.sql.dialect=value
SparkSQL1.1对数据的查询分成了2个分支:sqlContext 和 hiveContext。至于两者之间的关系,hiveSQL继承了sqlContext,所以拥有sqlontext的特性之外,还拥有自身的特性(最大的特性就是支持hive)。
- 演示版本:spark-1.4.1-bin-hadoop2.6
- sqlContext
- 使用Case Class定义RDD
- 介绍
对于Case Class方式,首先要定义Case Class,在RDD的Transform过程中使用Case Class可以隐式转化成SchemaRDD,然后再使用registerTempTable注册成表。注册成表后就可以在sqlContext对表进行操作,如select 、insert、join等。注意,case class可以是嵌套的,也可以使用类似Sequences 或 Arrays之类复杂的数据类型。 - 演示代码
scala> val sqlContext = new org.apache.spark.sql.SQLContext(sc) scala> import sqlContext.implicits._ scala> case class Person(name:String,age:Int) scala> val people=sc.textFile("hdfs://cloud25:9000/data/people.txt").map(_.split(",")).map(p=>Person(p(0),p(1).trim.toInt)).toDF() scala> teenagers.map(t => "Name: " + t(0)).collect().foreach(println)
- 介绍
- parquest演示
- 介绍
sqlContext可以读取parquet文件,由于parquet文件中保留了schema的信息,所以不需要使用case class来隐式转换。sqlContext读入parquet文件后直接转换成SchemaRDD,也可以将SchemaRDD保存成parquet文件格式。
- 演示代码
scala> import sqlContext.implicits._ scala> sqlContext.setConf("spark.sql.parquet.binaryAsString", "true") //解决文件中parquet中binary字段的问题 scala> val wikiData = sqlContext.parquetFile("hdfs://cloud25:9000/data/wiki_parquet").toDF() scala> wikiData.count() scala> wikiData.registerTempTable("wikidata") scala> val countResult = sqlContext.sql("SELECT COUNT(*) FROM wikiData").collect() scala> val queryResult= sqlContext.sql("SELECT username, COUNT(*) AS cnt FROM wikiData WHERE username <> '' GROUP BY username ORDER BY cnt DESC LIMIT 10") scala> queryResult.collect().foreach(println)
- 介绍
- Join演示
- 介绍
sqlContext可以从多个种类的SchemaRDD中执行join操作 - 演示代码
scala> val sqlContext = new org.apache.spark.sql.SQLContext(sc) scala> import sqlContext.implicits._ scala> case class Person(name:String,age:Int) scala> val people=sc.textFile("hdfs://cloud25:9000/data/people.txt").map(_.split(",")).map(p=>Person(p(0),p(1).trim.toInt)).toDF() scala> people.saveAsParquetFile("hdfs://cloud25:9000/data/people.parquet") scala> val parquetFile = sqlContext.parquetFile("hdfs://cloud25:9000/data/people.parquet") scala> people.registerTempTable("people") scala> parquetFile.registerTempTable("parquetFile") scala> val jointbls = sqlContext.sql("SELECT people.name FROM people join parquetFile where people.name=parquetFile.name") scala> jointbls.collect.foreach(println)
- 介绍
- 使用Case Class定义RDD
- hiveContext
- 描述
到1.4.1一版本,可以动过两种方式与hive集成,第一种是使用已经部署好的metastore,如果使用这种方式需要在spark中添加hive的相关配置,第二种:如果没有配置相关的信息,hiveContext会在当前目录自己创建metadata_db以及warehouse - 配置过程
以下配置流程仅仅针对描述中的第一种情况(使用已有metastore)- 后台启动metasore服务
- 创建/opt/cloud/spark-1.4.1-bin-hadoop2.6/conf/hive-site.xml文件,并编辑内容如下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <property> <name>hive.metastore.uris</name> <value>thrift://cloud25:9083</value> <description>Thrift URI for the remote metastore. Used by metastore client to connect to remote metastore.</description> </property> </configuration>
- 启动spark-shell:./spark-shell --master=spark://cloud25:7077 --executor-memory=2g
- 代码演示
- 使用已有metastore的代码
scala> val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc) scala> hiveContext.sql("select count(*) from SOGOUQ1 where S_SEQ=1 and C_SEQ=2").collect.foreach(println) scala> hiveContext.sql("select count(*) from SOGOUQ1 where S_SEQ=1 and C_SEQ=2 and WEBSITE like '%baidu%'").collect.foreach(println) scala> hiveContext.sql("select WEBSESSION,count(WEBSESSION) as cw from SOGOUQ1 group by WEBSESSION order by cw desc limit 10").collect.foreach(println)
- 独立维护metastore的代码
scala> val hiveContext = new org.apache.spark.sql.hive.HiveContext(sc) scala> hiveContext.sql("CREATE TABLE IF NOT EXISTS src (key INT, value STRING)")
- 使用已有metastore的代码
- 性能比较
下列的表格给出了hive基于hadoop以及spark的性能对比,由于都没有Hadoop,Spark集群都没有做优化,所以结果仅供参考
语句 hive on hadoop(s) hive on spark(s) Select count(*) from SOGOUQ1; 29.291 2.496752 select count(*) from SOGOUQ1 where S_SEQ=1 and C_SEQ=2; 26.421 2.83421 select count(*) from SOGOUQ1 where S_SEQ=1 and C_SEQ=2
and WEBSITE like '%baidu%';26.122 1.692844 select WEBSESSION,count(WEBSESSION) as cw from
SOGOUQ1 group by WEBSESSION order by cw desc limit 10;56.313 5.857438
- 描述
Spark入门之六:SparkSQL实战
最新推荐文章于 2023-06-04 13:06:06 发布