Shark,SparkSQL
Hive是Shark的前身,Shark是SparkSQL的前身
相对于Shark,SparkSQL有什么优势呢?
– SparkSQL产生的根本原因,其完全脱离了Hive的限制
– SparkSQL支持查询原生的RDD,这点就极为关键了。RDD是Spark平台的核心概念,是Spark能够高效的处理大数据的各种场景的基础
– 能够在Scala中写SQL语句。支持简单的SQL语法检查,能够在Scala中写Hive语句访问Hive数据,并将结果取回作为RDD使用
最近出来另个组合名称:
– Spark on Hive
• Hive只是作为了存储的角色
• SparkSQL作为计算的角色
– Hive on Spark
• Hive承担了一部分计算(解析SQL,优化SQL…)的和存储
• Spark作为了执行引擎的角色
DataFrame
与RDD类似,DataFrame也是一个分布式数据容器。然而DataFrame更像传统数据库的二维
表格,除了数据以外,还掌握数据的结构信息,即schema。同时,与Hive类似,
DataFrame也支持嵌套数据类型(struct、array和map)。从API易用性的角度上 看,
DataFrame API提供的是一套高层的关系操作,比函数式的RDD API要更加友好,门槛更低
DataFrame的底层封装的是RDD,只不过RDD的泛型是Row类型。
Spark SQL底层架构
首先拿到sql后解析一批未被解决的逻辑计划,再经过分析得到分析后的逻辑计划,再经过一批优化规则转换成一批最佳优化的逻辑计划,再经过SparkPlanner的策略转化成一批物理计划,随后经过消费模型转换成一个个的Spark任务执行。
谓词下推
将过滤表达式尽可能移动至靠近数据源的位置,以使真正执行时能直接跳过无关的数据。
再往高大上的方面说,就是将过滤表达式下推到存储层直接过滤数据,减少传输到计算层的数据量。
创建DataFrame的几种方式
- 读取json文件
sqlContext.read().format(“json”).load(path)
sqlContext.read().json(path)- 特点:
- 读取json的两种方式
- 读取json格式文件,列会按照ascii排序
- df.printSchema显示列的schema 信息
- df.show 默认显示20行,使用df.show(行数)
- 创建零时表的两种方式和区别(createOrReplaceTempView | createGrlobalTempView)
- dataframe可以转为 rdd。 df.rdd
- 读取嵌套格式的json数据,使用列明.属性即可
- 读取JsonArray格式的数据 explod()函数,导入隐式转换
- 特点:
- 读取json格式RDD
RDD的元素类型是String, 但是格式必须是Json格式 - 读取parquet文件创建DF
- RDD
- 通过给json格式的RDD来创建出来一个DataFrame,
- 通过反射的方式
- 动态创建schema的方式
- 通过给json格式的RDD来创建出来一个DataFrame,
sparkSQL的1.6和2.0区别
- 1.6中 spark 要创建 SQLContext(SparkContext)
2.0中 spark 要使用 SparkSession - 注册临时表不同
- 1.6中 df.registerTempTable
- 2.0 df.creteOrReplaceTemView 或者 df.createOrReplaceGlobalTempView
dateset 和 RDD的区别
- dataset 内部序列化机制与RDD不同,可以不用反序列化成对象调用对象的方法
- dataset是强类型,默认列名是value,操作上的方法比RDD多,RDD中的有的算子在dataset中都有
读取json格式的RDD/dataset
spark1.6中读取json格式的RDD,spark2.0只有读取json格式的DataSet
- 创建 ds:
.toDS()
将rdd变为 dataframe
1 反射方式:首先将RDD转为自定义类型,然后rdd.toDF()转为dataframe
2 动态创建schena
使用 spark.createDataFrame(rowRDD, structType)映射成dataFrame
ROW中数据的顺序要与创建schema的顺序一致
保存dataframe 成parquet
df1.write.Mode(SavaMode.Append).format(“parquet”).save("./data/parquet")
读取parquet格式加载DataFrame
val df2 = spark.read.parquet("./data/parquet")
将mySQL中的表加载成DataFrame
- 方式1
- 方式2
- 方式3
第四种
val infos =spark.read.jdbc(url=“jdbc:mysql://192.168.179.4:3306/spark”,table="(select * from person) t", properties)
可以将第一种方式中的 table的值变成 虚拟表,一个查询语句,但是要有表名
将DataFrame保存在mysql表中
df.write.mode(SaveMode.Overwrite).jdbc(url=“jdbc:mysql://xxx.xxx.xxx.xx:3306/spark”,table=“result”,properties)