SparkSQL的概念
Spark SQL is Apache Spark’s module for working with structured data.
Spark SQL是Spark用于结构化数据(Structured data)处理的Spark模块。
对于开发人员来说,SparkSQL可以简化RDD的开发,提高开发效率,并且执行效率非常快。SparkSQL为了简化RDD的开发,提高开发效率,提供了两个变成抽象(DataFrame和DataSet),类似Spark Core的RDD。
SparkSQL特点
- 将SQL查询和Spark编程整合
- 使用相同的方式连接不同的数据源
- 兼容Hive
- 标准的数据连接:使用JDBC或者ODBC连接
DataFrame&DataSet
1,DataFrame
在Spark中,DataFrame是一种以RDD为基础的分布式数据集,类似传统数据库中的二维表格。DataFrame与RDD的主要区别在于,DataFrame带有schema元信息,即DataFrame所表示的二维表数据集的每一列都带有名称和类型。而RDD只有数据。
DataFrame是为数据提供了Schema的视图,可以将它看作数据库的一张表来对待。
DataFrame也是懒执行的,但是性能比RDD要高,主要原因:优化的执行计划,即查询计划通过Spark catalyst optimiser进行优化
2,DateSet
DataSet是分布式数据集合,DataSet是Spark1.6中添加的一个新的抽象,是DataFrame的一个扩展。它提供了RDD的优势(强类型,使用强大的lambda函数的能力)以及Spark SQL优化执行引擎的优点。
- DataSet是DataFrame API的一个扩展,是SparkSQL最新的数据抽象
- 用户友好的API风格,既有类型安全检查,也具有DataFrame的查询优化特性
- 用样例类对DataSet中定义数据的结构信息,样例类中的每个属性的名称直接映射到DataSet中的字段名称
- DataFrame = DataSet[Row],Row也是一个类型,所有的表星系都用Row来表示,获取数据时需要指定顺序
SparkSQL核心编程
Spark Core中如果想要执行应用程序,需要首先构建上下文环境对象SparkContext,Spark SQL可以理解为对Spark Core的一种封装,不仅在模型上进行了封装,上下文环境对象也进行了封装。
SparkSession是Spark最新的SQL查询起始点,SparkSession中封装了SparkContext。
如果构建DatsFrame?
- 从Spark数据源进行创建spark.read.(json、csv)。如果从内存中读取数据,Spark可以知道数据类型具体是什么。如果是数字默认为Int;但是,如果从文件中读取的数字,不能确定是什么类型,所以用bigint接收,可以和Long类型转换,但是和Int不能进行转换
- 从一个存在的RDD进行转换,rdd.toDF(“列名1”, “列名2”)
- 可以从Hive Table进行查询返回
SQL语法
SQL语法风格是指我们查询数据的时候使用SQL语句来查询,这种风格的查询必须要有临时视图或者全局视图来辅助。
对DataFrame创建一个临时表:df.createOrReplaceTempView(“表名”),视图是查询结果集,只能查询不能修改。
DSL语法
DataFrame提供了一个特定领域语言(domain-specific language)去管理结构化的数据。它可以在Scala,java,Python和R中使用DSL,使用DSL语法风格不必去创建临时视图。
df.selet(“列名”)
df.selet(“单引号+列名+操作”)
如果构建DataSet?
DataSet是具有强类型的数据集合,需要提供对应的类型信息。
- 使用样例类序列创建DataSet
case class Person(id:Int, name:String)
val list = List(Person(), Person())
list.toDS - DataFrame转换为DataSet
df.as[case class 类名]
import org.apache.spark.SparkConf
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}
object Spark_SQL {
def main(args: Array[String]): Unit = {
//TODO 创建SparkSQL的运行环境
val sparkConf = new SparkConf().setMaster("local[*]").setAppName("sparkSQL")
//SparkSession主构造方法,辅助构造方法私有化
//val spark = new SparkSession()
val sparkSession: SparkSession = SparkSession.builder().config(sparkConf).getOrCreate()
//TODO 执行逻辑操作
//RDD
//DataFrame
val dataframe: DataFrame = sparkSession.read.json("src/user.json")
//dataframe.show()
//DataFrame SQL
dataframe.createOrReplaceTempView("user")
sparkSession.sql("select username from user").show()
//DataFrame DSL
//在使用DataFrame时,如果涉及到转换操作,需要引入转换规则
import sparkSession.implicits._
dataframe.select('age+1).show()
//DataSet
//DateFrame是特定泛型的DataSet
val seq = Seq(1, 2, 3)
val ds: Dataset[Int] = seq.toDS()
ds.show()
//RDD<=>DataFrame
val rdd = sparkSession.sparkContext.makeRDD(List((1, "zhangsan", 20), (2, "lisi", 50)))
val dataFrame: DataFrame = rdd.toDF("id", "name", "age").toDF()
val rdd1: RDD[Row] = dataFrame.rdd
//DataFrame<=>DataSet
val ds1: Dataset[User] = dataFrame.as[User]
ds1.toDF()
//RDD<=>DataSet
//TODO 关闭环境
sparkSession.close()
}
case class User(id:Int, name:String, age:Int)
}
SparkSQL连接Hive
如果想连接外部已经部署好的Hive,需要以下的步骤:
- 将hive.site.xml拷贝到conf目录下
- 把MySQL的驱动拷贝到jars/目录下
- 重启spark-shell
IDEA中SparkSQL操作Hive
- hive.site.xml放在ClassPath中
- 启用Hive的支持
- 增加对应的依赖关系(包含Mysql的驱动)