Spark SQL是Spark用来处理结构化数据的一个模块,它提供了一个编程抽象叫做DataFrame并且作为分布式SQL查询引擎的作用。
我们已经学习了Hive,它是将Hive SQL转换成MapReduce然后提交到集群上执行,大大简化了编写MapReduce的程序的复杂性,由于MapReduce这种计算模型执行效率比较慢。所有Spark SQL的应运而生,它是将Spark SQL转换成RDD,然后提交到集群执行,执行效率非常快!
与RDD类似,DataFrame也是一个分布式数据容器。然而DataFrame更像传统数据库的二维表格,除了数据以外,还记录数据的结构信息,即schema。同时,与Hive类似,DataFrame也支持嵌套数据类型(struct、array和map)。从API易用性的角度上 看,DataFrame API提供的是一套高层的关系操作,比函数式的RDD API要更加友好,门槛更低。由于与R和Pandas的DataFrame类似,Spark DataFrame很好地继承了传统单机数据分析的开发体验。
SparkSQL很多API和RDD的类似。
Spark 1.x和Spark 2.x在企业中都在使用,所以都得掌握。
首先得有SparkSQL的环境,在pom.xml中假如以下内容:
org.apache.spark
spark-sql_2.11 //都得和自己的spark环境一一对应
${spark.version}
maven 仓库:http://mvnrepository.com/
Spark 1.x实现:
package day04
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, SQLContext}
import org.apache.spark.{SparkConf, SparkContext}
/**
* @author WangLeiKai
* 2018/9/28 15:38
*/
case class User(id:Int,name : String,age:Int,fv:Int)
object SQLDemo1 {
def main(args: Array[String])= {
//程序的入口
val conf = new SparkConf().setAppName("SQLDemo1").setMaster("local[*]")
val sc = new SparkContext(conf)
//包装SparkContext
val sqlContext = new SQLContext(sc)
val lines = sc.textFile("d://data//person.txt")
val boyRDD: RDD[User] = lines.map(tp => {
val fields = tp.split(",")
val id = fields(0).toInt
val name = fields(1)
val age = fields(2).toInt
val fv = fields(3).toInt
User(id, name, age, fv)
})
//导入sqlContext的隐式转换
import sqlContext.implicits._
//将RDD转换成DataFrame
val f: DataFrame = boyRDD.toDF
//注册临时表
f.registerTempTable("t_boy")
//执行SQL语句
val result = sqlContext.sql("select id,name,age,fv from t_boy order by fv desc,age asc")
//调用action 因为sql类似于transformation 是lazy的
result.show()
sc.stop()
}
}
Spark 2.x实现
package day04
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, Dataset, SQLContext, SparkSession}
import org.apache.spark.{SparkConf, SparkContext}
/**
* @author WangLeiKai
* 2018/9/28 15:38
*/
case class User(id:Int,name : String,age:Int,fv:Int)
object SQLDemo4 {
def main(args: Array[String])= {
//创建SparkSession 如果有Spark Context 则调用,如果没有则创建
val spark = SparkSession
.builder()
.appName("SQLDemo4")
.master("local[*]")
.getOrCreate()
//导入spark的隐式转换
import spark.implicits._
val lines = spark.read.textFile("d://data//person.txt")
//注意:返回值是DataSet类型
val dst: Dataset[User] = lines.map(tp => {
val fields = tp.split(",")
val id = fields(0).toInt
val name = fields(1)
val age = fields(2).toInt
val fv = fields(3).toInt
User(id, name, age, fv)
})
//创建临时视图
dst.createTempView("t_boy")
val result = spark.sql("select id,name,age,fv from t_boy order by fv desc,age asc")
result.show()
spark.stop()
}
}