创建SparkSession
sparkSQl 可以读取不同数据源的数据,比如jdbc,json,csv,parquet
执行读操作就用sparkSession.read.文件类型,执行写操作就用SparkSession.write.文件类型
首先创建一个SparkSession:
val spark = SparkSession.builder().appName("load data")
.master("local[4]")
.getOrCreate()
如果通过spark-shell 进入的,会自动创建
[xxx@hadoop bin]$ ./spark-shell
Setting default log level to "WARN".
To adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).
2020-06-15 16:17:00,429 [main] WARN org.apache.spark.util.Utils - Service 'SparkUI' could not bind on port 4040. Attempting port 4041.
2020-06-15 16:17:00,430 [main] WARN org.apache.spark.util.Utils - Service 'SparkUI' could not bind on port 4041. Attempting port 4042.
2020-06-15 16:17:00,430 [main] WARN org.apache.spark.util.Utils - Service 'SparkUI' could not bind on port 4042. Attempting port 4043.
2020-06-15 16:17:00,431 [main] WARN org.apache.spark.util.Utils - Service 'SparkUI' could not bind on port 4043. Attempting port 4044.
Spark context Web UI available at http://172.20.xx.xx:4044
Spark context available as 'sc' (master = yarn, app id = application_1565137100893_1929326).
Spark session available as 'spark'.
读取数据
jdbc
读取
//load这个函数是并没有真正读取MySQL中的数据,而是建立了一个连接,记录了这个表头(Schema)的信息
val logs: DataFrame = spark.read.format("jdbc").options(
Map("url" -> "jdbc:mysql://localhost:3306/bigdata",
"driver" -> "com.mysql.jdbc.Driver",
"dbtable" -> "logs",
"user" -> "root",
"password" -> "")
).load()
保存
//将结果写入到数据库中
val props = new Properties()
props.put("user","root")
props.put("password","")
//mode是模式
// ignore表示不做任何改变,直接写,如果要写入的表已经存在,则不追加也不覆盖
result.write.mode("ignore").jdbc("jdbc:mysql://localhost:3306/bigdata","logs1",props)
json
//读取json文件(读取的数据格式直接就是DataFrame,因为json文件中可以保存属性名和属性值)
val logs: DataFrame = spark.read.json("/home/hadoop/app/json")
//DataFrame保存成json(可以保存更多的信息,属性和属性名(表头))
result.write.json("/home/hadoop/app/json")
csv
//读取csv文件(根据字段分割就知道一行有多少列数据,然后会给每一列取一个名字)
val logs: DataFrame = spark.read.csv("/home/hadoop/app/csv")
//自己定义每一列的名称
val csv: DataFrame = logs.toDF("id","name","age")
//DataFrame保存成csv(保存好的数据用逗号隔开,没有表头信息)
result.write.csv("/home/hadoop/app/csv")
parquet
//读取parquet文件(还可以指定HDFS目录),可以智能的知道每一列数据的类型
val parquetLines: DataFrame = spark.read.parquet("/home/hadoop/app/parquet")
//或者使用另一种方式读取
val parquetLines: DataFrame = spark.read.format("parquet").load("/home/hadoop/app/parquet")
//DataFrame保存成parquet(智能类型的数据源,列式存储),既保存数据,又保存了Schema信息
result.write.parquet("/home/hadoop/app/parquet")
保存数据
import org.apache.spark.SparkConf
import org.apache.spark.sql.{DataFrame, SparkSession}
//todo:sparksql可以把结果数据保存到不同的外部存储介质中
object SaveResult {
def main(args: Array[String]): Unit = {
//1、创建SparkConf对象
val sparkConf: SparkConf = new SparkConf().setAppName("Result").setMaster("local[2]")
//2、创建SparkSession对象
val spark: SparkSession = SparkSession.builder().config(sparkConf).getOrCreate()
//3、加载数据源 //也可以换成HDFS路径
val jsonDF: DataFrame = spark.read.json("d:\\data\\score.json")
//4、把DataFrame注册成表
jsonDF.createTempView("t_score")
//todo:5、统计分析
val result: DataFrame = spark.sql("select * from t_score where score > 80")
//保存结果数据到不同的外部存储介质中
//todo: 5.1 保存结果数据到文本文件 ---- 保存数据成文本文件目前只支持单个字段,不支持多个字段
result.select("name").write.text("./data/result/123.txt")
//todo: 5.2 保存结果数据到json文件
result.write.json("./data/json")
//todo: 5.3 保存结果数据到parquet文件
result.write.parquet("./data/parquet")
//todo: 5.4 save方法保存结果数据,默认的数据格式就是parquet
result.write.save("./data/save")
//todo: 5.5 保存结果数据到csv文件
result.write.csv("./data/csv")
//todo: 5.6 保存结果数据到表中
result.write.saveAsTable("t1")
//todo: 5.7 按照单个字段进行分区 分目录进行存储
result.write.partitionBy("classNum").json("./data/partitions")
//todo: 5.8 按照多个字段进行分区 分目录进行存储
result.write.partitionBy("classNum","name").json("./data/numPartitions")
spark.stop()
}
}