一、External Data Source API外部数据源
1、各数据源加载数据概要介绍
MapReduce Hive Spark
加载数据:
(1)格式:json、parquet、text、jdbc......+压缩
(2)FileSystem:
HDFS:hdfs://......
HBase:
S3(亚马逊):S3a://
OSS(对象存储):
(3)HDFS join MySQL:
旧:sqoop MySQL to HDFS 再join
新:Spark一句代码
(4)加载数据技术发展
raw data ==> Ext DS API ==> DataFrame/Dataset
Core
SQL
Streaming
MLlib
....
==> RDD ==> DataFrame/Dataset
DF/DS是打通整个Spark生态栈的利器
(4)可以转为DataFrame的格式
json、csv、hdfs、hive、jdbc、s3、parquet、es、redis、cassandra、hbase.......
通过external data sourceAPI转为DF
(5)分为两大类
build-in:直接调用
3th-party:https://spark-packages.org/
--jar外部的包进来
(6)好处
read:
spark.read.format("csv/json/com.ruoze.com.XXX").load()
write:
df.write.format("").save()
2、以spark-csv为例看如何导SparkSQL不支持的数据源
(1)https://spark-packages.org/package/databricks/spark-csv
(2)GAV方式导入--packages
(3)spark-shell命令介绍
通常还要指定--classpath
(4)优缺点
优点:灵活
缺点:集群不能上网,很可能无法到maven库里下载。所以要打包成jar,然后--jars进来。
(5)csv特性
3、读取parquet文件
(1).read.load()先读取json文件
说明.read.load()方法默认读取parquet文件
spark.read.load("file:///opt/app/spark-2.3.2/spark-2.3.2-bin-2.6.0-cdh5.7.0/examples/src/main/resources/people.json").show
(2)读parquet文件
spark.read.load("file:///opt/app/spark-2.3.2/spark-2.3.2-bin-2.6.0-cdh5.7.0/
examples/src/main/resources/users.parquet").show
(3)分析.read.load()方法
所以该方法默认读取的文件格式是parquet
(4)指定.read.load()方法指定的默认文件格式
官网:
(5)读取parquet后SparkSQL的schema结构
users.printSchema()
(6)将当前parquet文件中的两行数据输出成text文件
users.select("name","favorite_color").write.format("text")
.option("compression","none")
.save("/opt/tmp/spark/parquet/")
意义:
很多时候读取进来都不可能是你想要的格式,你可以转为自己想要的格式
(7)解决转格式文件已存在的情况
第一种方法:
第二种方法:
4、操作JDBC的数据
HBinz001下的表emp读取到SparkSQL
val jdbcDF = spark.read.format("jdbc").option("url", "jdbc:mysql://hadoop002:3306/hbinz001").option("dbtable", "emp").option("user", "root").option("password", "123456").load()
报错:
(1)重启Spark-shell,指定--driver-class-path
成功启动。
(2)第二种方法,加多个option字段
val jdbcDF = spark.read.format("jdbc").option("url", "jdbc:mysql://hadoop002:3306/hbinz001").option("dbtable", "emp").option("user", "root").option("password", "123456").option("driver","com.mysql.jdbc.Driver").load()
5、Hive/SparkSQL跟MySQL做join
spark.sql("show tables").show
spark.sql("select * from dept").show
dept:Hive/SparkSQL
emp:mysql
(1)spark.table(" 表名")
spark内置方法直接将Hive表转为DF
(2)将两个表转为DF
(3)join
empDF.join(deptDF,empDF.col("deptno") === deptDF.col("deptno")).show()
(4)分区如何处理
哪一行
最小分区幅度
最大分区幅度
多少个分区
6、/spark-sql处理以上问题
(1)Spark-sql读JDBC的数据
官网:
CREATE TEMPORARY VIEW emp_mysql
USING org.apache.spark.sql.jdbc
OPTIONS (
url "jdbc:mysql://hadoop002:3306/hbinz001",
dbtable "emp",
user 'root',
password '123456'
)
SELECT * FROM emp_mysql
(2)true的意思
是否临时表的意思(当前session才可以看得到临时表)
二、写出文件
1、将empDF写出到MySQL
官网:
empDF.write.format("jdbc").option("url", "jdbc:mysql://hadoop002:3306/hbinz001").option("dbtable", "test_emp").option("user", "root").option("password", "123456").save()
2、报错
driver找不到方法
.option导入Driver
.option("driver","com.mysql.jdbc.Driver")
如果想表存在的时候仍覆盖就再加个.mode("overwrite")
3、原表和新表的结构对比
test_emp:
emp:
个别字段变化了,如果想自定义新表的字段格式的话可以再加以下参数:
// Specifying create table column data types on write
jdbcDF.write
.option("createTableColumnTypes", "name CHAR(64), comments VARCHAR(1024)")
.jdbc("jdbc:postgresql:dbserver", "schema.tablename", connectionProperties)
三、数据处理流程
1、数据传输、处理流程的几种方式
第三种处理方法最优:
列示存储-计算-传输
2、数据倾斜怎么导致
shuffle
3、小文件
小文件会导致HDFS压力骤增
四、Spark如何构建外部数据源,底层剖析
1、BaseRelation
作用:加载外部数据源的数据,定义数据的schema信息
Represents a collection of tuples with a known schema. Classes that extend BaseRelation must
be able to produce the schema of their data in the form of a `StructType`.
(1)传schema信息,带StructType类型
(2)抽象类,需要子类实现功能
(3)
2、RelationProvider
作用:产生Relation
(1)createRelation()方法
(2)parameters:传的是option的那些东西
3、Scan
作用:如何更有效的读取外部数据源的数据
(1)TableScan
没有任何条件,意味着整表扫描,扫出来转成RDD[Row]
(2)PrunedScan
(3)PrunedFilteredScan
(4)CatalystScan
4、Insert
(1)InsertableRelation
扫描数据源之后,写入数据
5、以JDBCRelation为例讲解底层
继承了BaseRelation,可以传schema信息
继承了PrunedFilteredScan,按列扫描的同时可以过滤
继承了InsertableRelation,可以写数据,.write方法
(1)BaseRelation的实现
分别实现这两个方法
(2)PrunedFilteredScan的实现
(3)InsertableRelation的实现
6、JdbcRelationProvider
7、幂等性问题