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工具,在写这个工具的时候,可以参考着他来写。