通過本書,你可以了解到:Spark SQL的新接口如何為SQL的RDD數據結構提升性能。Spark Core與Spark SQL中數據join的不同選擇方式。充分利用標準RDD轉換的技術。如何解決Spark中鍵值范式的性能問題。不借助Scala或其他JVM語言來編寫高性能的Spark代碼。采用改進建議后,如何來測試其功能及性能情況。使用Spark MLlib和Spark ML機器學習庫。Spark的流處理組件、外部的社區(qū)擴展包。
前言
這本書為數據工程師和數據科學家所寫,他們可以從Spark 中獲得最大的收益。如果你一直在使用并深耕 Spark,但曾被內存錯誤和奇奇怪怪的間歇性故障所困擾,那么這本書很適合你。如果你一直在使用 Spark 進行一些探索或者嘗試性的工作,但沒有足夠的信心將其應用于生產,這本書可能會有幫助。如果你對 Spark 很有熱情,但是在性能提升方面沒有達到你的預期,希望這本書能有所幫助。本書的目標人群是那些了解一些 Spark 使用方式、但對 Spark或者分布式計算理解不夠的用戶。更多推薦閱讀請參考后面的“配套書籍及資料”。
本書旨在于幫助優(yōu)化生產上的重復查詢問題,而非針對探索實驗。與其他框架相比,使用 Spark 編寫高性能查詢對于數據工程師來說更加重要,這一點對于數據科學家更加明顯。這對于思考性能問題時很少嚴格考慮數據的統(tǒng)計屬性、分布,以及布局的數據工程師還是很有幫助的。我們希望本書能夠幫助他們將數據管道應用于生產環(huán)節(jié)之時,可以更加嚴格地考慮其中的數據。希望幫助讀者提出一些問題,比如“我的數據是如何分布的?”“是否有數據傾斜?”“這一列的值的范圍是多少”“我們期望如何對一個給定值進行分組”,然后將這些問題的答案應用到編寫 Spark 查詢的邏輯中。
然而,對于數據科學家來說即使只是出于探索性目的來使用 Spark,本書也能夠培養(yǎng)一些關于編寫高性能 Spark 查詢的重要直觀感受,這樣隨著探索性分析規(guī)模不可避免地增長,你就可以在第一時間更好地運行這些查詢。我們希望可以引導那些習慣以分布式視角思考數據的人,可以更加嚴格地評估自己的程序,增強他們全面、快速的數據探索能力,同時可以與幫助他們將算法應用于生產的人更加有效地溝通。
無論你從事什么樣的崗位,你所使用的數據量很可能都在迅速增長。你的最初方案可能需要進行擴展,解決新問題時用到的老技術也可能需要更迭。我們希望這本書能幫助你利用 Apache Spark 更容易地解決新問題,同時更高效地解決老問題。
第一版注釋
非常感謝你正在閱讀這本書的第一版!如果你在本書中發(fā)現一些錯誤、問題,或者有思路來改進某些方面,請通過 high-performance-spark@googlegroups.com 聯(lián)系我們。如果你希望出現在本書的未來版本中的“致謝”部分,請備注下你要展示的名字。
配套書籍及資料
對于初學 Spark 的數據科學家和開發(fā)人員來說,由 Karau、Konwinski、Wendell 和 Zaharia 共同撰寫的《Learning Spark》是一本不錯的學習資料注1,另外由 Sandy Ryza、Uri Laserson、Sean Owen 和 Josh Wills 所寫的《Advanced Analytics with Spark》對于一些數據科學家可能會比較有吸引力。而對于流處理感興趣的,即將出版的由 François Garillot 所著的《Learning Spark Streaming》可能更加適用。
書籍之外,還有一些入門級的 Spark 培訓資料。對于喜歡視頻的來說,Paco Nathan 在 O’Reilly 有一套不錯入門視頻。商業(yè)方面,Databricks、Cloudera以及其他的 Hadoop/Spark 供應商也提供了相應的 Spark 培訓。在 Apache Spark 的文檔頁面可以找到以往的 Spark 訓練營錄音,以及其他非常優(yōu)秀的資源。
如果你沒有 Scala 經驗,我們將在第 1 章中盡最大努力說服你學會 Scala。感興趣的話,可以參考 Dean Wampler 和 Alex Payne 所著的《ProgrammingScala, 2nd Edition》注2。
排版約定
本書使用了下述排版約定。
斜體(Italic)
表示新術語、URL、電子郵件地址、文件名和擴展名。
等寬字體(Constant Width)
表示程序片段,以及正文中出現的變量、函數名、數據庫、數據類型、環(huán)境變量、語句和關鍵字等。
等寬斜體(constant width italic)
表示應該由用戶輸入的值或根據上下文確定的值替換的文本。
使用示例代碼
從本書的 Github 倉庫(https://github.com/highperformance-spark/highperformance-spark-examples)可以下載補充材料(代碼示例、練習等),一些測試代碼可以從 Spark Testing Base 和 Spark Validator 的 Github 倉庫獲取。Structured Streaming 機器學習的示例,通常出現在“evil”分類(xi 頁的排版約定中有提及),可以從 https://github.com/holdenk/spark-structuredstreaming-ml 獲取。
本書的目的在于幫助你更好地完成工作。通常情況下,可以在你的程序或者文檔中使用本書的代碼。不必聯(lián)系我們獲取代碼的使用權,除非你需要使用大量的代碼。例如,在寫程序的時候引用幾段代碼不需要向我們申請許可。但以光盤方式銷售或者重新發(fā)行 O’Reilly 書中的示例則需要獲得許可。引用本書或引用本書中的示例代碼來回答問題也不需要申請許可。代碼遵循的是Apache 2.0 協(xié)議。如果要將本書中的大量代碼加入到你的產品文檔,則需要申請許可。
我們欣賞你在引用時注明出處,但不強求。引用通常包括書名、作者、出版社和 ISBN。如:“High Performance Spark by Holden Karau and Rachel Warren (O’Reilly). Copyright 2017 Holden Karau, Rachel Warren, 978-1-491-94320-5”。
如果覺得使用示例代碼的情況不屬于前面列出的合理使用或許可范圍,請通過電子郵件聯(lián)系我們,郵箱地址為 permissions@oreilly.com。
O’Reilly 在線學習平臺(O’Reilly Online Learning)
近40 年來,O’Reilly Media 致力于提供技術和商業(yè)培訓、知識和卓越見解,來幫助眾多公司取得成功。
我們擁有獨一無二的專家和革新者組成的龐大網絡,他們通過圖書、文章、會議和我們的在線學習平臺分享他們的知識和經驗。O’Reilly 的在線學習平臺允許你按需訪問現場培訓課程、深入的學習路徑、交互式編程環(huán)境,以及O’Reilly 和200 多家其他出版商提供的大量文本和視頻資源。有關的更多信息,請訪問http://oreilly.com。
如何聯(lián)系作者
如果有需要進行反饋的內容, 請發(fā)郵件至 high-performance-spark@googlegroups.com。如果你有任何關于Spark 的任何想法,請在 twitter 上關注我們:
Holden: http://twitter.com/holdenkarau。
Rachel: https://twitter.com/warre_n_peace。
聯(lián)系我們
美國:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
中國:
北京市西城區(qū)西直門南大街2號成銘大廈C座807室(100035)
奧萊利技術咨詢(北京)有限公司
如果你對本書有一些評論或技術上的建議,請發(fā)送電子郵件到bookquestions@oreilly.com。
有關其他圖書、講座、會議、新聞的信息,請訪問我們的網站:http://www.oreilly.com。
我們的Facebook:http://facebook.com/oreilly。
我們的Twitter:http://twitter.com/oreillymedia。
我們的YouTube:http://www.youtube.com/oreillymedia。
致謝
作者要感謝每一個曾對我們的早期文稿提出意見和建議的人。特別感謝 Anya Bida、Jakob Odersky 和 Katharine Kearnan 審核文稿和圖表。我們要感謝Mahmoud Hanafy 對示例代碼以及早期文稿的審核和改進。我們還要感謝Michael Armbrust 對 SQL 章節(jié)文稿的審核及反饋。Justin Pihony 是最活躍的早期讀者之一,他提出了各個方面(包括語言、格式等)的修改建議。
感謝我們 O’Reilly 早期發(fā)行時的所有讀者,他們對于各種錯誤提出了不少反饋,其中包括 Kanak Kshetri 和 Rubén Berengue。
最后,感謝我們各自的雇主理解我們在這本書的工作。尤其是Lawrence Spracklen 堅持讓我們在這里提到他。
Holden Karau是一位加拿大人,在IBM的Spark技術中心擔任軟件開發(fā)工程師。同時作為一位Spark committer,經常在PySpark和機器學習方面進行貢獻。另外曾在多次國際會議中發(fā)表關于Spark的演講。
Rachel Warren是Alpine Data的軟件工程師和數據科學家。在工作中,她利用Spark來解決實際場景中的數據處理和機器學習問題。另外,她還曾在工業(yè)界以及學術界擔任過分析師和導師。
目錄
前言 .1
第1 章 高性能Spark 介紹 7
1.1 Spark 是什么以及性能的重要性 .7
1.2 你可以從本書中得到什么 8
1.3 Spark 版本 .9
1.4 為什么是 Scala ? 9
1.4.1 成為一名 Spark 專家必須要學習一點 Scala .9
1.4.2 Spark 的 Scala API 比 Java API 更好用 10
1.4.3 Scala 比 Python 更高效 10
1.4.4 為什么不用 Scala ? 11
1.4.5 學習 Scala 11
1.5 小結 12
第2 章 Spark 運行原理 .13
2.1 Spark 如何融入大數據生態(tài)系統(tǒng) 14
2.2 Spark 并行計算模型:RDD 16
2.2.1 惰性求值 17
2.2.2 內存持久化和內存管理 20
2.2.3 不可變性和 RDD 接口 . 21
2.2.4 RDD 的類型 23
2.2.5 RDD 上的函數:轉換與行動 24
2.2.6 寬依賴和窄依賴 25
2.3 Spark 作業(yè)調度 . 27
2.3.1 應用程序間的資源分配 27
2.3.2 Spark 應用程序 . 28
2.4 Spark Job 剖析 29
2.4.1 有向無環(huán)圖(DAG) 30
2.4.2 作業(yè)(Job) 31
2.4.3 階段(Stage) 31
2.4.4 任務(Task) 32
2.5 小結 34
第 3 章 DataFrame、Dataset 和Spark SQL 35
3.1 從 SparkSession(或者 HiveContext 和 SQLContext)入門 . 36
3.2 Spark SQL 依賴 39
3.2.1 管理 Spark 依賴 39
3.2.2 避免使用 Hive JAR 40
3.3 schema 基礎 41
3.4 DataFrame API 45
3.4.1 轉換 45
3.4.2 基于多個 DataFrame 的轉換 . 56
3.4.3 普通的 SQL 查詢以及與 Hive 數據交互 . 57
3.5 DataFrame 和 Dataset 中的數據表示 . 58
3.6 數據加載和保存函數 . 59
3.6.1 DataFrameWriter 和 DataFrameReader . 60
3.6.2 格式 60
3.6.3 保存模式 70
3.6.4 分區(qū)(發(fā)現和寫入) . 70
3.7 Dataset 71
3.7.1 與 RDD、DataFrame 和本地集合的互操作性 72
3.7.2 編譯時強類型 73
3.7.3 簡易函數式轉換操作(類似 RDD) . 74
3.7.4 關系型轉換操作 74
3.7.5 多 Dataset 關系轉換操作 . 75
3.7.6 Dataset 的分組操作 75
3.8 使用用戶自定義的函數和聚合函數(UDF、UDAF)進行擴展 . 76
3.9 查詢優(yōu)化器 . 79
3.9.1 邏輯和物理計劃 79
3.9.2 代碼生成 79
3.9.3 大型查詢計劃和迭代算法 80
3.10 調試 Spark SQL 查詢 80
3.11 JDBC/ODBC 服務器 81
3.12 小結 . 82
第 4 章 Join (SQL 和Spark Core) 84
4.1 Spark Core 中的 Join . 84
4.1.1 選擇 Join 類型 86
4.1.2 選擇執(zhí)行計劃 88
4.2 Spark SQL 中的 Join 91
4.2.1 DataFrame 的 Join 91
4.2.2 Dataset 的 Join 95
4.3 小結 96
第 5 章 高效的轉換 .97
5.1 窄轉換與寬轉換 98
5.1.1 對于性能的影響 100
5.1.2 對于容錯的影響 101
5.1.3 coalesce 的特殊情況 102
5.2 轉換會返回什么類型的 RDD . 102
5.3 最小化對象創(chuàng)建成本 104
5.3.1 重用現有對象 . 104
5.3.2 使用更小的數據結構 108
5.4 mapPartitions 迭代器到迭代器的轉換 111
5.4.1 什么是迭代器到迭代器的轉換? 112
5.4.2 空間和時間優(yōu)勢 113
5.4.3 案例 . 114
5.5 集合操作 117
5.6 降低初始化開銷 118
5.6.1 共享變量 119
5.6.2 廣播變量 119
5.6.3 累加器 121
5.7 重用 RDD . 125
5.7.1 重用的案例 126
5.7.2 判斷重新計算是否足夠劃算 129
5.7.3 重用類型:緩存、持久化、檢查點、shuffle 文件 130
5.7.4 Alluxio(之前的 Tachyon) 135
5.7.5 LRU 緩存 . 135
5.7.6 繁忙集群的注意事項 137
5.7.7 與累加器交互 . 138
5.8 小結 . 139
第 6 章 處理鍵值對數據 . 140
6.1 金發(fā)女孩案例 . 142
6.1.1 金發(fā)女孩之版本 0:迭代方案 143
6.1.2 如何使用 PairRDDFunctions 和 OrderedRDDFunctions 146
6.2 鍵值對上的行動操作 147
6.3 groupByKey 函數有什么風險 . 148
6.3.1 金發(fā)女孩之版本 1:groupByKey 方案 148
6.3.2 為什么 groupByKey 會失敗 150
6.4 選擇聚合操作 . 152
6.5 涉及多個 RDD 的操作 156
6.6 分區(qū)器和鍵值對數據 157
6.6.1 使用 Spark 的分區(qū)器對象 . 158
6.6.2 哈希分區(qū) 158
6.6.3 范圍分區(qū) 159
6.6.4 自定義分區(qū) 160
6.6.5 保留跨不同轉換的分區(qū)信息 160
6.6.6 利用協(xié)同位置(Co-located)和協(xié)同分區(qū)(Co-Partitioned)
的 RDD 161
6.6.7 PairRDDFunctions 中關于映射和分區(qū)函數的字典 163
6.7 OrderedRDDFunctions 字典 165
6.8 二級排序和 repartitionAndSortWithinPartitions 167
6.8.1 在按鍵分組和按值排序的函數中利用
repartitionAndSortWithinPartitions 168
6.8.2 如何不按照兩個排序鍵排序 172
6.8.3 金發(fā)女孩之版本 2:二級排序 172
6.8.4 金發(fā)女孩問題的另外一種不同解法 . 176
6.8.5 金發(fā)女孩之版本 3:對單元格值排序 . 181
6.9 掉隊檢測與不均衡數據 . 182
6.9.1 再次回到金發(fā)女孩問題 . 184
6.9.2 金發(fā)女孩之版本 4:在每個分區(qū)上歸并為不同值 184
6.10 小結 191
第 7 章 Scala 之外 192
7.1 JVM 之內、Scala 之外 194
7.2 Scala 之外、JVM 之外 198
7.2.1 PySpark 工作原理 . 198
7.2.2 SparkR 工作原理 207
7.2.3 Spark.jl(Julia Spark) 209
7.2.4 Eclair JS 工作原理 210
7.2.5 Spark 基于公共語言運行時(CLR),C# 及類似語言 211
7.3 在 Spark 中調用其他語言 . 211
7.3.1 使用管道及類似工具 211
7.3.2 JNI 213
7.3.3 Java 本地訪問(JNA) . 216
7.3.4 一切的背后都是 FORTRAN 217
7.3.5 談談 GPU . 218
7.4 未來 . 219
7.5 小結 . 219
第 8 章 測試和驗證 221
8.1 單元測試 221
8.1.1 一般 Spark 單元測試 222
8.1.2 模擬 RDD . 227
8.2 獲取測試數據 . 228
8.2.1 生成大數據集 . 229
8.2.2 抽樣 . 230
8.3 用 ScalaCheck 檢查屬性 232
8.4 集成測試 235
8.5 性能驗證 237
8.5.1 用于性能驗證的 Spark 計數器 237
8.5.2 性能驗證相關項目 238
8.6 作業(yè)驗證 239
8.7 小結 . 240
第 9 章 Spark MLlib 和ML 241
9.1 在 Spark MLlib 和 Spark ML 之間選擇 . 241
9.2 使用 MLlib 242
9.2.1 MLlib 入門(組織和導入) 242
9.2.2 MLlib 特征編碼和數據準備 244
9.2.3 特征縮放和選擇 248
9.2.4 MLlib 模型訓練 . 249
9.2.5 預測 . 250
9.2.6 服務和持久化 . 251
9.2.7 模型評估 254
9.3 使用 Spark ML 254
9.3.1 Spark ML 組織和導入 254
9.3.2 管道階段 256
9.3.3 參數解釋 257
9.3.4 數據編碼 258
9.3.5 數據清洗 261
9.3.6 Spark ML 模型 261
9.3.7 整合成管道 262
9.3.8 訓練管道 263
9.3.9 訪問單個階段 . 264
9.3.10 數據持久化和 Spark ML . 264
9.3.11 使用自定義算法擴展 Spark ML 管道 267
9.3.12 模型和管道持久化與 Spark ML 服務 275
9.4 一般服務考量因素 276
9.5 小結 . 276
第 10 章 Spark 組件和包 278
10.1 基于 Spark 的流處理 280
10.1.1 Source 和 Sink . 281
10.1.2 批處理間隔 283
10.1.3 數據 checkpoint 間隔 284
10.1.4 DStream 的注意事項 284
10.1.5 Structured Streaming 的考量因素 286
10.1.6 高可用性模式(或處理 Driver 程序故障或進行 checkpoint) 294
10.2 GraphX 295
10.3 使用社區(qū)包和庫 295
10.4 小結 298
附錄 調優(yōu)、調試以及開發(fā)者容易忽略的其他問題 301