Data Source(1.2)概述
源端 ==> MapReduce/Hive/Spark ===> 目标端
业务逻辑处理都是在引擎层面来考虑
load ======> ETL/… ======> save
存在的问题:
1.数据文件格式有很多,普通文本,JSON这种带Schema信息的等等等等
2.数据有可能存在在本地/HDFS/S3
因为这两大类问题的存在,使得光使用传统方法,无法只用一套方法处理各种问题
这就需要使用DataSource
SparkCore 通过 DataSource API 来读各种来源的 各种类型的数据文件
这些外部数据通过DataSource会变成 DataFrame/DataSet
这样就可以使用SQL或者DF/DS API来使用
DataFrame也可以通过 DataSource 写到外部数据源里
外部数据源<=>DataSource <=> DataFrame/DataSet
Parquet
Spark SQL支持读取和写入Parquet文件,这些文件自动保留原始数据的模式
1.以编程方式加载数据
import spark.implicits._
val peopleDF = spark.read.json(“file:///xxx/examples/src/main/resources/people.json”)
//spark.read.format(“json”).load("")
//peopleDF.write.format(“parquet”).save(“file:///xxx”)
peopleDF.write.parquet(“file:///xxxx”) //先read load 再 write save
spark.read.parquet(“file:///xxxx”) //可以再用read load检查一下之前存储的数据
这样可以直接将文件类型转换 parquet,json,orc…相互转换
也可以将DataFrame 转换为临时视图,这样就可以使用SQL直接查询
peopleDF.createOrReplaceTempView(“people”)
2.分区探测 能够自动从路径上面推测出分区信息 注意base在哪里,如果往下走一层,不会把当前层当做分区字段
3.架构合并 成本比较高
4.Hive Metastore Parquet表转换
ORC
spark.read.format(“orc”).load("")
Hive
配置 hive-site.xml
import spark.implicits._
import spark.sql
sql(“CREATE TABLE IF NOT EXISTS src (key INT, value STRING) USING hive”)
sql(“LOAD DATA LOCAL INPATH ‘examples/src/main/resources/kv1.txt’ INTO TABLE src”)
sql(“SELECT * FROM src”).show()
JDBC to Other Databases
val tbls = spark.read.format(“jdbc”)
.option(“url”,“jdbc:mysql://hadoop001:3306/hive_d6”)
.option(“dbtable”,“TBLS”)
.option(“user”,“root”)
.option(“password”,“123456”)
.load()
val dbs = spark.read.format(“jdbc”)
.option(“url”,“jdbc:mysql://hadoop001:3306/hive_d6”)
.option(“dbtable”,“DBS”)
.option(“user”,“root”)
.option(“password”,“123456”)
.load()
dbs.join(tbls,dbs(“DB_ID”)===tbls(“DB_ID”)).select(“NAME”,“URI”).show(false)
// 此时 多个不同数据源来的DF就可以做相关的关联操作了
基本配置是在 RDBMS
用户行为日志 Hive/SparkSQL
abstract class BaseRelation { -0
def sqlContext: SQLContext
def schema: StructType
} // 这些接口可以使得 外部数据源可以给我们并行地提供数据
trait TableScan {
def buildScan(): RDD[Row]
} 读取所有的数据,返回 RDD[Row] ...select * from
trait PrunedScan {
def buildScan(requiredColumns: Array[String]): RDD[Row]
} 裁剪的scan... select a,b from
trait PrunedFilteredScan {
def buildScan(requiredColumns: Array[String], filters: Array[Filter]): RDD[Row]
} 过滤 select a,b from xxx where a>xxx (where 底层也是filter)
trait CatalystScan {
def buildScan(requiredColumns: Seq[Attribute], filters: Seq[Expression]): RDD[Row]
}
trait InsertableRelation {
def insert(data: DataFrame, overwrite: Boolean): Unit
}
// 创建Relation
trait RelationProvider {
def createRelation(sqlContext: SQLContext, parameters: Map[String, String]): BaseRelation
}产生Relation
trait InsertableRelation {
def insert(data: DataFrame, overwrite: Boolean): Unit
}
class JdbcRelationProvider extends CreatableRelationProvider
with RelationProvider with DataSourceRegister {
override def createRelation{
}
Spark 去处理 JDBC 数据源
拼SQL ==> JDBC API编程 ==> DataFrame
构建自己的外部数据源 ******