SparkSql簡介
SparkSql主要用於處理結構化的數據以及Spark執行類sql的查詢
SparkSql的數據源:SparkSql的數據源可以是JSON字符串,JDBC,HIVE,HDFS等
DataFrame
DataFrame也是一個分佈式的數據容器,與RDD類似,也可以轉換成RDD,DataFrame除了保存數據外,還保存數據的結構信息scheme,DataFrame底層封裝的就是RDD,只不過是row的RDD
DataSet
1.DataSet是DataframeAPI的一個擴展,是Spark最新的數據抽象
2.DataSet支持編解碼器,當需要訪問非堆上的數據可以避免反序列化整個對象,提高了效率
3.樣例類被用來在Dataset中定義數據的結構信息,樣例類中每個屬性的名稱直接映射到DataSet中的字段名稱
4.DataFrame是Dataset的特例,DataFrame = Dataset[Row],可以通過as方法將DataFrame轉換爲Dataset,Row是一個類型,跟Car,Person這些類型一樣,所有的表結構信息都用Row來表示
5.DataSet是強類型,可以有DataSet[Car],DataSet[Person]
6.DataFrame只是知道字段,但是不知道字段類型,所以在執行這些操作的時候是沒辦法在編譯的時候檢查是否類型失敗的
SparkSQL怎麼來查詢
在1.6版本中,SparkSQL有兩種SQL查詢起始點:一個叫SQLContext,用於Spark自己提供的SQL查詢,一個叫HiveContext,用於連接Hive的查詢
2.0以上的版本中,SparkSQL的查詢起始點使用SparkSession,實質上是SQLContext和HiveContext的組合
創建DataFrame
DataFrame的創建方式有三種
1.spark數據源進行創建
讀取json文件創建DataFrame
def main(args: Array[String]): Unit = {
var spark =SparkSession.builder()
.appName("sparksql")
.master("local")
.getOrCreate();
spark.sparkContext.setLogLevel("ERROR")
val dataFrame : DataFrame= spark.read.format("json").load("./data/json")
//默認顯示前20條
dataFrame.show()
}
通過創建臨時表,使用sql來查詢
def main(args: Array[String]): Unit = {
//編寫sql,創建sparkSession
val spark =SparkSession.builder()
.appName("sparksession")
.master("local[*]")
//.config("spark.some.config.option", "some-value")
.getOrCreate()
//讀取json文件創建DataFrames
val dataFrame = spark.read.json("data/user.json")
dataFrame.createOrReplaceTempView("people")
//使用sql進行查詢
val dfSql = spark.sql("select * from people")
dfSql.show()
spark.stop()
}
2.RDD進行轉換
a.json格式的RDD創建DataFrame
def main(args: Array[String]): Unit = {
var conf = new SparkConf();
conf.setMaster("local")
conf.setAppName("readjson")
var sc = new SparkContext(conf)
var sqlContext = new SQLContext(sc)
//創建RDD
var nameRDD = sc.makeRDD(Array("{\"name\":\"zhangsan\",\"age\":18}",
"{\"name\":\"lisi\",\"age\":19}",
"{\"name\":\"wangwu\",\"age\":20}"
));
//創建RDD
var scoreRDD = sc.makeRDD(Array("{\"name\":\"zhangsan\",\"score\":100}",
"{\"name\":\"lisi\",\"score\":200}",
"{\"name\":\"wangwu\",\"score\":300}"
))
//RDD轉DataFrame
var nameDataFrame = sqlContext.read.json(nameRDD)
var scoreDataFrame = sqlContext.read.json(scoreRDD)
//創建臨時表
nameDataFrame.registerTempTable("name")
scoreDataFrame.registerTempTable("score")
var result = sqlContext.sql("select name.name ,name.age,score.score from name ,score where name.name = score.name")
result.show();
sc.stop();
}
結果:
b.使用樣例類轉換成DataFrame
DataDrame轉換成RDD
def main(args: Array[String]): Unit = {
//編寫sql,創建sparkSession
val spark =SparkSession.builder()
.appName("sparksession")
.master("local[*]")
.getOrCreate()
//讀取json文件創建DataFrames
val dataFrame = spark.read.json("data/user.json")
//使用sql進行查詢
//df轉換爲rdd
val dfToRDD = dataFrame.rdd
dfToRDD.foreach(row=>{
println(row)
})
spark.stop()
}
3.HIve Table查詢進行返回
DataSet的創建方式
DataFrame創建DataSet
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder()
.master("local[*]")
.appName("dataset")
.getOrCreate()
import spark.implicits._
val userDs = spark.read.json("data/user.json").as[User]
userDs.show()
}
RDD DataFrame DataSet的相同與不同之處
相同之處
1.RDD、DataFrame、DataSet都是彈性分佈式數據集
2.三者都有惰性機制,只有在遇到Action時,纔會觸發操作
3.三者都會根據spark的內存情況自動緩存運算
4.三者都有partition的概念
5.DataFrame和DataSet均可使用模式匹配獲取各個字段的值和類型
不同之處
1.RDD不支持sparksql操作,DF和DS支持sparksql
2.DF和DS可以註冊表/視圖,支持sql查詢
3.DataFrame的每一行類型固定爲Row,每一行有哪些字段,各個字段是什麼類型,是無法得知的,每一列的值無法直接訪問,只能通過getAs或者模式匹配來訪問
4.DataSet可以很方便的訪問列字段的值和類型,但是需要先寫明樣例類,給DS聲明類型