1 spark SQL
1.1 发展过程
1.2 解决的问题
-
Spark SQL使用Hive解析SQL生成AST语法树, 将其后的逻辑计划生成, 优化, 物理计划都自己完成, 而不依赖Hive -
执行计划和优化交给优化器
Catalyst -
内建了一套简单的
SQL解析器, 可以不使用HQL, 此外, 还引入和DataFrame这样的DSL API, 完全可以不依赖任何Hive的组件 -
Shark只能查询文件,Spark SQL可以直接降查询作用于RDD
1.3 适用场景
| 定义 | 特点 | 举例 | |
|---|---|---|---|
|
结构化数据 |
有固定的 |
有预定义的 |
关系型数据库的表 |
|
半结构化数据 |
没有固定的 |
没有固定的 |
指一些有结构的文件格式, 例如 |
|
非结构化数据 |
没有固定 |
没有固定 |
指文档图片之类的格式 |
-
-
SparkSQL主要用于处理
1.4 SparkSession
SparkContext在读取文件的时候,读取出来的是 RDD, 不包含 Schema(结构化)信息。所以出现了SparkSession作为SparkSQL的入口点,
1.5 Catalyst优化器
SparkSQL整体架构
-
-
收到
SQL语句以后, 将其交给Catalyst,Catalyst负责解析SQL, 生成执行计划等 -
Catalyst的输出应该是RDD的执行计划 -
简单优化过程
1.6 Dataset
-
-
Dataset提供了访问对象中某个特定字段的能力, 不用像RDD一样每次都要针对整个对象做操作 -
Dataset和RDD不同, 如果想把Dataset[T]转为RDD[T], 则需要对Dataset底层的InternalRow
1.7 DataFrame
-
-
DataFrame一般处理结构化数据和半结构化数据 -
DataFrame具有数据对象的 Schema 信息 -
可以使用命令式的
API操作DataFrame, 同时也可以使用SQL操作DataFrame -
DataFrame
1.8 Dataset 和 DataFrame 的异同
DataFrame是Dataset的一种特殊情况, 也就是说DataFrame是Dataset[Row]的别名。DataFrame和Dataset所表达的语义不同
DataFrame表达的含义是一个支持函数式操作的表, 而Dataset表达是是一个类似RDD的东西,Dataset可以处理任何对象
代码解析:
def dataframe4(): Unit = {
val spark = SparkSession.builder()
.appName("dataframe1")
.master("local[6]")
.getOrCreate()
import spark.implicits._
val personList = Seq(Person("zhangsan", 15), Person("lisi", 20))
// DataFrame 是弱类型的
val df: DataFrame = personList.toDF()
df.map( (row: Row) => Row(row.get(0), row.getAs[Int](1) * 2) )(RowEncoder.apply(df.schema))
.show()
// DataFrame 所代表的弱类型操作是编译时不安全
// df.groupBy("name, school")
// Dataset 是强类型的
val ds: Dataset[Person] = personList.toDS()
ds.map( (person: Person) => Person(person.name, person.age * 2) )
.show()
// Dataset 所代表的操作, 是类型安全的, 编译时安全的
// ds.filter( person => person.school )
}


