SparkSQL介绍

文章目录

  • SparkSQL的前世今生
    • Shark
    • SharkSQL
    • C位出道
  • Spark SQL的最佳搭档Dataframe
    • 由列组成的数据集Dataframe
    • DataFrame创建的方式
  • SparkSQL DataSource
  • Spark SQL 底层架构
  • SparkSQL读取MySQL数据库
  • Spark on Hive整合

SparkSQL的前世今生

Spark SQL是Spark用于处理结构化数据的模块
Shark是SparkSQL的前身,Hive是Shark的前身

Shark

       Shark是基于Spark计算框架之上且兼容Hive语法的SQL执行引擎,由于底层的计算采用了Spark,性能比MapReduce的Hive普遍快2倍以上,当数据全部load在内存的话,将快10倍以上,因此Shark可以作为交互式查询应用服务来使用。
       除了基于Spark的特性外,Shark是完全兼容Hive的语法,表结构以及UDF函数等,已有的HiveSql可以直接进行迁移至Shark上
       Shark底层依赖于Hive的解析器,查询优化器,但正是由于Shark的整体设计架构对Hive的依赖性太强,难以支持其长远发展,比如不能和Spark的其他组件进行很好的集成,无法满足Spark的一栈式解决大数据处理的需求

SharkSQL

       由于Shark对于Hive的太多依赖(如采用Hive的语法解析器、查询优化器等),制约了Spark的One Stack to rule them all(一栈式)的既定方针,制约了Spark各个组件的相互集成,所以才有了SparkSQL。
       相对于Shark,SparkSQL有一下优势:

  1. SparkSQL产生的根本原因,其完全脱离了Hive的限制
  2. SparkSQL支持查询原生的RDD,这点就极为关键了。RDD是Spark平台的核心概念,是Spark能够高效的处理大数据的各种场景的基础SparkSQL支持查询原生的RDD,这点就极为关键了。RDD是Spark平台的核心概念,是Spark能够高效的处理大数据的各种场景的基础
  3. 能够在Scala中写SQL语句。支持简单的SQL语法检查,能够在Scala中写Hive语句访问Hive数据,并将结果取回作为RDD使用能够在Scala中写SQL语句。支持简单的SQL语法检查,能够在Scala中写Hive语句访问Hive数据,并将结果取回作为RDD使用

C位出道

       SparkSQL提供了非常强大的API,让分析人员用一次,就会为之倾倒,为之着迷,为之至死不渝。最近出来另个组合名称:

  1. SparkSQL on Hive (当红流量小生,很常用)
    Hive只是作为了存储的角色
    SparkSQL作为计算的角色
  2. Hive on Spark
    Hive承担了一部分计算(解析SQL,优化SQL…)的和存储
    Spark作为了执行引擎的角色

Spark SQL的最佳搭档Dataframe

由列组成的数据集Dataframe

       与RDD类似,DataFrame也是一个分布式数据容器。然而DataFrame更像传统数据库的二维表格,除了数据以外,还掌握数据的结构信息,即schema。同时,与Hive类似,DataFrame也支持嵌套数据类型(struct、array和map)。从API易用性的角度上 看,DataFrame API提供的是一套高层的关系操作,比函数式的RDD API要更加友好,门槛更低。
SparkSQL介绍_第1张图片

DataFrame创建的方式

  1. 读json文件(不能是嵌套格式的json)
val jsonDF = sqlContext.read().format(“json”).load(“path”)
val jsonDF = sqlContext.read().json(“path”)
  1. 读取json格式的RDD
    RDD的元素类型是String,但是格式必须是JSON格式
val jsonDF = sqlContext.read().json(jsonRDD)
  1. 读取parquet文件创建DataFrame
  • parquet格式的文件是一个应用面很广的压缩格式的文件,它更少地占用磁盘空间
  • 直接打开parquet格式的文件是看不懂的,通过hive SparkSQL可以读懂
val parquetDF = sqlContext.read.format("parquet").load("path")
  1. RDD
    通过非json格式的RDD来创建出来一个DataFrame
           1). 反射的方式创建DataFrame
                  底层原理,直接调用toDF方法。实际上会通过反射的方式去调用Person对象的字段以及每一个字段的类型, 拿到每一个字段的名字和类型作为DF的列的名字和类型。
val people = sc.textFile("Peoples.txt")
				   .map(_.split(","))
				   .map(p => Person(p(1), p(2).trim.toInt))
				   .toDF()
people.registerTempTable("people") //注册成临时表
val teenagers = sqlContext.sql("SELECT name, age FROM people WHERE age >= 6 AND age <= 19")
/**
* 对dataFrame使用map算子后,返回类型是RDD
* 通过索引号去row对象中取值
*/
teenagers.map(t => "Name: " + t(0)).foreach(println)
/**
* 通过列名获取row对象中对应的值
*/
teenagers.map(t => "Name: " + t.getAs[String]("name")).foreach(println)

Peoples.txt文件中的数据如下:

1,Spark,7
2,Hadoop,11
3,Flink,5

              弊端:修改列名以及列的类型的时候,需要去修改代码,打成jar包,发送至client提交任务spark-submit等操作
       2). 动态创建Schema的方式创建DataFrame
           ①. RDD->Row RDD
           ②. 创建schema
           ③. Row RDD+schema = DF

val people = sc.textFile("scores.txt")   
val schemaString = "clazzaa:String scoreaa:Integer"
//如果schema中制定了除String以外别的类型,在构建rowRDD的时候要注意指定类型,例如:p(2).toInt 
val rowRDD = people.map(_.split("\t")).map(p => Row(p(0), p(1).toInt))
//创建结构信息
val schema =
	StructType(
		schemaString.split(" ")
			.map(fieldName => 
				StructField(fieldName.split(":")(0),
                if (fieldName.split(":")(1).equals("String")) StringType else IntegerType,
                true)
                 )
           )
val peopleDataFrame = sqlContext.createDataFrame(rowRDD, schema)

SparkSQL中也可以对文件进行自动推测分区

SparkSQL DataSource

DataFrame支持丰富的数据源
SparkSQL介绍_第2张图片

Spark SQL 底层架构

SparkSQL介绍_第3张图片

SparkSQL读取MySQL数据库

未完待续

Spark on Hive整合

未完待续

你可能感兴趣的:(大数据,Spark)