好程式設計師大資料學習路線分享SparkSQl
好程式設計師大資料學習路線分享SparkSQl,Spark SQL 是 Spark 用來處理結構化資料的一個模組,它提供了一個程式設計抽象叫做 DataFrame 並且作為分散式 SQL 查詢引擎的作用。 SparkSql 中返回的資料型別是 DataFrame
1.1.1. 為什麼要學習 Spark SQL
我們已經學習了Hive ,它是將 Hive SQL 轉換成 MapReduce 然後提交到叢集上執行,大大簡化了編寫 MapReduce 的程式的複雜性 ,由於MapReduce這種計算模型執行效率比較慢。所有Spark SQL的應運而生,它是將Spark SQL轉換成RDD,然後提交到叢集執行,執行效率非常快!
HIVE:簡化編寫MapReduce的程式的複雜性
Spark SQL轉換成RDD: 替代 MapReduce, 提高效率
Spark1.0 版本開始就推出了 SparkSQL ,最早是叫 Shark
1 、記憶體列儲存 -- 可以大大最佳化記憶體使用效率,減少了記憶體消耗,避免了 gc 對大量資料的效能開銷
2 、位元組碼生成技術( byte-code generation ) -- 可以使用動態位元組碼生成技術來最佳化效能
3 、 Scala 程式碼的最佳化
結構化資料是指任何有結構資訊的資料。所謂結構資訊,就是每條記錄共用的已知的欄位集合。 當資料符合 這樣的條件時, Spark SQL 就會使得針對這些資料的讀取和查詢變得更加簡單高效。具體 來說, Spark SQL 提供了以下三大功能(見圖 9-1 )。
(1) Spark SQL 可以從各種結構化資料來源(例如 JSON 、 Hive 、 Parquet 等)中讀取資料。
(2) Spark SQL 不僅支援在 Spark 程式內使用 SQL 語句進行資料查詢,也支援從類似商業 智慧軟體 Tableau 這樣的外部工具中透過標準資料庫聯結器( JDBC/ODBC )連線 Spark SQL 進行查詢。
(3) 當在 Spark 程式內使用 Spark SQL 時, Spark SQL 支援 SQL 與常規的 Python/Java/Scala 程式碼高度整合,包括連線 RDD 與 SQL 表、公開的自定義 SQL 函式介面等。這樣一來, 許多工作都更容易實現了。
為了實現這些功能, Spark SQL 提供了一種特殊的 RDD ,叫作 SchemaRDD 。 SchemaRDD 是存放 Row 物件的 RDD ,每個 Row 物件代表一行記錄。 SchemaRDD 還包含記錄的結構信 息(即資料欄位)。 SchemaRDD 看起來和普通的 RDD 很像,但是在內部, SchemaRDD 可 以利用結構資訊更加高效地儲存資料 。此外, SchemaRDD 還支援 RDD 上所沒有的一些新 操作,比如執行 SQL 查詢。 SchemaRDD 可以從外部資料來源建立,也可以從查詢結果或普 通 RDD 中建立。
什麼是 DataFrames
( SparkSql 中返回的資料型別 : 它在概念上等同於關聯式資料庫中的表 , 但在查詢上進行了最佳化 )
與 RDD 類似, DataFrame 也是一個分散式資料容器。然而 DataFrame 更像傳統資料庫的二維表格,除了資料以外,還 記錄 資料的結構資訊,即 schema 。
1.1.1. 建立 DataFrames
在Spark SQL中SQLContext是建立DataFrames和執行SQL的入口,在spark-1.6.1中已經內建了一個 sqlContext
1.在本地建立一個檔案,有三列,分別是id、name、age,用空格分隔,然後上傳到hdfs上
hdfs dfs -put person.txt /
2.在spark shell執行下面命令,讀取資料,將每一行的資料使用列分隔符分割
val lineRDD = sc.textFile("hdfs://node01:9000/person.txt").map(_.split(" "))
3. 定義 case class (相當於表的 schema )
case class Person(id:Int, name:String, age:Int)
4. 將 RDD 和 case class 關聯
val personRDD = lineRDD.map(x => Person(x(0).toInt, x(1), x(2).toInt))
( 裡面的資料是在 Array 中 )
5. 將 RDD 轉換成 DataFrame
val personDF = personRDD.toDF
6.對DataFrame進行處理
personDF.show
val seq1 = Seq(("1","bingbing",35),("2","yuanyuan",34),("3","mimi",33))
val rdd1 =sc.parallelize(seq1)
val df = rdd1.toDF("id","name","age")
df.show
DSL:領域特定語言
////檢視DataFrame中的內容
//檢視DataFrame部分列中的內容
1.
2.
3.
//列印DataFrame的Schema資訊
//查詢所有的name和age,並將age+1
1.df.select(col("id"),col("name"),col("age")+1).show
2.df.select(df("id"), df("name"), df("age") + 1).show
//過濾age大於等於18的
df.filter(col("age") >= 35).show
//按年齡進行分組並統計相同年齡的人數
df.groupBy("age").count().show()
SQL 風格語法
//查詢年齡最大的前兩名
1.如果想使用SQL風格的語法,需要將DataFrame註冊成表
df.registerTempTable("t_person")
2.sqlContext.sql("select * from t_person order by age desc limit 2").show
//顯示錶的Schema資訊
以程式設計方式執行 Spark SQL 查詢
1. 編寫 Spark SQL 查詢程式
1. 透過反射推斷 Schema
=======================================================
package com.qf.gp1708.day06
//透過反射獲取使用者資訊
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, SQLContext}
import org.apache.spark.{SparkConf, SparkContext}
object InferSchema {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setMaster( "local" )
.setAppName( "inferschema" )
val sc = new SparkContext(conf)
val sqlContext:SQLContext = new SQLContext(sc)
1. //獲取資料並切分
val line = sc.textFile( "C://Users/Song/Desktop/person.txt" ).map(_.split( "," ))
3 //將獲取的資料和Person樣例類進行關聯
val personRdd: RDD[Godness] = line.map(arr=> Godness (arr(0).toLong,arr(1),arr(2).toInt,arr(3).toInt))
//引入隱式轉換函式,這樣才可以呼叫到toDF方法
import sqlContext.implicits._
4 //將personRDD轉換成DataFrame
val dF: DataFrame = personRdd.toDF
5. //註冊一張臨時表
dF.registerTempTable( "t_person" )
val sql = "select * from t_person where fv > 70 order by age"
//查詢
val res: DataFrame = sqlContext.sql(sql)
res.show()
sc.stop()
}
}
2// 建立樣例類
case class Godness(id:Long,name:String,age:Int,fv:Int)
=========================================================
2. 透過 StructType 直接指定 Schema
===========================================
package com.qf.gp1708.day06
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, Row, SQLContext}
import org.apache.spark.sql.types.{IntegerType, StringType, StructField, StructType}
import org.apache.spark.{SparkConf, SparkContext}
/**
* 透過StructType型別直接指定Schema
*/
object StructTypeSchema {
def main(args: Array[String]): Unit = {
val conf = new SparkConf()
.setAppName( "str" )
.setMaster( "local" )
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
//獲取資料並切分
val lines = sc.textFile( "hdfs://..." ).map(_.split( "," ))
//指定schema資訊
StructType {
List (
StructField ( "id" ,IntegerType, false ),
StructField ( "name" ,StringType, true ),
StructField ( "age" ,IntegerType, true ),
StructField ( "fv" ,IntegerType, true ),
)
}
//開始對映
val rowRDD: RDD[Row] = lines.map(arr => Row (arr(0).toInt,arr(1),arr(2).toInt,arr(3).toInt))
//把RDD轉換為DataFrame
val personDF: DataFrame = sqlContext.createDataFrame(rowRDD,schema)
//生成臨時表
personDF.registerTempTable( "t_person" )
val sql = "select name,age,fv from t_person where age >30 order by age desc"
val res = sqlContext.sql(sql)
res.write.mode( "append" ).json( "c://out-20180903-1" )
sc.stop()
}
}
=================================================================
1. 資料來源
1.1. JDBC
Spark SQL可以透過JDBC從關係型資料庫中讀取資料的方式建立DataFrame,透過對DataFrame一系列的計算後,還可以將資料再寫回關係型資料庫中。
1.1.1. 從 MySQL 中載入資料( Spark Shell 方式)
1.啟動Spark Shell,必須指定mysql連線驅動jar包
/usr/local/spark-1.6.1-bin-hadoop2.6/bin/spark-shell \
--master spark://node01:7077 \
--jars /usr/local/spark-1.6.1-bin-hadoop2.6/mysql-connector-java-5.1.35-bin.jar \
(指定MySQL包)
--driver-class-path /usr/local/spark-1.6.1-bin-hadoop2.6/mysql-connector-java-5.1.35-bin.jar (指定驅動類)
2.從mysql中載入資料
val jdbcDF = sqlContext.read.format("jdbc").options(Map("url" -> "jdbc:mysql://node03:3306/bigdata", "driver" -> "com.mysql.jdbc.Driver", "dbtable" -> "person", "user" -> "root", "password" -> "root")).load()
3.執行查詢
jdbcDF.show()
1.1.2. 將資料寫入到 MySQL 中(打 jar 包方式)
package com.qf.gp1708.day06
import java.util.Properties
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{Row, SQLContext}
import org.apache.spark.sql.types.{IntegerType, StringType, StructField, StructType}
import org.apache.spark.{SparkConf, SparkContext}
/**
* 寫入資料到MySQL
*/
object InsertData2MySQLDemo {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName( "" ).setMaster( "local[2]" )
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
val lines= sc.textFile( "" ).map(_.split( "," ))
//生成Schema
val schema = StructType {
Array (
StructField ( "name" , StringType, true ),
StructField ( "age" , IntegerType, true ),
StructField ( "fv" , StringType, true ),
)
}
//對映
val personRDD = lines.map(arr => Row (arr(1).toString,arr(2).toInt,arr(3).toInt))
//生成DataFrame
val personDF = sqlContext.createDataFrame(personRDD,schema)
//生成用於寫入MySQL的配置資訊
val prop = new Properties()
prop.put( "user" , "root" )
prop.put( "password" , "root" )
prop.put( "driver" , "com.mysql.jdbc.Driver" )
val jdbcUrl= "jdbc:mysql://hadoop03:3306/bigdata"
val table= "person"
//把資料寫入MySQL
personDF.write.mode( "append" ).jdbc(jdbcUrl,table,prop)
sc.stop()
}
}
/usr/local/spark-1.6.3-bin-hadoop2.6/spark-submit \
--class com.qf..... \
--master spark://hadoop01:7077 \
--executor-memory 512m \
--total-executor-cores 2 \
--jars /usr/.../mysql-connector-java-5.1.35-bin.jar \
--driver-class-path /usr/.../mysql-connector-java-5.1.35-bin.jar \
/root/1.jar
=======================================================
kafka:訊息中介軟體(快取資料)---解耦
為處理實時資料提供一個統一、高吞吐量、低等待的平臺
3 、為什麼需要訊息佇列(重要、瞭解)
訊息系統的核心作用就是三點:解耦,非同步和並行
Kafka對訊息儲存時根據Topic進行歸類
Topic:底層就是佇列,將不同的訊息放在不同的佇列中進行分類
釋出 /訂閱模式:1對多
JMS:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69913892/viewspace-2653694/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 好程式設計師大資料學習路線分享MAPREDUCE程式設計師大資料
- 好程式設計師大資料學習路線分享Hbase指令學習程式設計師大資料
- 好程式設計師大資料學習路線分享大資料之字串程式設計師大資料字串
- 好程式設計師大資料學習路線Hadoop學習乾貨分享程式設計師大資料Hadoop
- 好程式設計師大資料學習路線分享HDFS學習總結程式設計師大資料
- 好程式設計師大資料學習路線分享hdfs學習乾貨程式設計師大資料
- 好程式設計師大資料學習路線分享Actor學習筆記程式設計師大資料筆記
- 好程式設計師大資料學習路線分享Map學習筆記程式設計師大資料筆記
- 好程式設計師大資料學習路線分享HDFS讀流程程式設計師大資料
- 好程式設計師大資料學習路線分享AWK詳解程式設計師大資料
- 好程式設計師大資料學習路線分享UDF函式程式設計師大資料函式
- 好程式設計師大資料學習路線分享spark之Scala程式設計師大資料Spark
- 好程式設計師大資料學習路線分享Lambda表示式程式設計師大資料
- 好程式設計師大資料學習路線分享大資料之執行緒程式設計師大資料執行緒
- 好程式設計師大資料學習路線分享高階函式程式設計師大資料函式
- 好程式設計師大資料學習路線分享Scala系列之物件程式設計師大資料物件
- 好程式設計師大資料學習路線分享Hadoop機架感知程式設計師大資料Hadoop
- 好程式設計師大資料學習路線分享TCP和UDP學習筆記程式設計師大資料TCPUDP筆記
- 好程式設計師大資料學習路線分享大資料之基礎語法程式設計師大資料
- 好程式設計師大資料學習路線分享MapReduce全過程解析程式設計師大資料
- 好程式設計師大資料學習路線分享hive的執行方式程式設計師大資料Hive
- 好程式設計師大資料學習路線分享什麼是Hash表程式設計師大資料
- 好程式設計師大資料學習路線分享Scala系列之抽象類程式設計師大資料抽象
- 好程式設計師大資料學習路線分享Scala系列之陣列程式設計師大資料陣列
- 好程式設計師大資料學習路線分享Scala分支和迴圈程式設計師大資料
- 好程式設計師大資料學習路線分享MapReduce全流程總結程式設計師大資料
- 好程式設計師大資料學習路線分享Scala系列之泛型程式設計師大資料泛型
- 好程式設計師大資料學習路線之大資料自學路線二程式設計師大資料
- 好程式設計師大資料學習路線之大資料自學路線一程式設計師大資料
- 好程式設計師大資料學習路線分享執行緒學習筆記二程式設計師大資料執行緒筆記
- 好程式設計師大資料學習路線分享多執行緒學習筆記程式設計師大資料執行緒筆記
- 好程式設計師大資料學習路線Hbase總結程式設計師大資料
- 好程式設計師大資料學習路線之mapreduce概述程式設計師大資料
- 好程式設計師大資料學習路線分享彈性分散式資料集RDD程式設計師大資料分散式
- 好程式設計師大資料學習路線分享函式+map對映+元祖程式設計師大資料函式
- 好程式設計師大資料學習路線分享hive分割槽和分桶程式設計師大資料Hive
- 好程式設計師大資料學習路線分享Scala系列之對映Map程式設計師大資料
- 好程式設計師大資料學習路線分享Scala系列之基礎篇程式設計師大資料