spark學習筆記--Spark SQL
Spark SQL
- Spark SQL可以從各種結構化資料來源(如JSON,Hive,Parquet等)中讀取資料
- Spark SQL不僅支援在程式內進行SQL查詢,也支援從類似商業智慧軟體Tableau等這樣的外部工具通過資料庫聯結器(JDBC/ODBC)進行SQL查詢
- Spark SQL 支援 SQL 與常規的 Python/Java/Scala 程式碼高度整合,包括連線 RDD 與 SQL 表、公開的自定義 SQL 函式介面等。
為了實現這些功能,Spark SQL提供了一種特殊的RDD,叫做SchemaRDD: - SchemaRDD是存放Row物件的RDD,每個Row物件代表一行記錄 - SchemaRDD還包含記錄的結構資訊(即資料欄位)
Spark SQL最強大之處就是可以在Spark應用內使用。這種方式讓我們可以輕鬆讀取資料並使用SQL查詢,同時還能把這一過程和普通的Python/Java/Scala程式程式碼結合在一起
Spark SQL是基於已有的SparkContext建立一個HiveContext,HiveContext可以建立出表示結構化資料的SchemalRDD,並且使用SQL或類似map()的普通RDD操作
Spark SQL的應用
scala:
// 匯入Spark SQL
import org.apache.spark.sql.hive.HiveContext
// 如果不能使用hive依賴的話
import org.apache.spark.sql.SQLContext
//匯入隱式轉換支援(隱式轉換被用來把帶有型別資訊的 RDD 轉變為專門用於 Spark SQL 查詢的 RDD(即SchemaRDD))
// 建立Spark SQL的HiveContext
val hiveCtx = ...
// 匯入隱式轉換支援
import hiveCtx._
//建立SQL上下文
val sc = new SparkContext(...)
val hiveCtx = new HiveContext(sc)
//查詢示例
val input = hiveCtx.jsonFile(inputFile)
// 註冊輸入的SchemaRDD
input.registerTempTable("tweets")
// 依據retweetCount(轉發計數)選出推文
val topTweets = hiveCtx.sql("SELECT text, retweetCount FROM
tweets ORDER BY retweetCount LIMIT 10")
SchemaRDD
從內部機理來看,SchemaRDD 是一個由 Row 物件組成的 RDD,附帶包含每列資料型別的結構資訊。Row 物件只是對基本資料型別(如整型和字串型等)的陣列的封裝。
SchemaRDD中可以儲存的資料型別
Row 物件表示 SchemaRDD 中的記錄,其本質就是一個定長的欄位陣列。
快取
Spark SQL 的快取機制與 Spark 中的稍有不同。由於我們知道每個列的型別資訊,所以 Spark 可以更加高效地儲存資料。
當快取資料表時,Spark SQL 使用一種列式儲存格式在記憶體中表示資料。這些快取下來的表只會在驅動器程式的生命週期裡保留在記憶體中,所以如果驅動器程式退出,就需要重新快取資料。和快取 RDD 時的動機一樣,如果想在同樣的資料上多次執行任務或查詢時,就應把這些資料表快取起來。
讀取與儲存資料
- Apache Hive
當從 Hive 中讀取資料時,Spark SQL 支援任何 Hive 支援的儲存格式(SerDe),包括文字檔案、RCFiles、ORC、Parquet、Avro,以及 Protocol Buffer。
scala:
import org.apache.spark.sql.hive.HiveContext
val hiveCtx = new HiveContext(sc)
val rows = hiveCtx.sql("SELECT key, value FROM mytable")
val keys = rows.map(row => row.getInt(0))
- Parquet
Parquet(http://parquet.apache.org/)是一種流行的列式儲存格式,可以高效地儲存具有巢狀欄位的記錄。
scala:
//讀取資料
HiveContext.parquetFile 或者 SQLContext.parquetFile
//儲存資料
saveAsParquetFile()
- JSON
如果你有一個 JSON 檔案,其中的記錄遵循同樣的結構資訊,那麼 Spark SQL 就可以通過掃描檔案推測出結構資訊,並且讓你可以使用名字訪問對應欄位,而無需編寫專門的程式碼來讀取不同結構的檔案。
scala:
//讀取資料
val input = hiveCtx.jsonFile(inputFile)
- 基於RDD建立SchemaRDD
帶有 case class 的 RDD 可以隱式轉換成 SchemaRDD。
scala:
case class HappyPerson(handle: String, favouriteBeverage: String)
...
// 建立了一個人的物件,並且把它轉成SchemaRDD
val happyPeopleRDD = sc.parallelize(List(HappyPerson("holden", "coffee")))
// 注意:此處發生了隱式轉換
// 該轉換等價於sqlCtx.createSchemaRDD(happyPeopleRDD)
happyPeopleRDD.registerTempTable("happy_people")
- 連線JDBC/ODBC伺服器
scala:
//啟動JDBC伺服器
./sbin/start-thriftserver.sh --master sparkMaster
//使用Spark自帶的Beelinek客戶端程式連線伺服器
holden@hmbp2:~/repos/spark$ ./bin/beeline -u jdbc:hive2://localhost:10000
Spark assembly has been built with Hive, including Datanucleus jars on classpath
scan complete in 1ms
Connecting to jdbc:hive2://localhost:10000
Connected to: Spark SQL (version 1.2.0-SNAPSHOT)
Driver: spark-assembly (version 1.2.0-SNAPSHOT)
Transaction isolation: TRANSACTION_REPEATABLE_READ
Beeline version 1.2.0-SNAPSHOT by Apache Hive
0: jdbc:hive2://localhost:10000> show tables;
+---------+
| result |
+---------+
| pokes |
+---------+
1 row selected (1.182 seconds)
0: jdbc:hive2://localhost:10000>
使用者自定義函式UDF
Spark SQL 不僅有自己的 UDF 介面,也支援已有的 Apache Hive UDF。
- Spark SQL UDF
scala:
registerFunction("strLenScala", (_: String).length)
val tweetLength = hiveCtx.sql("SELECT strLenScala('tweet') FROM tweets LIMIT 10")
- Hive UDF
標準的 Hive UDF 已經自動包含在了 Spark SQL 中。如果需要支援自定義的 Hive UDF,我們要確保該 UDF 所在的 JAR 包已經包含在了應用中。
scala:
//註冊Hive UDF
hiveCtx.sql("CREATE TEMPORARY FUNCTION name AS class.function")。
Spark SQL效能
Spark SQL中的效能選項
- Beeline配置
scala:
beeline> set spark.sql.codegen=true;
SET spark.sql.codegen=true
spark.sql.codegen=true
Time taken: 1.196 seconds
- Spark傳統配置
scala:
conf.set("spark.sql.codegen", "true")
配置說明:
- spark.sql.codegen
- 這個選項可以讓 Spark SQL 把每條查詢語句在執行前編譯為 Java 二進位制程式碼。由於生成了專門執行指定查詢的程式碼,codegen 可以讓大型查詢或者頻繁重複的查詢明顯變快。
- 在執行特別快(1 ~ 2 秒)的即時查詢語句時,codegen 有可能會增加額外開銷,因為 codegen 需要讓每條查詢走一遍編譯的過程。
- codegen 還是一個試驗性的功能,但是我們推薦在所有大型的或者是重複執行的查詢中使用 codegen。
- spark.sql.inMemoryColumnarStorage.batchSize
在快取 SchemaRDD 時,Spark SQL 會按照這個選項制定的大小(預設值是 1000)把記錄分組,然後分批壓縮。太小的批處理大小會導致壓縮比過低,而批處理大小過大的話,也有可能引發記憶體問題。如果你表中的記錄比較大,你就可能需要調低批處理大小來避免記憶體不夠(OOM)的錯誤。如果不是在這樣的場景下,預設的批處理大小是比較合適的,因為壓縮超過 1000 條記錄時也基本無法獲得更高的壓縮比了。
相關文章
- spark學習筆記-- Spark StreamingSpark筆記
- Spark學習筆記(三)-Spark StreamingSpark筆記
- spark學習筆記Spark筆記
- spark學習筆記--叢集執行SparkSpark筆記
- spark學習筆記--RDDSpark筆記
- spark學習筆記--Spark調優與除錯Spark筆記除錯
- Cris 的 Spark SQL 筆記SparkSQL筆記
- spark學習筆記--RDD鍵對操作Spark筆記
- Spark SQL學習——DataFrame和DataSetSparkSQL
- spark筆記Spark筆記
- spark學習筆記--進階程式設計Spark筆記程式設計
- Spark系列 - (3) Spark SQLSparkSQL
- spark 學習Spark
- Spark學習——記憶體管理Spark記憶體
- Spark3學習【基於Java】3. Spark-Sql常用APISparkJavaSQLAPI
- Spark學習進度-Spark環境搭建&Spark shellSpark
- spark學習筆記--資料讀取與儲存Spark筆記
- Spark簡明筆記Spark筆記
- Spark SQL:4.對Spark SQL的理解SparkSQL
- Spark SQL 教程: 通過示例瞭解 Spark SQLSparkSQL
- Spark SQL 教程: 透過示例瞭解 Spark SQLSparkSQL
- Cris 的 Spark Streaming 筆記Spark筆記
- 1.Spark學習(Python版本):Spark安裝SparkPython
- Spark 系列(九)—— Spark SQL 之 Structured APISparkSQLStructAPI
- Spark SQL | Spark,從入門到精通SparkSQL
- spark2.2.0 配置spark sql 操作hiveSparkSQLHive
- Spark SQL學習——UDF、UDAF和開窗函式SparkSQL函式
- 【spark筆記】在idea用maven匯入spark原始碼Spark筆記IdeaMaven原始碼
- Spark Streaming學習——DStreamSpark
- Spark學習——排序ShuffleSpark排序
- Spark Streaming + Spark SQL 實現配置化ETSparkSQL
- Spark 系列(十一)—— Spark SQL 聚合函式 AggregationsSparkSQL函式
- Spark API 全集(1):Spark SQL Dataset & DataFrame APISparkAPISQL
- Spark學習進度11-Spark Streaming&Structured StreamingSparkStruct
- Spark記錄(一):Spark全景概述Spark
- Spark學習——問題排查Spark
- SQL學習筆記SQL筆記
- Spark 從零到開發(五)初識Spark SQLSparkSQL