spark sql 数据类型转换_「大数据」(八十二)Spark之SparkSQL应用案例

【导读:数据是二十一世纪的石油,蕴含巨大价值,这是·情报通·大数据技术系列第[82]篇文章,欢迎阅读和收藏】

1 背景介绍

SparkSQL 引入了一种新的 RDD —— SchemaRDD , SchemaRDD 由行对象( Row )以及描述行对象中每列数据类型的 Schema 组成; SchemaRDD 很像传统数据库中的表。 SchemaRDD 可以通过 RDD 、 Parquet 文件、 JSON 文件、或者通过使用 hiveql 查询 hive 数据来建立。 SchemaRDD 除了可以和 RDD 一样操作外,还可以通过 registerTempTable 注册成临时表,然后通过 SQL 语句进行操作。

0f32b96178634a415b9c3b0e53ef0e97.png

值得注意的是:

l Spark1.1 使用 registerTempTable 代替 1.0 版本的 registerAsTable

l Spark1.1 在 hiveContext 中, hql() 将被弃用, sql() 将代替 hql() 来提交查询语句,统一了接口。

l 使用 registerTempTable 注册表是一个临时表,生命周期只在所定义的 sqlContext 或 hiveContext 实例之中。换而言之,在一个 sqlContext (或 hiveContext )中 registerTempTable 的表不能在另一个 sqlContext (或 hiveContext )中使用。

l Spark1.1 提供了语法解析器选项 spark.sql.dialect ,就目前而言, Spark1.1 提供了两种语法解析器: sql 语法解析器和 hiveql 语法解析器。

l sqlContext 现在只支持 sql 语法解析器( SQL-92 语法)

l hiveContext 现在支持 sql 语法解析器和 hivesql 语法解析器,默认为 hivesql 语法解析器,用户可以通过配置切换成 sql 语法解析器,来运行 hiveql 不支持的语法,如 select 1 。

切换可以通过下列方式完成:

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 )。

2 sqlContext

2.1 使用 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)

2.2 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)

2.3 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)

3 hiveContext

SparkSQL 1.4.1 版本,可以动过两种方式与 hive 集成,第一种是使用已经部署好的 metastore ,如果使用这种方式需要在 spark 中添加 hive 的相关配置,第二种 : 如果没有配置相关的信息, hiveContext 会在当前目录自己创建 metadata_db 以及 warehouse

配置过程

以下配置流程仅仅针对描述中的第一种情况(使用已有 metastore )

l 后台启动 metasore 服务

l 创建 /opt/cloud/spark-1.4.1-bin-hadoop2.6/conf/hive-site.xml 文件,并编辑内容如下:

hive.metastore.uris

thrift://cloud25:9083

Thrift URI for the remote metastore. Used by metastore client to connect to remote metastore.

启动 spark-shell:

./spark-shell --master=spark://cloud25:7077 --executor-memory=2g

应用案例:

l 使用已有 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)

l 独立维护 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)")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值