SparkSQL03

1.回顾前面的内容

DF是个数据集,是按列处理的,是关系数据表里面的一张表

RDD转成DF,加载数据进来就是RDD,第一种case class 通过反射的机制来拿到外面的DF,第二种通过是手工编程的方式,structType  好处是可以指定字段的类型,坏处是有点麻烦。structField这里面装的是列的名,列的数据类型,是否为空,SQL2的内容一定要熟练到脱口而出。

2.External Data Source API (外部数据源接口)*****

(1)无论是hive spark mapreduce 等无论哪种分布式框架,必然首先要加载数据。

但是数据可能有好几种格式:json,parquet,text,jdbc。。。。+compression

数据的来源:HDFS 、Hbase 、S3(这是亚马逊的文件系统)、oss(阿里云对象存储)

3.Generic Load/Save Functions

val usersDF = spark.read.load("examples/src/main/resources/users.parquet")
usersDF.select("name", "favorite_color").write.save("namesAndFavColors.parquet")
//很多时候读取进来都不可能是你想要的格式,你可以转为自己想要的格式

4.读取MySQL数据到spark

 val spark=SparkSession.builder().master("local[2]").appName("ExyDSApp").getOrCreate()


    val empDF = spark.read.format("jdbc").options(Map("url"->"jdbc:mysql://192.168.137.251:3306/ruozedb?user=root&password=123456","dbtable"->"user",
      "driver"->"com.mysql.jdbc.Driver")).load().show()

//这就是从MySQL中读取出来的数据,这就显得很简单了,不需要Sqoop那样麻烦的抽取。

5.Spark导入MySQL数据,创建临时表

./spark-sql --master --jars /home/hadoop/software/mysql-connector-java-5.1.46/mysql-connector-java-5.1.46.jar --driver-class-path /home/hadoop/software/mysql-connector-java-5.1.46/mysql-connector-java-5.1.46.jar 

//这里有个坑,在jars的说明中是包含了driver的,事实是没有包含的,所以需要自己加进去的。


   CREATE TEMPORARY VIEW emp_mysql
      USING org.apache.spark.sql.jdbc
    OPTIONS (
      url "jdbc:mysql://192.168.137.251:3306/ruozedata_basic03?user=root&password=123456",
    dbtable "emp",
    driver "com.mysql.jdbc.Driver"
    );

//创建临时的表,在sql中show出来后面有个true


empDF.write.format("jdbc").option("url","jdbc:mysql://192.168.137.251:3306/ruozedb?user=root&password=123456").option("dbtable","test_emp").option("driver","com.mysql.jdbc.Driver").option("user","root").option("password","123456").save()


//将表写到mysql去,但是数据结构类型会变,不影响,例如varchar会变成text

以上就读写关系型数据的大概流程,工作用到了到官网这儿找http://spark.apache.org/docs/latest/sql-data-sources-load-save-functions.html

6.Predicate Push  Down(谓词下压)

这个东西对大数据处理有很大的影响!

7.读外部数据源的三种实现机制  *****

目的:如何更有效的读取外部数据源

(1)TableScan

trait TableScan {
  def buildScan(): RDD[Row]
}

//这个相当于将我们的整张表扫描,扫描出来后变成一个RDD Row,如下图所示,他不做任何的预处理,逮住就是直接干

DataS    disk        network            CPU    
1T----------》 1T----------》1T----------》1G /1M

(2)PrunedScan

trait PrunedScan {
  def buildScan(requiredColumns: Array[String]): RDD[Row]
}

//Pruned:裁剪的
这个方法,你可以传入你想要的列,做一个裁剪,明显网络传输的数据少多了嘛

DataS    disk        network            CPU    
1T----------》 10G----------》10G----------》1G /1M

(3)PrunedFilteredScan

trait PrunedFilteredScan {
  def buildScan(requiredColumns: Array[String], filters: Array[Filter]): RDD[Row]
}

//这个方法不但加入了列裁剪,还加了行过滤,这个方法不久最屌了

DataS    disk              CPU             network 
1T----------》 10G----------》1G----------》1G /1M

8.写外部数据源的实现机制  *****

一种基线,可用于通过插入方法向其中插入数据。*如果insert method中的overwrite为true,那么关系中的旧数据应该用*新数据覆盖。如果insert方法中的覆盖为false,则应追加新数据。insert tablerelation有以下三个假设。

* 1.它假设提供给insert方法*的数据(DataFrame中的行)与BaseRelation模式中的顺序字段完全匹配。

* 2.它假设这个关系的模式不会改变。*即使insert方法更新了模式(例如JSON或Parquet数据的关系可能在插入操作后进行*模式更新),也不会使用新模式。

* 3.它假设insert方法中提供的数据字段是可空的。*如果数据源需要检查字段的实际可空性,则需要在* insert方法中进行检查。

trait InsertableRelation {
  def insert(data: DataFrame, overwrite: Boolean): Unit
}
//这个先暂时放这儿

9.

(1)abstruct BaseRelation

它代表的是一个集合,集合里面装的是一些已经知道schema的Tupple,所以必须通过StructType制定schema

(2)trait RealtionProvider 

它产生BaseRelation

10.JDBCUtils

val conn: Connection = JdbcUtils.createConnectionFactory(url, properties)()

这是一个封装得很好的一个JDBC工具,在写这个工具的时候,可以参考着他来写。

猜你喜欢

转载自blog.csdn.net/qq_42064119/article/details/82502327